Jump to content
Sign in to follow this  
panther42

Need help with math formula

Recommended Posts

I'm trying to come up with a formula to create points on a circle(used for waypoints) which alternate and intersect center position. I can create simple points on the circle fine, but what I want to do is create them in the following sequence, or similar depending on number of points. I.E. 360/8 for example:

Using a clock face as reference

First point is created at twelve, next is created at six

Third is created at 7.5, next is created at 1.5

Fifth is created at 3, next is created at 9

Seventh is created at 10.5, next is created at 4.5

Using degrees:

First point at 0, next at 180

Third at 225, next at 45

Fifth at 90, next at 270

Seventh at 315, next at 135

Order does not matter as much as alternating sides of circle. I have looked through as many formulas as I could find, but can't wrap my head around this one.

Any help is appreciated.

panther42

Share this post


Link to post
Share on other sites

This is not tested but rather an example to point you in the rough general direction:

//x is the increment you want. so for 360/8 x = 45.

a = 1;
_point = 1;

while a = 1 do {

if _point > 360 then {_point = _point - 360};

while _point < 361 {
	_point = _point + 180;

	_point = _point + x;

	_point = _point + 180;

	_point = _point + x;

	_point = _point + 180;

	etc
}
}

Share this post


Link to post
Share on other sites

Hey there! You could do something like this. This is a function that takes the position and radius of a circle and spreads points around it's circumference evenly. Then it stores them in an array for later use. Passed arguments are (in order) position(coordinate array), radius(number), and number of points. Return is an array consisting of position(x,y,z) arrays.


_c = _this select 0;
_cX = _c select 0;
_cY = _c select 1;

_cR = _this select 1;

_points = _this select 2;

_a = 360 / _points;

_circlePoints = [];


for "_i" from 1 to _points do
{
_posX = round(_cX + _cR * cos(_a*_i));
_posY= round(_cY + _cR * sin(_a*_i));
_coords = [_posX, _posY,0];
_circlePoints set [count _circlePoints , _coords];
};

//return
_circlePoints
[/Code]

Edited by Tuliq

Share this post


Link to post
Share on other sites

Have a look in my All Round Defence addon for setting up points on a circle. There might be some useful stuff in there:

private ["_condx","_cond0","_cond1","_cond2","_cond3","_cond4","_cond5","_cond6","_cond7","_cond8","_cond9","_cond10","_cond11","_unit_position","_count_up","_array_eligible_units","_ARD_count","_ARD_count_old","_ARD_target_radius","_thisgroup","_unit_total","_side","_animState","_animStateChars","_animP"];

(group player) setVariable ["HORDE_ARD_new_ARD_order", 1, false];

HORDE_ARD_radius = round HORDE_ARD_radius;

_ARD_target_radius = (HORDE_ARD_radius + 100);
_thisgroup = group player;
_unit_total = units _thisgroup;

if (isNil ("HORDE_ARD_radius")) then
{
HORDE_ARD_radius = 10;
};

if (HORDE_ARD_radius > 100) then
{
HORDE_ARD_radius = 100;
};

if (vehicle player isKIndOf "Air" and HORDE_ARD_radius < 25) then
{
HORDE_ARD_radius = 25;
};

if (!isNil{(group player) getVariable "HORDE_ARD_trigger_active"}) then
{
deleteVehicle HORDE_ARD_hub_logic;
(group player) setVariable ["HORDE_ARD_trigger_active", nil, false];
};

///////////////////////////////////////////////

sleep 0.05;

player playAction "gestureFreeze";

sleep 1;

///////////////////////////////////////////////

player sideChat format["form all round defence %1m spread, bearing %2 degrees", HORDE_ARD_Radius, round (direction player)];

_side = format ["%1",side player];

