rejenorst 18 Posted October 27, 2014 (edited) I am not sure if this is useful but: I was searching for a quick and easy way of generating positions in an arc that could be used for flanking waypoints. I came across this forum post which showed a formula for brezier curves taken from wikipedia: http://www.coderanch.com/t/480970/Game-Development/java/plot-curve-points http://en.wikipedia.org/wiki/B%C3%A9zier_curve I decided to use that code and alter it to ARMA script while making some adjustments to allow for the user to sample only a few points along the curve with the end point being the _end point. Add this to init.sqf or rename the function as you see fit: rej_fnc_bezier = compile preProcessFileLineNumbers "rej_fnc_bezier.sqf"; Create a rej_fnc_bezier.sqf or a renamed version as you see fit and add it to the mission folder then add the following code: //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //-- This script is a Bezier Curve function and will return a specified number of points along the Bezier Curve --// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private["_vector1","_vector2","_controlVector","_numberOfPoints","_removeStartPos","_x","_y","_increments","_positions"]; _vector1 = _this select 0; _vector2 = _this select 1; _controlVector = _this select 2; _numberOfPoints = _this select 3; _removeStartPos = _this select 4; ///////////////////////////////////////////////////////////////////////////////////////////////////////////// //-- Double distance for the control vector to make the peak of the curve pass through the controlVector --// ///////////////////////////////////////////////////////////////////////////////////////////////////////////// _midPoint_1 = ((_vector1 select 0) + (_vector2 select 0)) / 2; _midPoint_2 = ((_vector1 select 1) + (_vector2 select 1)) / 2; _midPoint = [_midPoint_1,_midPoint_2,0]; _midPoint_1 = ((_vector1 select 0) + (_vector2 select 0)) / 2; _midPoint_2 = ((_midPoint select 1) + (_midPoint select 1)) / 2; _midPoint = [_midPoint_1,_midPoint_2,0]; _vectorDiff = _controlVector vectorDiff _midPoint; _controlVector = _controlVector vectorAdd _vectorDiff; ///////////////////////// //-- Calculate curve --// ///////////////////////// if (_numberOfPoints >= 1) then { _increments = 1 / _numberOfPoints; _positions = []; for [{_i = 0.0},{_i <= 1},{_i =_i + _increments}] do { _x = ((1 - _i) * (1 - _i) * (_vector1 select 0) + 2 * (1 - _i) * _i * (_controlVector select 0) + _i * _i * (_vector2 select 0)); _y =((1 - _i) * (1 - _i) * (_vector1 select 1) + 2 * (1 - _i) * _i * (_controlVector select 1) + _i * _i * (_vector2 select 1)); _positions pushback [_x,_y,0]; _markname = format["%1 %2%3",("testmarker"),(ceil random 999),(ceil random 999),(ceil random 999)]; //-- For demo purpose only. Please remove. _marker = createMarker [_markname,[_x,_y,0]]; //-- For demo purpose only. Please remove. _markname setMarkerType "hd_dot"; //-- For demo purpose only. Please remove. _markname setMarkerColor "ColorBlack"; //-- For demo purpose only. Please remove. }; if (_removeStartPos) then { _positions deleteAt 0; }; } else { _positions = _vector2; }; _positions Call the function as follows: _curvePositionsArray = [startPos,endPos,controlPos,4,true] call rej_fnc_bezier; hint format["POSITIONS RETURNED: %1",(curvePositionsArray)]; -Where _startPos is the starting position, -Where _endPos is the destination position, -Where _controlPos is the position where the curve should flex towards. I've coded it so that the peak or the curve near the peak should pass through the controlPos. This is the direction where the curve tip will point towards and hopefully pass through. -Where 4 can be any number of points you want returned in the array *, -Where true is whether or not you want the starting point returned in the array (it will always be included in the array regardless of whether you asked for 1 position or more to be returned so use this to delete the starting Position from the array. * Make sure you use whole numbers. Using anything less that 1 will return the end position and using any non whole numbers like 1.9 will probably not return the end destination. I tested 1.9 and it landed me somewhere in the middle of the curve. Note: I added a quick marker generation for the points so you can get a visual representation of the points being generated. Feel free to remove. I only spent a short time testing this script out so let me know if there are any weird problems . Edited October 29, 2014 by Rejenorst Share this post Link to post Share on other sites
Jigsor 176 Posted October 27, 2014 This is very cool. Good thinking outside of the box. Could be very handy for waypoints. Would it be possible to double the distance of curve peak in the function so precalculations are not necessary for accuracy? Kinda off topic but, it would be cool to see similar function calculating parabola curve to be used in a spinning radar simulation. Anyway, this has great potential. Very nice. Share this post Link to post Share on other sites
rejenorst 18 Posted October 28, 2014 (edited) I've updated the code to have the curve pass through the control point. It was a lot less difficult then I at first thought. I thought I might have to use a logic and the modeltoworld and dir function but I figured since its an obtuse triangle I could just get the midpoint of the line between vector1 and vector2 and then the midpoint between that midpoint and vector1 to get a difference in x & z coords between that midpoint and vector1. Then add that to the controlpoint to effectively double the distance. For the most part the peak will usually pass through the controlpoint unless you place the control point behind vector1 or vector2 in which case the peak may or may not be a little off but the curve will or should still pass through the control point. *Note I've renamed the function.sqf etc as I renamed my function to a bezier curve rather than a parabola which was my initial aim until I found bezier. Also what did you have in mind with your radar simulation? Do you mean a GUI radar or a script that moves a line around the map in a circle and checks if any objects like planes etc pass through it which then updates it to the map? The latter wouldn't require any parabola. One could just use a loop script which uses a logic and spins it around slowly while checking lineintersects or whether the object is in the angle of view of the logic (not 100% sure if that would work but yeah). For the GUI simulating a radar screen it would require a sine curve I think for the old fashioned ww2 radar screens or a rotating line animation over a small black circle (which would be easier). Edited October 28, 2014 by Rejenorst Share this post Link to post Share on other sites
Jigsor 176 Posted October 28, 2014 Rejenorst, the update of passing through the control point is great and is working with accuracy. For the radar, I was over thinking how the how reflections would work, but line intersects would work just fine as the radar receiver would only ping when one of the beam axis is aligned with object anyways I believe. Good stuff, thank you. Share this post Link to post Share on other sites
rejenorst 18 Posted October 28, 2014 (edited) No worries :D Glad the script is of use to someone other than me :) Thank you for testing and giving feedback. EDIT: have updated the code to take advantage of array pushback and deleteAt commands which are likely more optimized. Edited October 29, 2014 by Rejenorst Share this post Link to post Share on other sites