Jump to content
mad_cheese

How to select the closest of multiple areas?

Recommended Posts

After all these years, still bad with the math 🙂

 

Let's say I have an array with multiple areas in the regular format [_center,_sizeA, _sizeB, _dir, _isRectangle]

 

How would I check which one of these areas/planes is the closest to a position? In this case, sorting by distance to the areas centers is not working.

 

Thanks guys.

 

EDIT: I think I got it https://mathinsight.org/distance_point_plane

 

Going to be a headache but I'll get there

 

  • Like 1

Share this post


Link to post
Share on other sites

Why isn't sorting the area centres working?

 

Is the centre of the area good enough? Are the areas the same size, shape and orientation?

 

https://community.bistudio.com/wiki/BIS_fnc_nearestPosition

[_arrayofareacentres,_mypostion] call BIS_fnc_nearestPosition

Will do what you want if the centre is good enough

 

If you need the nearest edge of the area that is nearest to your position, it's doable, but rather more complicated.

  • Like 1

Share this post


Link to post
Share on other sites

Hi @Tankbuster! Thanks for your answer, I have to admit I am a fan of your work, ha!

 

I do need the edge unfortunately. I have found a rather weird workaround that ends up working in my case, by using the pathCalculated eventhandler. I can create the path and check it's length until it eventually hits an area 🙂

 

I'm still very interested in this problem in general, how to get the shortest line between a point and the edge of an area/plane.

Share this post


Link to post
Share on other sites

That's an interesting one! Keep in mind that, depending on the type of simulated unit, calculatePath (or the PathCalculated EH workaround) does not return anything like a straight line, so an incorrect result is possible if your markers are at relatively similar distances.

Share this post


Link to post
Share on other sites

OK, let's work this through.

These areas, are they at ground level?

Is the position you want to get nearest to, is that ground level too?

Why the talk of calculatePath? Is it relevant?

Is the distance to be calculated the shortest, direct distance?

 

 

Share this post


Link to post
Share on other sites

An interesting one indeed. I have a feeling that finding a correct solution requires way more geometry than I can endure 😅

 

I put together something that might do the trick. It's based on this function I found: https://community.bistudio.com/wiki/BIN_fnc_distanceToAreaBorder
As far as I know, this function is available only when Contact DLC is enabled in the launcher so I copy-pasted the calculation into mine.

 

Foley_fnc_nearestArea = {
	params ["_pos", "_areas"];

	private _distances = _areas apply {
		[_pos, _x] call Foley_fnc_distanceToArea
	};

	_distances find (selectMin _distances)
};

Foley_fnc_distanceToArea = {
	params ["_pos", "_area"];
	_area params ["_center", "_a", "_b", "_angle", "_isRectangle", "_c"];
	
	private "_centerToEdge";

	// This calculation stolen from https://community.bistudio.com/wiki/BIN_fnc_distanceToAreaBorder
	if (_isRectangle) then {
		private _dir = _angle - (_center getDir _pos);
		_centerToEdge = abs (_a / cos (90 - _dir)) min abs (_b / cos _dir);
	} else {
		private _dir = _angle - (_center getDir _pos) + 90;
		_centerToEdge = vectorMagnitude [
			(_a * _b) / sqrt (_b ^ 2 + _a ^ 2 * tan _dir ^ 2),
			(_a * _b * tan _dir) / sqrt (_b ^ 2 + _a ^ 2 * tan _dir ^ 2),
			0
		];
	};

	(_pos distance _center) - _centerToEdge
};

Here's a demo

KiBAZnf.gif

 

Spoiler

 


private _markers = ["red", "green", "blue", "orange"];
private _markerAreas = _markers apply {_x call BIS_fnc_getArea};

while {true} do {
	private _nearestIndex = [getPos player, _markerAreas] call Foley_fnc_nearestArea;
	private _nearestMarker = _markers select _nearestIndex;
	
	{
		_x setMarkerBrush "Border";
	} forEach _markers;

	_nearestMarker setMarkerBrush "SolidBorder";

	sleep 0.1;
};

 

It appears to work correctly but you may notice one frame where the green area is highlighted though the blue edge is slightly closer.

This edge case (pun intended 😄) happens because the algorithm finds the point on the edge that's between you and the area center but that is not necessarily the nearest point to you.

  • Like 2

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

×