HORDE_ARD_hub_logic = createTrigger [ "EmptyDetector", getPos (vehicle player) ];
HORDE_ARD_hub_logic setTriggerArea [ HORDE_ARD_Radius + 2, HORDE_ARD_Radius + 2, 0, false ];
HORDE_ARD_hub_logic setTriggerActivation [ _side, "NOT PRESENT", false ];
HORDE_ARD_hub_logic setTriggerTimeout [ 0, 0, 0, false ];
HORDE_ARD_hub_logic setTriggerStatements [ "{ alive (vehicle _x) } count thisList == 0", "deleteVehicle HORDE_ARD_hub_logic; {_x SetUnitPos 'auto'; _x doTarget objNull} forEach units group player; (group player) setVariable ['HORDE_ARD_trigger_active', nil, false]", "" ];
HORDE_ARD_hub_logic attachTo [vehicle player,[0,0,0.25]];
(group player) setVariable ["HORDE_ARD_trigger_active", 1, false];

sleep 0.05;

detach HORDE_ARD_hub_logic;

{_x setVariable ["HORDE_ARD_back_to_player", nil, false]} forEach _unit_total;

{_x SetUnitPos "auto"} forEach _unit_total;

(group player) setVariable ["HORDE_ARD_new_ARD_order", nil, false];

[] spawn HORDE_ARD_null_units;

_ARD_count_old = 999;

while {!isNil{(group player) getVariable "HORDE_ARD_trigger_active"} and isNil{(group player) getVariable "HORDE_ARD_new_ARD_order"}} do
{

_array_eligible_units = [];
{
//		if (vehicle _x != _x and !isPlayer _x and _ARD_count_old == 999 ) then {_x doMove getPos objNull; _x doFollow _x};
	if (currentCommand _x == "GET IN" and !isPlayer _x ) then { _x setVariable ["HORDE_ARD_back_to_player", 1, false]; _x SetUnitPos "auto"; _x doTarget objNull; _x doWatch objNull; };
//		if (_ARD_count_old != 999) then
//		{
//			if (player == formLeader _x and (vehicle player) != (vehicle _x) and !isPlayer _x ) then
////			if (_x != formLeader _x) then
//			{
//				_x setVariable ["HORDE_ARD_back_to_player", 1, false];
//				_x SetUnitPos "auto";
//				_x doTarget objNull;
//				_x doWatch objNull;
//			};
//		};
//		_condD = (vehicle _x distance HORDE_ARD_hub_logic <= 150);
	_condx = (isNil{_x getVariable "HORDE_ARD_back_to_player"});
	_cond0 = (isNil{_x getVariable "HORDE_ARD_unit_busy"});
	_cond1 = (!isPlayer _x);
	_cond2 = (_x != assignedGunner (vehicle _x));
	_cond3 = (_x != assignedDriver (vehicle _x));
	_cond4 = (_x != assignedCommander vehicle _x);
	_cond5 = (vehicle _x == _x);
	_cond6 = (vehicle _x isKindOf "Car");
	_cond7 = (vehicle _x isKindOf "Tank");
	_cond8 = (vehicle _x isKindOf "Air");
	_cond9 = (getpos vehicle _x select 2 < 2.2);
	_cond10 = (lifeState _x != "UNCONSCIOUS");
	_cond11 = ((assignedVehicleRole _x) find "Cargo" > -1);

	if ( (_condx and _cond0 and _cond1 and _cond2 and _cond5 and _cond10) or							// ON FOOT
	     (_condx and _cond0 and _cond1 and _cond2 and _cond6 and _cond10) or							// IN A CAR
	     (_condx and _cond0 and _cond1 and _cond2 and _cond3 and _cond4 and _cond7 and _cond10 and _cond11) or			// IN A TANK
	     (_condx and _cond0 and _cond1 and _cond2 and _cond3 and _cond4 and _cond8 and _cond9 and _cond10 and _cond11) ) then	// IN A CHOPPER/PLANE
	{
		_array_eligible_units set [count _array_eligible_units, _x];
	};
} forEach units _thisgroup;

_array_veh_units = [];
{
	if (_x != vehicle _x) then
	{
		_array_veh_units set [count _array_veh_units, _x];
	};
} forEach _array_eligible_units;

_array_eligible_units = _array_eligible_units - _array_veh_units;
_array_eligible_units = _array_eligible_units + _array_veh_units;

_ARD_count = count _array_eligible_units;

private ["_ARD_angle"];

if (_ARD_count == 0) then {_ARD_angle = 360} else {_ARD_angle = 360/_ARD_count};

if (_ARD_count != _ARD_count_old) then
{
	_animState = animationState player;
	_animStateChars = toArray _animState;
	_animP = toString [_animStateChars select 5,_animStateChars select 6,_animStateChars select 7];

	_count_up = 0;
	{

		if (vehicle _x != _x) then
		{
				unassignVehicle _x;
				doGetOut _x;
				waitUntil {vehicle _x == _x};
				sleep 0.5;
		};

//			if (vehicle _x == _x) then
//			{
			_x setUnitPos "AUTO";
			_unit_position = (HORDE_ARD_hub_logic modelToWorld [(sin (_count_up * _ard_angle)) * HORDE_ARD_radius, (cos (_count_up * _ard_angle)) * HORDE_ARD_radius, 0]);
			_x moveTo _unit_position;
			_x doMove _unit_position;
			_x doWatch (HORDE_ARD_hub_logic modelToWorld [(sin (_count_up * _ard_angle)) * _ARD_target_radius, (cos (_count_up * _ard_angle)) * _ARD_target_radius, 0]);
			[_x, _animP] spawn HORDE_ARD_unit_ready;
//			};
		_count_up = _count_up + 1;
		sleep 0.03;
	} forEach _array_eligible_units;
};

_ARD_count_old = _ARD_count;

sleep 0.8;

};

