Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Need a formula to calculate angle between two points.
#1
I need a formula that can calculate the angle(preferably in degrees) between any two points.

The reason is that I am coding some AI for my car game. When the AI is in attack mode, it needs to turn towards the player. I can't seem to figure out a formula that can correctly calculate the angle between the player and the AI. Also, I can't find one in my Trig book. :-? Could it be that my much needed formula does not exist?!
nd remember kids, only you can provoke forest fires!
Reply
#2
You could simply use ATN() (arc-tangent), but the range of that function is limited to the 4th and 1st quadrants because it's not a one-to-one function.

You can compensate like so (not fully tested, but right idea):

Code:
qbasic
CONST pi = 3.1415926535898#
INPUT "x1, y1: ", x1, y1
INPUT "x2, y2: ", x2, y2
IF x2 <> x1 THEN
  a = ATN((y2 - y1) / (x2 - x1))
  IF x2 < x1 THEN a = a + pi
ELSEIF y2 > y1 THEN
  a = pi / 2
ELSE
  a = 3 * pi / 2
END IF
IF a < 0 then a = 2 * pi + a
PRINT a * (180 / pi); " degrees"
Reply
#3
Angles between dots doesn't make sense, so you probably mean something slightly different. Smile

I would imagine that you actually have this information:

1) You have the position co-ordinate of an enemy.
2) You have the position co-ordinate of your bot
3) You have the direction vector of your bot

Firstly, translate all of these into vectors; you have 2 position vectors and 1 direction vector.

Now you need to make your calculations relative to the bot position vector, so subtract the position vector of the bot from the position vector of the bot and the position vector of the enemy (store these in some temporary vector variables, by the way). Now you have a direction vector and the position vector of the enemy relative to the bot position.

It is simple to find the angle between the two now by using the property that: a . b = |a||b|cos(theta)

Rearrange:-

cos(theta) = (a . b) / |a||b|

Now it is simple to find an expression for theta (the angle that your bot has to turn):-

theta = arccos((a . b) / |a||b|)

Here is a bit of untested pseudo-code:-

[syntax="QBASIC"]

TYPE Vec2D
x AS SINGLE
y AS SINGLE
END TYPE

...

' Assuming we have 3 vectors here:- the direction vector of the
' bot (bot-dir), the position vector of the bot and the position
' vector of the enemy.

DIM enemyRelativePosition AS Vec2D

enemyRelativePosition.x = enemyPosition.x - botPosition.x
enemyRelativePosition.y = enemyPosition.y - botPosition.y

' Since the direction vector is already relative to the bot position,
' we don't need to translate it.

dotProduct! = (enemyRelativePosition.x * botDirection.x) + (enemyRelativePosition.y * botDirection.y)
modDirection! = SQR((botDirection.x * botDirection.x) + (botDirection.y * botDirection.y))
modRelativeEnemyPosition! = SQR((enemyRelativePosition.x * enemyRelativePosition.x) + (enemyRelativePosition.y * enemyRelativePosition.y))

' Calculate the value of COS(theta!)
cosTheta! = dotProduct! / (modDirection! * modRelativeEnemyPosition!)

' QB only gives us arctan, which is a pain in the arse.
' So, anyway, did some working and this should work to get
' theta out of COS(theta) using ATN.
'
' Here is my working for this:
'
' tan x = (sin x) / (cos x)
' Thus: tan^2 x = (sin^2 x) / (cos^2 x)
'
' sin^2 x = 1 - cos^2 x
'
' Thus: tan^2 x = (1 - cos^2 x) / (cos^2 x)
' Thus: tan x = SQR((1 - cos^2 x) / (cos^2 x))
'
' And finally: x = ATN(SQR((1 - cos^2 x) / (cos^2 x)))
'

tanTheta! = SQR( (1 - (cosTheta! * cosTheta!)) / (cosTheta! * cosTheta!) )

' Finally, we can find theta.

theta! = ATN(tanTheta!)

' This is the angle that we need to turn to face the enemy.
[/syntax]

Like I said, untested code, but the theory, as far as I know, is correct. I tried to explain it quite a bit so hopefully it's okay to follow.

-shiftLynx
img]http://www.cdsoft.co.uk/misc/shiftlynx.png[/img]
Reply
#4
Heh, thanks for taking the time to help. After a little bit of tinkering I got RST's code to work. Thanks anyways, Shift, but my problem wasn't that complicated.
nd remember kids, only you can provoke forest fires!
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)