Jump to content
Sign in to follow this  
Harzach

Creating multiple spaced positions

Recommended Posts

Heya,

I am building an array of positions all of which need to be a certain distance away from each other. I know I am doing it incorrectly (clearly, as it doesn't work) and could use some fresh brains to prod me in the right direction.

HARZ_LOCATIONS = [[0,0,0]];  //this initial position is a placeholder for the distance check and is deleted after the first position is created
private _count = 10;
private _index = 0;

while {_index < _count} do {
	private _pos = [_whitelist, _blacklist] call BIS_fnc_randomPos;
	if (({(_pos distance _x > 500)} forEach HARZ_LOCATIONS) && !(_pos isEqualTo [0,0])) then {  // check distance from other positions and that it is a valid position
		_locIndex = _locIndex +1;
		HARZ_LOCATIONS pushBack _pos;
		if ([0,0,0] in HARZ_LOCATIONS) then {  //  check if placeholder still exists
			HARZ_LOCATIONS deleteAt 0;  //  delete placeholder position
		};
	}; 
};

Everything works except for the distance check.

 

I've considered wacky solutions such as adding new blacklist markers on the new positions, but that seems, well, wacky.

 

I'm sure there's a better alternative to the placeholder position nonsense, as well.

Share this post


Link to post
Share on other sites

I usually do something like this

private _max_positions = 10;						// how many positions we want
_min_radius = 500;									// minimum distance from another position

private _pos = [0,0,0];
private _registered_positions = [_pos];
_max_positions = 3 + 1;								// 1 is the [0,0,0] we remove at the end
_timeout = diag_ticktime + 30;						// timeout to exit the loop after 30 seconds
for '_i' from 0 to 1 step 0 do {					// infinite loop until positions are found or timeout triggers
	// test a position
	_pos = [........] call bis_fnc_randompos;
	// position conditions
	if (
		((_registered_positions findIf {((_x distance2D _pos) < _min_radius)}) isEqualTo -1)
	) then {
		_registered_positions pushback _pos;
	};
	// exit conditions
	if (
		((count _registered_positions) isEqualTo _max_positions) ||
		{(diag_tickTime > _timeout)}
	) exitWith {};
};
_registered_positions deleteAt 0;
if (diag_tickTime > _timeout) exitWith {
	// timed out, failed to find enough positions
};
_registered_positions

 

theres nothing wrong with a placeholder position in an array, you could try without it and see what happens too.

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites
27 minutes ago, fn_Quiksilver said:

I usually do something like this

 

Thanks, I'll muck around with it and see what happens.

 

My brain sort of had a moment and realized that the forEach check is failing because the final value it returns has always happened to be "true."

 

Anyhoo, onward.

Share this post


Link to post
Share on other sites

Yup, findIf was the prompt I needed. Thanks again, @fn_Quiksilver!

HARZ_LOCATIONS = [[0,0,0]];  //this initial position is a placeholder for the distance check and is deleted after the first position is created
private _count = 10;
private _index = 0;

while {_index < _count} do {
	private _pos = [_whitelist, _blacklist] call BIS_fnc_randomPos;
	if ((HARZ_LOCATIONS findIf { _pos distance _x < 500 } == -1) && !(_pos isEqualTo [0,0])) then {  // check distance from other positions and that it is a valid position
		_locIndex = _locIndex +1;
		HARZ_LOCATIONS pushBack _pos;
		if ([0,0,0] in HARZ_LOCATIONS) then {  //  check if placeholder still exists
			HARZ_LOCATIONS deleteAt 0;  //  delete placeholder position
		};
	}; 
};
  • Like 1

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  

×