Author Topic: Angle between vectors  (Read 3266 times)

0 Members and 1 Guest are viewing this topic.

Offline sai`ke

  • Camper
  • ***
  • Posts: 318
  • Can't be arsed to remove christmas avatar
Angle between vectors
« 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.



All in- and output parameters are single floating point values.
Returns -1 when a zero length vector is given.

Code: [Select]
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;

« Last Edit: November 22, 2007, 04:36:32 am by sai`ke »
#soldat.ttw #ttw.gather --- Quakenet!
http://ttwforums.com

Offline rainrider

  • Soldier
  • **
  • Posts: 145
    • rrhp
Re: Angle between vectors
« Reply #1 on: November 14, 2007, 08:20:17 am »
atan2

Offline EnEsCe

  • Retired Soldat Developer
  • Flamebow Warrior
  • ******
  • Posts: 3101
  • http://enesce.com/
    • [eC] Official Website
Re: Angle between vectors
« Reply #2 on: November 14, 2007, 09:05:18 am »
I think this should be in general scripting chat or something...

Offline sai`ke

  • Camper
  • ***
  • Posts: 318
  • Can't be arsed to remove christmas avatar
Re: Angle between vectors
« Reply #3 on: November 14, 2007, 09:12:27 am »
Okay, whatever floats your boat :P. I can't move it there so an admin should do that then.

Atan2?
#soldat.ttw #ttw.gather --- Quakenet!
http://ttwforums.com

Offline Kavukamari

  • Camper
  • ***
  • Posts: 435
  • 3.14159265358979, mmm... pi
Re: Angle between vectors
« Reply #4 on: November 15, 2007, 12:50:47 pm »
what is arctan()?

P.S. I made a slope script, it finds the slope between two coords, should I post it?
« Last Edit: November 15, 2007, 12:55:13 pm by Kavukamari »
"Be mindful of fame, show a mighty courage, watch against foes. Nor shalt thou lack what thou desirest, if with thy life thou hast comest out from that heroic task."

Offline urraka

  • Soldat Developer
  • Flagrunner
  • ******
  • Posts: 703
Re: Angle between vectors
« Reply #5 on: November 15, 2007, 12:58:28 pm »
The inverse function of tan. It's trigonometry.
urraka

Offline sai`ke

  • Camper
  • ***
  • Posts: 318
  • Can't be arsed to remove christmas avatar
Re: Angle between vectors
« Reply #6 on: November 15, 2007, 02:18:27 pm »
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.
#soldat.ttw #ttw.gather --- Quakenet!
http://ttwforums.com

Offline urraka

  • Soldat Developer
  • Flagrunner
  • ******
  • Posts: 703
Re: Angle between vectors
« Reply #7 on: November 22, 2007, 03:28:50 am »
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.

Code: [Select]
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
urraka

Offline sai`ke

  • Camper
  • ***
  • Posts: 318
  • Can't be arsed to remove christmas avatar
Re: Angle between vectors
« Reply #8 on: November 22, 2007, 04:38:24 am »
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.
#soldat.ttw #ttw.gather --- Quakenet!
http://ttwforums.com

Offline Kavukamari

  • Camper
  • ***
  • Posts: 435
  • 3.14159265358979, mmm... pi
Re: Angle between vectors
« Reply #9 on: December 03, 2007, 08:34:18 pm »
Here is my SlopeCalc script if you want it, is pretty useless...

Code: [Select]
function SlopeCalc(const X1, X2, Y1, Y2: single):single;
begin
  Result:=RoundTo(((Y2-Y1)/(X2-X1)),2);
end;

ps it rounds to hundredths place
"Be mindful of fame, show a mighty courage, watch against foes. Nor shalt thou lack what thou desirest, if with thy life thou hast comest out from that heroic task."

Offline poutch

  • Major(1)
  • Posts: 34
Re: Angle between vectors
« Reply #10 on: December 04, 2007, 09:30:47 am »
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 :

Code: [Select]
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 ^^
« Last Edit: December 04, 2007, 10:42:33 am by poutch »
www.pleez.fr .... coming soon

Offline Kavukamari

  • Camper
  • ***
  • Posts: 435
  • 3.14159265358979, mmm... pi
Re: Angle between vectors
« Reply #11 on: December 06, 2007, 12:13:49 pm »
you could probably code arccos, but the computer would still be doing the same math (if my thinking is correct...)
"Be mindful of fame, show a mighty courage, watch against foes. Nor shalt thou lack what thou desirest, if with thy life thou hast comest out from that heroic task."