Official Soldat Forums
Server Talk => Scripting Releases => Topic started by: sai`ke on November 13, 2007, 03:20:28 pm
-
Function to compute the smallest angle between vectors.
Consider two vectors v1 and v2, each with an x and y component, then this function will return the smallest angle between them in degrees.
(http://upload.wikimedia.org/wikipedia/commons/thumb/7/72/Scalarproduct.gif/300px-Scalarproduct.gif)
All in- and output parameters are single floating point values.
Returns -1 when a zero length vector is given.
function angle( v1x, v1y, v2x, v2y: single ): single;
var
cosangle: single;
dist: single;
begin
dist := ( distance( 0, 0, v1x, v1y ) * distance( 0, 0, v2x, v2y ) );
if dist = 0 then
begin
Result := -1;
exit;
end
cosangle := ( v1x * v2x + v1y * v2y ) / dist;
Result := 90 - 720 * ( arctan( cosangle / ( 1 + sqrt( 1 - cosangle * cosangle ) ) ) ) / (2 * pi);
if FloatToStr(Result) = 'NAN' then
Result := 0.0;
end;
-
atan2
-
I think this should be in general scripting chat or something...
-
Okay, whatever floats your boat :P. I can't move it there so an admin should do that then.
Atan2?
-
what is arctan()?
P.S. I made a slope script, it finds the slope between two coords, should I post it?
-
The inverse function of tan. It's trigonometry.
-
The arctan formula mess in there is actually a way to calculate the inverse cosine since it isn't available in the scriptcore nor in regular pascal.
-
I modified a bit your function. First, your are checking if dist equals 0 after making a division by dist. So I moved that line. And second, sometimes the function returns NAN if the points are very close to each other. So I made it return 0 in that case.
function angle( v1x, v1y, v2x, v2y: single ): single;
var
cosangle: single;
dist: single;
begin
dist := ( distance( 0, 0, v1x, v1y ) * distance( 0, 0, v2x, v2y ) );
if dist = 0 then
begin
Result := -1;
exit;
end
cosangle := ( v1x * v2x + v1y * v2y ) / dist;
Result := 90 - 720 * ( arctan( cosangle / ( 1 + sqrt( 1 - cosangle * cosangle ) ) ) ) / (2 * pi);
if FloatToStr(Result) = 'NAN' then
Result := 0.0;
end;
Btw, thanks for this script. Checking for angle >= 90 between the current and the last position (relative to the checkpoint) seems to be working almost perfectly in PerroRACE :P
-
Haha, yea oops. I'll also edit the script in the initial post then. Well I only tested it for a specific number of angles for which the NAN thing did not occur. They probably arise from numerical problems.
-
Here is my SlopeCalc script if you want it, is pretty useless...
function SlopeCalc(const X1, X2, Y1, Y2: single):single;
begin
Result:=RoundTo(((Y2-Y1)/(X2-X1)),2);
end;
ps it rounds to hundredths place
-
instead of 720 * (...) / (2 * pi);
u can do 360 * (...) / pi which would use less cpu operations
and you could also use acos which is more direct :
function angle( v1x, v1y, v2x, v2y: single ): single;
begin
Result := 180 / pi * acos( (v1x*v2x + v1y*v2y) / sqrt( (v1x*v1x + v1y*v1y) * (v2x*v2x + v2y*v2y) ) );
end;
*edit* ok you don't have arccos on the scriptcore so you can keep arctan ^^
-
you could probably code arccos, but the computer would still be doing the same math (if my thinking is correct...)