Jump to content
🛡️FORUMS ARE IN READ-ONLY MODE Read more... ×
Sign in to follow this  
tryteyker

Getting a random position around an object

Recommended Posts

Hey,

I'm crrently trying to work out how to get a random position around an object. I haven't tried anything script-wise yet since I'm in the middle of class and I haven't found anything on google or the wiki either.

My first guess was BIS_fnc_relPos but I'm absolutely clueless on how to use that and I'm not even sure if it's the right thing, so any help would be appreciated.

Share this post


Link to post
Share on other sites

the easiest way is


            _target = player // change this to the object name that you want to get the position around
_dist = random 45;// this chooses a random distance from 0-45
_dir = random 360;// this selects a random direction from 360 degrees rotation
_pos = getPos _target;		
   _positions = [(_pos select 0) + (sin _dir) * _dist, (_pos select 1) + (cos _dir) * _dist, 0];

   //then to use you use i.e

     _mkr = createMarker ["test", _positions];

// or

_ied = "Land_IED_v4_PMC" createVehicle _positions ;

//so the _positions becomes the positions

Share this post


Link to post
Share on other sites

Thanks, but could you elaborate on sin and cos please? Didn't quite get the wiki, not even sure what sine and cosine is.

Share this post


Link to post
Share on other sites

There is needed semicolon in the first line and some aditiona settings for the marker.

However, as above code doesn't return truly uniform distribution:

randomcircle1.jpg

I'm wondering, if I can to add own question in this matter, if there is better method for that distribution on circular area, than this:

_target = player;
_pos = getPosATL _target;
_rds = 500;
_ct = 0;
_goodPos = [];

while {_ct < 5000} do   
{     
_positions = [(_pos select 0) + (random 1000) - 500,(_pos select 1) + (random 1000) - 500,0];
if ((_positions distance player) <= _rds) then
	{
	_ct = _ct + 1;
	_goodPos set [(count _goodPos),_positions];
	_mkr = createMarker [(str _ct), _positions];
	_mkr setMarkerShape "ICON";
	_mkr setMarkerType "DOT";
	_mkr setMarkerSize [0.2,0.2];
	}
};

randomcircle2.jpg

Share this post


Link to post
Share on other sites
some aditiona settings for the marker. QUOTE]

i know that mate i was on my phone just used a basic example as the question was for position not marker

Share this post


Link to post
Share on other sites

I'm wondering, if I can to add own question in this matter, if there is better method for that distribution on circular area, than this:

_target = player;
_pos = getPosATL _target;
_rds = 500;
_ct = 0;
_goodPos = [];

while {_ct < 5000} do   
{     
_positions = [(_pos select 0) + (random 1000) - 500,(_pos select 1) + (random 1000) - 500,0];
if ((_positions distance player) <= _rds) then
	{
	_ct = _ct + 1;
	_goodPos set [(count _goodPos),_positions];
	_mkr = createMarker [(str _ct), _positions];
	_mkr setMarkerShape "ICON";
	_mkr setMarkerType "DOT";
	_mkr setMarkerSize [0.2,0.2];
	}
};

Yeah, that's the method I use to do this too, ironically for an IED system as well. :)

Share this post


Link to post
Share on other sites

most likely the best way is to use shk pos http://www.armaholic.com/page.php?id=13783

download it follow instructions to fire it up in the mission and use this to call it in your script

	 _pos = getpos player; 
             _spos = [_pos,random 360,[1000,2000]] call SHK_pos;// 1000 = minimum 1000mtrs change as needed and 2000 = max distance change as needed


Share this post


Link to post
Share on other sites

Well, Shuko's code is based on the same radius&distance (sin&cos) method and, obviously, returns same distribution, as on first image, means non-uniform.

EDIT: some interesting changes occur, when we will try to "push" distance distribution out of uniform, so farer becomes more probable. But with what exact formula distribution of randomized distance should be calculated, so we will get truly uniform distribution of positions?

Some illustration, of course with only makeshift distance, where most probably distance is a half of the radius, and distribution isn't uniform still:

_target = player;
_pos = getPosATL _target;	

for "_i" from 1 to 5000 do
{
_dist = (random 250) + (random 250);
_dir = random 360;	
_positions = [(_pos select 0) + (sin _dir) * _dist, (_pos select 1) + (cos _dir) * _dist, 0];

_mkr = createMarker [(str _i), _positions];
_mkr setMarkerShape "ICON";
_mkr setMarkerType "DOT";
_mkr setMarkerSize [0.2,0.2];
};

randomcircle3.jpg

Edited by Rydygier

Share this post


Link to post
Share on other sites

You know whats got me is how you could like make a spaceing on each position result so the results dont land next to another result i.e a 50 mtr gap at minimum between results.

Share this post


Link to post
Share on other sites
the easiest way is


            _target = player // change this to the object name that you want to get the position around
