SRL Archive - RS3 Help

Filtering points from an irregularly-shaped area


Citrus

2015-03-07 20:40:53

I'm trying to filter points from the Fishing Guild dock from any compass angle. It's shaped like an 'h' so I don't think convex hull will work. Any ideas for making this work?

Turpinator

2015-03-07 20:59:01

Care to elaborate on what exactly you are trying to do? Mainscreen, minimap? pics are great.

Lipcot

2015-03-07 21:31:10

doing little ATPAS ? … tpatoatpa(5,5); if i dont recall incorrectly.. you'll get tons of results but you wont miss the target :P

Citrus

2015-03-07 21:45:39

From: Turpinator
Care to elaborate on what exactly you are trying to do? Mainscreen, minimap? pics are great.


[ATTACH=CONFIG]25224[/ATTACH]
When the script looks for fishing spots, it sometimes picks up points from other players, usually a fishing cape. I want to exclude any points that fall within the boundaries of the dock. It isn't a big deal in this specific case, and I could solve it another way, but I can see myself needing to do something like this in the future.

Turpinator

2015-03-07 23:18:40

okay… soo.
get a TPA of the pier.
now get one of all the white.
now… using a loop and nearbyPointInArrayEx() (or not Ex) and remove any points in your white TPA that are nearby the pier.

although, with people standing on it… there will be space between the capes and the pier…

you could probably perform something similar with the water instead of the pier. perhaps using some findTPAEdges.

Citrus

2015-03-08 04:04:15

From: Turpinator
okay… soo.
get a TPA of the pier.
now get one of all the white.
now… using a loop and nearbyPointInArrayEx() (or not Ex) and remove any points in your white TPA that are nearby the pier.

although, with people standing on it… there will be space between the capes and the pier…

you could probably perform something similar with the water instead of the pier. perhaps using some findTPAEdges.


Yeah using the water was my backup plan. I guess I was hoping for something more elegant.

Kasi

2015-03-08 12:06:47

You can use vector math here.

Citrus

2015-03-08 16:17:54

From: Kasi
You can use vector math here.


Could you explain further?

Kasi

2015-03-08 18:23:36

From: evilcitrus
Could you explain further?



public boolean PointInTri(PointD PointD_P, PointD PointD_A,
PointD PointD_B, PointD PointD_C) {

boolean[] boolArrTemp = new boolean[3];

boolArrTemp[0] = (Sign(PointD_P, PointD_A, PointD_B) <= 0.0F);
boolArrTemp[1] = (Sign(PointD_P, PointD_B, PointD_C) <= 0.0F);
boolArrTemp[2] = (Sign(PointD_P, PointD_C, PointD_A) <= 0.0F);

return (boolArrTemp[0] == boolArrTemp[1])
&& (boolArrTemp[1] == boolArrTemp[2]);
}[B][/B]

The same concept can be applied to any polygon providing the sides don't cross.

Citrus

2015-03-08 20:09:22

From: Kasi

public boolean PointInTri(PointD PointD_P, PointD PointD_A,
PointD PointD_B, PointD PointD_C) {

boolean[] boolArrTemp = new boolean[3];

boolArrTemp[0] = (Sign(PointD_P, PointD_A, PointD_B) <= 0.0F);
boolArrTemp[1] = (Sign(PointD_P, PointD_B, PointD_C) <= 0.0F);
boolArrTemp[2] = (Sign(PointD_P, PointD_C, PointD_A) <= 0.0F);

return (boolArrTemp[0] == boolArrTemp[1])
&& (boolArrTemp[1] == boolArrTemp[2]);
}[B][/B]

The same concept can be applied to any polygon providing the sides don't cross.


I'm a bit confused about what Sign() is doing with the points.

Kasi

2015-03-08 21:16:50

From: evilcitrus
I'm a bit confused about what Sign() is doing with the points.



public float Sign(PointD PointD_A, PointD PointD_B, PointD PointD_C) {
return (PointD_A.X() - PointD_C.X()) * (PointD_B.Y() - PointD_C.Y())
- (PointD_B.X() - PointD_C.X()) * (PointD_A.Y() - PointD_C.Y());
}


Citrus

2015-03-08 21:44:34

From: Kasi

public float Sign(PointD PointD_A, PointD PointD_B, PointD PointD_C) {
return (PointD_A.X() - PointD_C.X()) * (PointD_B.Y() - PointD_C.Y())
- (PointD_B.X() - PointD_C.X()) * (PointD_A.Y() - PointD_C.Y());
}



Okay thanks. I'll look into this more if/when I need it.

bg5

2015-03-08 23:46:53

@evilcitrus

This should work for any angle:


program new;
{$include TCol.simba}
{$loadlib AND_TPA}
var
pierC,waterC,spotC :TCol;
debugBmp,cw,ch, T:integer;
TPA1,TPA2,TPA3: TPointArray;
ATPA :T2dPointArray;
centerPoint : TPoint;
begin
GetClientDimensions(cw,ch);
centerPoint := Point(cw div 2,ch div 2); // center of mainscreen is coded inside SRL, I just dont use SRL now

pierC.Create(4349543,2,2,0.23,0.27);
waterC.Create(7426622,23,1);
spotC.Create(12166806,19,2,0.09,0.27);



pierC.FindTPA(TPA1);
waterC.FindTPA(TPA2);
spotC.FindTPA(TPA3); // color of "bubbles" in the water

T := GeTTimeRunning();

FilterTPADistTPAExCmpr(TPA1,30,30,TPA2,2,8); // we leave only those parts of pierses, which are next to the water
// Cmpr means, that we compress both TPAs for faster processing

SplitTPAExWrap(TPA1,6,6,ATPA);
SortATPAFromMidPoint(ATPA,centerPoint); // this is to select the pier on which you stay

FilterTPADistTPAEx(TPA3,5,5,TPA2); // this is to ensure, that every pixel of bubbles found is in the water
FilterTPADistTPAEx(TPA3,40,40,ATPA[0]); // now we leave only those bubbles, which are next to your pier


// This part is for debug only

T := GeTTimeRunning() - T;
writeln('Time of this mess : ' + tostr( T) );

GetClientDimensions(cw,ch);
debugBmp:= BitmapFromClient(0,0,cw-1,ch-1);
DisplayDebugImgWindow(cw+1,ch+1);

DrawTPABitmap(debugBmp,TPA1,$00BFFF); // docks in water( olive)
DrawTPABitmap(debugBmp,ATPA[0],$FFFFFF); // your pier ( white )
DrawTPABitmap(debugBmp,TPA2,$00FF00); // water ( green )
DrawTPABitmap(debugBmp,TPA3,$0000FF); // spots ( red )
DrawBitmapDebugImg(debugBmp);
end.

Is it enough for your needs?

Citrus

2015-03-11 00:29:58

From: bg5

Is it enough for your needs?


Yes!
Wow, this is really cool. I'll definitely look into this so I can use it in other situations.