Jump to content
Sign in to follow this  
hansen111

isPosIn2DArea [function]

Recommended Posts

So someome asked me how to detect if a position is in a rectangle area without having to use a marker, i searched to give him a link but could not find a small working function, so i wrote and tested one. I thought i share it for anyone in the future searching for the same function:

The functions needs (Parameters):

1) A position, either getPos or getPosATL ect. IMPORTANT - Use the same method (getPos, getPosATL ect.) to get positions of the area and to get postion of player ect

_myPos = getPos player;

2) An array containing 4 positions that makes the box

I used 4 flag objects to test the box:

_myBox = [getPos flag1,getPos flag2,getPos flag3,getPos flag4];

The function returns boolean (true/false) if the position is in the box

So:

_isPlayerInArea = [getPos player,_myBox] call isPosIn2DArea;

isPosIn2DArea = {

//Author: Henrik Hansen

private ["_maxx","_maxy","_minx","_miny","_pos","_box"];

_pos = _this select 0;_box = _this select 1;

_maxx = (_box select 0) select 0;_minx = _maxx;

_maxy = (_box select 0) select 1;_miny = _maxy;

{

if ((_x select 0) < _minx) then {_minx=(_x select 0)};

if ((_x select 0) > _maxx) then {_maxx=(_x select 0)};

if ((_x select 1) < _miny) then {_miny=(_x select 1)};

if ((_x select 1) > _maxy) then {_maxy=(_x select 1)};

} forEach _box;

( ((_pos select 0) <= _maxx) && ((_pos select 0) >= _minx) && ((_pos select 1) <= _maxy) && ((_pos select 1) >= _miny) )

};//function

Here is the test code i used, it will make a hint every second saying on screen if you are in or outside the box:

[] spawn {

private ["_myBox"];

_myBox = [getPos flag1,getPos flag2,getPos flag3,getPos flag4];

while {true} do {

if ([getPos player,_myBox] call isPosIn2DArea) then {hint "In Box"} else {hint "Outside Box"};

sleep 1;

};//while

};//spawn

enjoy

Edited by Hansen111

Share this post


Link to post
Share on other sites

BIS_fnc_inTrigger uses trigger / trigger area based on marker:

if (typename _trig == typename "") then {_trig = [markerpos _trig,markersize _trig + [markerdir _trig,markershape _trig == "rectangle"]]};

As i said in my post the person making the request of the function did not want to use markers or triggers, but purely position arrays.

As for the Picture you linked to that deals with none 2d regular rectangles which is not in the scope for this function - my function checks for the extremes on x,y axis, so the area check would include positions all the way out to the extreme points, disregarding the center most points.

Share this post


Link to post
Share on other sites

BIS_fnc_inTrigger can also do that for you.

It really is a badly named function and should be BIS_fnc_inArea or similar, as it can check for a position inside a trigger, marker or a defined area, it also takes into account the angle of the area aswell so it could be a diamond or a rotated rectangle/ellipse.

//Square, Rectangle or Ellipse
[ [ _areaPos, [ _xSize, _ySize, _angle, _isRectangle ] ], _checkPos ] call BIS_fnc_inTrigger
//Circle
[ [ _areaPos, _radius ], _checkPos ] call BIS_fnc_inTrigger
//Trigger
[ _myTrigger, _checkPos ] call BIS_fnc_inTrigger
//Marker
[ _markerName, _checkPos ] call BIS_fnc_inTrigger

It can also tell you how far from the edge of the area your are if you use the third argument e.g

[ _myTrigger, _checkpos, true ] call BIS_fnc_inTrigger

Will return the distance in meters of how far away you are both inside and outside. Its a negative number if you are inside the area.

Edited by Larrow

Share this post


Link to post
Share on other sites
BIS_fnc_inTrigger can also do that for you.