Share this post


Link to post
Share on other sites

I'm trying to do something somewhat related, but also simpler. Still, it's been *mumble* years since I've done any trig so I'm feeling kind of helpless. I figured it's better to post here than start a new topic...

Basically, I want to place an object at a random point somewhere on the circumference of a circle - limiting it to an arbitrary number of points (E.G. the 360 degree radials, minutes of a clock, etc.) would be fine, if it makes a difference.

I literally have no idea where to start. How does Arma deal with trig? Is there a resource for this somewhere that I am not finding?

Thanks!

edit:

It seems I managed to bang something out after poring over the examples from Tuliq and DasAttorney and dredging up some decades-old memories of trig classes:

while {true} do
{
//define values
_radial = (0 + (random 359));
_radius = 1000;
_X = round(_radius * cos _radial);
_Y = round(_radius * sin _radial);
//move game logic
spawn1 setPos [(getPos center1 select 0) + _X, (getPos center1 select 1) + _Y, 0];
sleep 30;
};

This moves a game logic (spawn1) every 30 seconds to a random position 1000 meters away from a defined position (center1).

Any problems with this? It does what I need it to, but I'm sure there's a better way since I have little idea what I'm doing. Still, it seems pretty simple, so maybe I'm done.

Edited by Harzach

Share this post


Link to post
Share on other sites

This should help you. the two variables that will concern you is the radius and the number of points.

_center_position = getPos center_position; ///I used a logic placed in the editor named center_position,
_number_of_points = 50;
_interval = 360/_number_of_points;
_radius = 1000;

_angle = 0;
for [{_index = 0},{_index < _number_of_points},{_index =_index + 1}] do{
_position = [(_center_position select 0)+sin(_angle)*_radius,(_center_position select 1)+cos(_angle)*_radius];
_angle = _angle + _interval;

_marker = format ['point_marker_%1',_index];
createMarker[_marker, _position];
_marker setMarkerType 'dot';
_marker setMarkerSize[0.5, 0.5];
_marker setMarkerDir 1;
_marker setMarkerColor 'Colorred';
_marker setMarkerText '';
};

You could put all the positions in an array and then randomly select one from the array later

Share this post


Link to post
Share on other sites

Thanks for all the replies. I think I've come up with something which works for what I need. Could use improvements I'm sure.

I will be posting a UAV deployment with patrol script example in the coming days using this formula. I wasn't happy with the "circular", or "rectangular" patrols for UAV's created by BIS or similar UAV scripts. These didn't give a good target approach for firing missiles. I also don't like using the BIS UAV module...

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  

×