_dist = random 45;// this chooses a random distance from 0-45
_dir = random 360;// this selects a random direction from 360 degrees rotation
_pos = getPos _target;		
   _positions = [(_pos select 0) + (sin _dir) * _dist, (_pos select 1) + (cos _dir) * _dist, 0];

   //then to use you use i.e

     _mkr = createMarker ["test", _positions];

// or

_ied = "Land_IED_v4_PMC" createVehicle _positions ;

//so the _positions becomes the positions

Alright, so I get 90% of this example, but the thing that I don't get is the _positions array.

Specifically there I don't get the _pos select 0 and select 1. It's using _target, but that contains only 1 thing (player), which should be 0, right?

//Edit

(Although this might be a bit offtopic)

I got an additional question about the Spawngroup function, I'm trying to spawn a group of vehicles with it, but since they're so big they're just crashing into eachother once they spawn (infantry works fine) and thus disabling eachother.

How do I add a small radius so I could prevent that, and also, how do I give the group a name so I can use addWaypoint with it?

Edited by tryteyker

Share this post


Link to post
Share on other sites
You know whats got me is how you could like make a spaceing on each position result so the results dont land next to another result i.e a 50 mtr gap at minimum between results.

Check out ruebe's functions:

For a start

Creating Random Spawn Positions

Check post #2 in the above thread or download the ruebe library:

rube-wip

Edited by panther42

Share this post


Link to post
Share on other sites

I already have it so the group spawns randomly around a marker created, what I want to do is increase the minimum distance between each of the units that spawn so they don't form a cluster.

My script looks like this currently:

_target = player;
_dist = random 50;
_dir = random 360;
_pos = getpos _target;
_group = ["USMC_Soldier","USMC_Soldier_AA","USMC_Soldier_MG","USMC_Soldier_LAT","USMC_Soldier_Medic"];
_eastinf = ["MVD_Soldier_AT","RU_Soldier","RU_Soldier","MVD_Soldier_Marksman","RU_Soldier_AA","RU_Soldier_AA","RU_Soldier_LAT"];
_eastveh = ["T72_RU","BMP3","2S6M_Tunguska"];
_positions = [(_pos select 0) + (sin _dir) * _dist, (_pos select 1) + (cos _dir) * _dist, 0];


if (true) then {
_heli = createmarker ["Heli",_positions];
"Heli" setmarkershape "ICON";
"Heli" setmarkertype "DESTROY";
hintSilent "Marker created!";
}else{
hintSilent "Can't find Heli!";
};

if (getpos heli select 2 <= 1) then {
_us = [getMarkerPos "Heli", WEST,_group,[],[],[0.6,1],[],[2,0.4],90] call BIS_fnc_spawnGroup;
hintSilent "Group spawned";
_inf = [getMarkerPos "infspawn", EAST,_eastinf,[],[],[0.1,1],[],[5,0.4],210] call BIS_fnc_spawnGroup;
_veh = [getMarkerPos "vehspawn", EAST,_eastveh,[],[],[0.4,1],[],[2,0.1],270] call BIS_fnc_spawnGroup;

/* _infwp = _inf addwaypoint [getpos infwp, 0];
_infwp setwaypointtype "SAD";
_infwp setWaypointSpeed "FULL";
_infwp setWaypointBehaviour "COMBAT";
_infwp setWaypointFormation "LINE";

_vehwp = _veh addwaypoint [getpos vehwp, 0];
_vehwp setwaypointtype "SAD";
_vehwp setWaypointSpeed "FULL";
_vehwp setWaypointBehaviour "COMBAT";
_vehwp setWaypointFormation "LINE"; */


/* _uswp = _us addwaypoint [getpos uswp, 0];
_uswp setwaypointtype "SAD";
_uswp setwaypointspeed "FULL";
_uswp setwaypointbehaviour "COMBAT";
_uswp setwaypointformation "LINE";
*/
}else{
hintSilent "Can't find Heli (creategroup)!";
};

(I've commented out the waypoint codes because it didn't seem to work)

Edited by tryteyker

Share this post


Link to post
Share on other sites

I use this to get a random point in an ellipse. First it picks an uniform random point in a circle. Then it shrinks or enlarges it to get an uniform distribution in an ellipse. (shrinking or enlarging on one axis! will, maybe surprisingly, not ruin the uniform distribution.). It was based on markers and trigger areas. _a and _b are the axis. _angle is the angle of the marker or trigger.:

       //Create point in regular circle with radius _a.
       _dir = random 360;
       //Uniform distribution
       _mag = sqrt((random _a)*_a);
       _nX = _mag * (sin _dir);
       //Shrink or enlarge it along the y-axis/minor axis.
       _nY = _mag * (cos _dir) * _b / _a;

       //Rotate point
       _temp = _nX * cos(-_angle) - _nY * sin(-_angle);
       _nY = _nX * sin(-_angle) + _nY * cos(-_angle);
       _nX = _temp;

       _result = [_xPos + _nX, _yPos + _nY];

Share this post


Link to post
Share on other sites

Great. This is exactly this kind of solution, what I'm looking for. Thanks. :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

×