It really is a badly named function and should be BIS_fnc_inArea or similar, as it can check for a position inside a trigger, marker or a defined area, it also takes into account the angle of the area aswell so it could be a diamond or a rotated rectangle/ellipse.

//Square, Rectangle or Ellipse
[ [ _areaPos, [ _xSize, _ySize, _angle, _isRectangle ] ], _checkPos ] call BIS_fnc_inTrigger
//Circle
[ [ _areaPos, _radius ], _checkPos ] call BIS_fnc_inTrigger
//Trigger
[ _myTrigger, _checkPos ] call BIS_fnc_inTrigger
//Marker
[ _markerName, _checkPos ] call BIS_fnc_inTrigger

It can also tell you how far from the edge of the area your are if you use the third argument e.g

[ _myTrigger, _checkpos, true ] call BIS_fnc_inTrigger

Will return the distance in meters of how far away you are both inside and outside. Its a negative number if you are inside the area.

I missed that function because of its name, never used it either, so how would you use that on a 4 point area like the 4 flag poles like i did? , remember the task was to Work only with 5 positions - 4 positions for the area and 1 for the point to check.

//Square, Rectangle or Ellipse

[ [ _areaPos, [ _xSize, _ySize, _angle, _isRectangle ] ], _checkPos ] call BIS_fnc_inTrigger

If i understand it correctly you would need the 2 lengths and an angle, that would involve 2 distance calculations and an angle calculation?

Edited by Hansen111

Share this post


Link to post
Share on other sites
If i understand it correctly you would need the 2 lengths and an angle, that would involve 2 distance calculations and an angle calculation?

Not sure where these calculations come into play, but creating a "virtual zone" that is 10 meters wide and 10 meters tall could not be any simpler than:

_playerPos = getPosATL player;

while {true} do
{
if ([[5,5,0,true], _playerPos] call BIS_fnc_inTrigger) then
{
	hintSilent "You're inside"
}else
{
	hintSilent "You're outside"
};
sleep 0.02;
};

Edited by DreadedEntity
realized the loop could never become false

Share this post


Link to post
Share on other sites
remember the task was to Work only with 5 positions - 4 positions for the area and 1 for the point to check.
You neglected that fact in the original post "someome asked me how to detect if a position is in a rectangle area without having to use a marker".

If you specifically need to have your area defined by four points rather than position and size then it would hardly be worth it as you would still need to work out the max/min size.

Share this post


Link to post
Share on other sites
I missed that function because of its name

To be fair the name you gave to your function is pretty inexplicit as well, if not misleading.

Share this post


Link to post
Share on other sites
To be fair the name you gave to your function is pretty inexplicit as well, if not misleading.

Hmm i dont see that, inTrigger is way way worse because it leads you to think it revolves around arma triggers. 2 out of 4 in this thread thinks inTrigger is terrible, only you have a problem with my function name, so thats fine.

Edited by Hansen111

Share this post


Link to post
Share on other sites

I copy Deadfast's function here, which works for all polygons and not only rectangles. Pretty useful, I've been using it for ages.

[color=#FF8040][color=#006400][i]/*
Script by Deadfast.

Using the ray casting algorithm you just cast a line from the point in any direction
and count the number of times it crosses over an edge between two neighboring vertexes.

If the number is odd the point is inside. 

This works for both convex and concave polygons, as long as they are closed.

Input:
_point: position to check
_poly: array containing the positions of poly-vertexes
*/[/i][/color]

[color=#1874CD]_point[/color] [color=#8B3E2F][b]=[/b][/color] [color=#000000]_this[/color] [color=#191970][b]select[/b][/color] [color=#FF0000]0[/color][color=#8B3E2F][b];[/b][/color]
[color=#1874CD]_poly[/color]  [color=#8B3E2F][b]=[/b][/color] [color=#000000]_this[/color] [color=#191970][b]select[/b][/color] [color=#FF0000]1[/color][color=#8B3E2F][b];[/b][/color]

[color=#191970][b]if[/b][/color] [color=#8B3E2F][b]([/b][/color][color=#8B3E2F][b]([/b][/color][color=#1874CD]_poly[/color] [color=#191970][b]select[/b][/color] [color=#FF0000]0[/color][color=#8B3E2F][b])[/b][/color] [color=#191970][b]distance[/b][/color] [color=#8B3E2F][b]([/b][/color][color=#1874CD]_poly[/color] [color=#191970][b]select[/b][/color] [color=#8B3E2F][b]([/b][/color][color=#191970][b]count[/b][/color] [color=#1874CD]_poly[/color] [color=#FF0000]-1[/color][color=#8B3E2F][b])[/b][/color][color=#8B3E2F][b])[/b][/color] [color=#8B3E2F][b]>[/b][/color] [color=#FF0000]0.01[/color][color=#8B3E2F][b])[/b][/color] [color=#191970][b]then[/b][/color] [color=#8B3E2F][b]{[/b][/color][color=#1874CD]_poly[/color] [color=#191970][b]set[/b][/color] [color=#8B3E2F][b][[/b][/color][color=#191970][b]count[/b][/color] [color=#1874CD]_poly[/color][color=#8B3E2F][b],[/b][/color] [color=#1874CD]_poly[/color] [color=#191970][b]select[/b][/color] [color=#FF0000]0[/color][color=#8B3E2F][b]][/b][/color][color=#8B3E2F][b]}[/b][/color][color=#8B3E2F][b];[/b][/color]

[color=#1874CD]_crossings[/color] [color=#8B3E2F][b]=[/b][/color] [color=#FF0000]0[/color][color=#8B3E2F][b];[/b][/color]

[color=#191970][b]for[/b][/color] [color=#7A7A7A]"_i"[/color] [color=#191970][b]from[/b][/color] [color=#FF0000]0[/color] [color=#191970][b]to[/b][/color] [color=#8B3E2F][b]([/b][/color][color=#191970][b]count[/b][/color] [color=#1874CD]_poly[/color][color=#8B3E2F][b])[/b][/color][color=#FF0000]-1[/color] [color=#191970][b]do[/b][/color]
[color=#8B3E2F][b]{[/b][/color]
   [color=#191970][b]if[/b][/color] [color=#8B3E2F][b]([/b][/color][color=#8B3E2F][b]([/b][/color][color=#8B3E2F][b]([/b][/color][color=#8B3E2F][b]([/b][/color][color=#1874CD]_poly[/color] [color=#191970][b]select[/b][/color] [color=#1874CD]_i[/color][color=#8B3E2F][b])[/b][/color] [color=#191970][b]select[/b][/color] [color=#FF0000]1[/color] [color=#8B3E2F][b]<[/b][/color][color=#8B3E2F][b]=[/b][/color] [color=#1874CD]_point[/color] [color=#191970][b]select[/b][/color] [color=#FF0000]1[/color][color=#8B3E2F][b])[/b][/color] [color=#8B3E2F][b]&[/b][/color][color=#8B3E2F][b]&[/b][/color] [color=#8B3E2F][b]([/b][/color][color=#8B3E2F][b]([/b][/color][color=#1874CD]_poly[/color] [color=#191970][b]select[/b][/color] [color=#8B3E2F][b]([/b][/color][color=#1874CD]_i[/color][color=#8B3E2F][b]+[/b][/color][color=#FF0000]1[/color][color=#8B3E2F][b])[/b][/color][color=#8B3E2F][b])[/b][/color] [color=#191970][b]select[/b][/color] [color=#FF0000]1[/color] [color=#8B3E2F][b]>[/b][/color] [color=#8B3E2F][b]([/b][/color][color=#1874CD]_point[/color] [color=#191970][b]select[/b][/color] [color=#FF0000]1[/color][color=#8B3E2F][b])[/b][/color][color=#8B3E2F][b])[/b][/color][color=#8B3E2F][b])[/b][/color] [color=#8B3E2F][b]|[/b][/color][color=#8B3E2F][b]|[/b][/color]
       [color=#8B3E2F][b]([/b][/color][color=#8B3E2F][b]([/b][/color][color=#8B3E2F][b]([/b][/color][color=#1874CD]_poly[/color] [color=#191970][b]select[/b][/color] [color=#1874CD]_i[/color][color=#8B3E2F][b])[/b][/color] [color=#191970][b]select[/b][/color] [color=#FF0000]1[/color] [color=#8B3E2F][b]>[/b][/color] [color=#1874CD]_point[/color] [color=#191970][b]select[/b][/color] [color=#FF0000]1[/color][color=#8B3E2F][b])[/b][/color] [color=#8B3E2F][b]&[/b][/color][color=#8B3E2F][b]&[/b][/color] [color=#8B3E2F][b]([/b][/color][color=#8B3E2F][b]([/b][/color][color=#1874CD]_poly[/color] [color=#191970][b]select[/b][/color] [color=#8B3E2F][b]([/b][/color][color=#1874CD]_i[/color][color=#8B3E2F][b]+[/b][/color][color=#FF0000]1[/color][color=#8B3E2F][b])[/b][/color][color=#8B3E2F][b])[/b][/color] [color=#191970][b]select[/b][/color] [color=#FF0000]1[/color] [color=#8B3E2F][b]<[/b][/color][color=#8B3E2F][b]=[/b][/color] [color=#8B3E2F][b]([/b][/color][color=#1874CD]_point[/color] [color=#191970][b]select[/b][/color] [color=#FF0000]1[/color][color=#8B3E2F][b])[/b][/color][color=#8B3E2F][b])[/b][/color][color=#8B3E2F][b])[/b][/color][color=#8B3E2F][b])[/b][/color] [color=#191970][b]then[/b][/color]
   [color=#8B3E2F][b]{[/b][/color]
       [color=#1874CD]_intersect[/color] [color=#8B3E2F][b]=[/b][/color] [color=#8B3E2F][b]([/b][/color][color=#8B3E2F][b]([/b][/color][color=#1874CD]_point[/color] [color=#191970][b]select[/b][/color] [color=#FF0000]1[/color][color=#8B3E2F][b])[/b][/color] [color=#8B3E2F][b]-[/b][/color] [color=#8B3E2F][b]([/b][/color][color=#8B3E2F][b]([/b][/color][color=#1874CD]_poly[/color] [color=#191970][b]select[/b][/color] [color=#1874CD]_i[/color][color=#8B3E2F][b])[/b][/color] [color=#191970][b]select[/b][/color] [color=#FF0000]1[/color][color=#8B3E2F][b])[/b][/color][color=#8B3E2F][b])[/b][/color] [color=#8B3E2F][b]/[/b][/color]
                       [color=#8B3E2F][b]([/b][/color][color=#8B3E2F][b]([/b][/color][color=#8B3E2F][b]([/b][/color][color=#1874CD]_poly[/color] [color=#191970][b]select[/b][/color] [color=#8B3E2F][b]([/b][/color][color=#1874CD]_i[/color][color=#8B3E2F][b]+[/b][/color][color=#FF0000]1[/color][color=#8B3E2F][b])[/b][/color][color=#8B3E2F][b])[/b][/color] [color=#191970][b]select[/b][/color] [color=#FF0000]1[/color][color=#8B3E2F][b])[/b][/color] [color=#8B3E2F][b]-[/b][/color] [color=#8B3E2F][b]([/b][/color][color=#8B3E2F][b]([/b][/color][color=#1874CD]_poly[/color] [color=#191970][b]select[/b][/color] [color=#1874CD]_i[/color][color=#8B3E2F][b])[/b][/color] [color=#191970][b]select[/b][/color] [color=#FF0000]1[/color][color=#8B3E2F][b])[/b][/color][color=#8B3E2F][b])[/b][/color][color=#8B3E2F][b];[/b][/color]

       [color=#191970][b]if[/b][/color] [color=#8B3E2F][b]([/b][/color][color=#8B3E2F][b]([/b][/color][color=#1874CD]_point[/color] [color=#191970][b]select[/b][/color] [color=#FF0000]0[/color][color=#8B3E2F][b])[/b][/color] [color=#8B3E2F][b]<[/b][/color] [color=#8B3E2F][b]([/b][/color][color=#8B3E2F][b]([/b][/color][color=#8B3E2F][b]([/b][/color][color=#1874CD]_poly[/color] [color=#191970][b]select[/b][/color] [color=#1874CD]_i[/color][color=#8B3E2F][b])[/b][/color] [color=#191970][b]select[/b][/color] [color=#FF0000]0[/color][color=#8B3E2F][b])[/b][/color] [color=#8B3E2F][b]+[/b][/color] [color=#1874CD]_intersect[/color] [color=#8B3E2F][b]*[/b][/color]
               [color=#8B3E2F][b]([/b][/color][color=#8B3E2F][b]([/b][/color][color=#8B3E2F][b]([/b][/color][color=#1874CD]_poly[/color] [color=#191970][b]select[/b][/color] [color=#8B3E2F][b]([/b][/color][color=#1874CD]_i[/color][color=#8B3E2F][b]+[/b][/color][color=#FF0000]1[/color][color=#8B3E2F][b])[/b][/color][color=#8B3E2F][b])[/b][/color] [color=#191970][b]select[/b][/color] [color=#FF0000]0[/color][color=#8B3E2F][b])[/b][/color] [color=#8B3E2F][b]-[/b][/color] [color=#8B3E2F][b]([/b][/color][color=#8B3E2F][b]([/b][/color][color=#1874CD]_poly[/color] [color=#191970][b]select[/b][/color] [color=#1874CD]_i[/color][color=#8B3E2F][b])[/b][/color] [color=#191970][b]select[/b][/color] [color=#FF0000]0[/color][color=#8B3E2F][b])[/b][/color][color=#8B3E2F][b])[/b][/color][color=#8B3E2F][b])[/b][/color][color=#8B3E2F][b])[/b][/color] [color=#191970][b]then[/b][/color]
       [color=#8B3E2F][b]{[/b][/color]
           [color=#1874CD]_crossings[/color] [color=#8B3E2F][b]=[/b][/color] [color=#1874CD]_crossings[/color] [color=#8B3E2F][b]+[/b][/color] [color=#FF0000]1[/color][color=#8B3E2F][b];[/b][/color]
       [color=#8B3E2F][b]}[/b][/color][color=#8B3E2F][b];[/b][/color]
   [color=#8B3E2F][b]}[/b][/color][color=#8B3E2F][b];[/b][/color]
[color=#8B3E2F][b]}[/b][/color][color=#8B3E2F][b];[/b][/color]

[color=#8B3E2F][b]([/b][/color][color=#1874CD]_crossings[/color] [color=#8B3E2F][b]%[/b][/color] [color=#FF0000]2[/color][color=#8B3E2F][b])[/b][/color] [color=#8B3E2F][b]>[/b][/color] [color=#FF0000]0[/color] [color=#006400][i]//Odd number when inside, even when outside [/i][/color]
[/color]

Made with KK's SQF to BBCode Converter

Share this post


Link to post
Share on other sites
If you specifically need to have your area defined by four points rather than position and size then it would hardly be worth it as you would still need to work out the max/min size.

Correct, that was what i was getting at.

I copy Deadfast's function here, which works for all polygons and not only rectangles. Pretty useful, I've been using it for ages.

Thanks zapat, could you include a few examples, that would be great for future readers of the post. Love your Work on getTactical and blackrain btw.

Edited by Hansen111

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×