Relate Two Vectors to an Angle?

  • Context: Undergrad 
  • Thread starter Thread starter VX967
  • Start date Start date
  • Tags Tags
    Angle Vectors
Click For Summary

Discussion Overview

The discussion revolves around how to relate two vectors—specifically a steering vector and a kart's local orientation vector—to determine a signed angle for steering direction in a racing game being developed in Blender. The focus is on programming techniques and mathematical approaches for calculating angles in a 3D space, with an emphasis on distinguishing between left and right turns based on vector orientation.

Discussion Character

  • Technical explanation
  • Mathematical reasoning
  • Debate/contested

Main Points Raised

  • One participant describes the need to relate a steering vector and a local orientation vector to derive an angle for steering direction.
  • Another suggests creating a new variable that rotates the local orientation vector to determine the direction of the steering vector based on acute or obtuse angles.
  • A participant points out that the angle between two 3D vectors is always positive and proposes using the cross product to determine a signed angle based on the defined plane of projection.
  • Another participant emphasizes the importance of assuming the vertical axis is consistent to correctly determine angles within the kart's frame of reference.
  • One contribution discusses using the dot product to find the angle but notes that it does not provide direction, suggesting a method to rotate the steering vector into the kart's reference frame.
  • Several participants discuss the use of the cross product as a simpler method for obtaining a signed angle, with one questioning how to derive a signed angle without a third vector.
  • A participant shares their implementation of a proposed method in Python, indicating that they were able to achieve a clear distinction between left and right turns.
  • Another participant mentions that using a standard coordinate system could simplify future problem-solving and discussions.
  • One participant notes that the solution works but raises an issue regarding the steering actuator's settings overriding the kart's controls.
  • Another clarifies that arcsin can provide a signed angle, contrasting it with the dot product method which always yields a positive angle.

Areas of Agreement / Disagreement

Participants express various methods for calculating the angle and determining the direction of steering, with no clear consensus on a single approach. Multiple competing views on the best mathematical technique remain present throughout the discussion.

Contextual Notes

Some participants assume a specific orientation of the coordinate system, which may affect the applicability of their proposed solutions. Additionally, there are unresolved questions regarding the implementation details of vector operations in Blender.

Who May Find This Useful

Game developers, particularly those working with physics simulations in Blender, as well as individuals interested in vector mathematics and steering algorithms in 3D environments.

VX967
Messages
3
Reaction score
0
Hey there, I'm new to these forums. I'm currently trying to steer an AI kart for a racing game I'm making in Blender. I'm not sure if anyone on these forums has experience with programming games or AI, but here it goes.

Basically, there is a steering actuator that returns a steering vector (x,y,z). This traces the path that the kart should go around the track, and updates in real-time.

I also have the kart's local orientation, also in the form of a vector (x,y,z).

What I'm trying to do is somehow relate those vectors into an equation of some sort and come out with an angle.

So if the steering vector points to the right [relative to the kart's local orientation vector], it will come out with a positive angle [relative to the kart's front] and will turn the wheels positively to turn right. If the steering vector points to the left of the kart's local orientation, it will return a negative angle and steer the kart to the left.

[Note that I'm only looking for a clear distinction of left or right by using positive or negative. The wheels will always turn by a set amount, so the extremities of the values are ignored.]

If anyone is familiar with Blender or Python, here's the code I was suggested:

Code:
angle = obj.localOrientation[1].angle(steervector)

However, it always returns a positive value. I hope this question isn't too confusing. I can draw a diagram if necessary.

EDIT: I created a visual representation.
 

Attachments

  • Steering AI.png
    Steering AI.png
    8 KB · Views: 553
Last edited:
Physics news on Phys.org
Try creating a new variable which takes the local orientation angle and rotates it by a quarter turn clockwise (or anti-clockwise and reverse everything else I say), then if the angle between this new vector and the steer vector is acute you need to turn right and if it's obtuse you need to turn left.
 
VX967 said:
Code:
angle = obj.localOrientation[1].angle(steervector)

However, it always returns a positive value.

Yes, the 3D angle between two 3D vectors is always positive. To make it a signed angle you have to define a plane of projection (here the horizontal plane). Let's say:

I assume the vertical axis (Z) of the vehicle is obj.localOrientation[2] ?

Code:
angle = obj.localOrientation[1].angle(steervector)
if obj.localOrientation[1].crossProduct(steervector).dotProduct(obj.localOrientation[2]) < 0:
    angle *= -1.0

Note: I don't know the exact vector method names blender uses for cross and dot product. But it should be similar.
 
Last edited:
I'm going to assume that z=0 for both vectors, otherwise you do not have enough information to determine the angle correctly within the kart's frame of reference (i.e. this solution assumes that 'up' for the kart is always (0,0,1)). Assuming that, you are only dealing with (x,y) vectors and the solution is two fold:

Find the angle using dot product rules, \theta=arccos\left(\frac{A\cdot B}{\left\|A\right\|\;\left\|B\right\|}\right), which gives you angle but not direction.

What I do next is easy but hard to conceptualize. You 'rotate' the steering vector (x,y) into the kart's reference frame. This makes it appear that the kart's (x,y) = (1,0) then you just check the sign of the steering vector's y to determine direction.

(x_k,y_k) - kart
(x_s,y_s) - steering

n_{xk}=x_k/\sqrt{x^2_k+y^2_k}

n_{yk}=y_k/\sqrt{x^2_k+y^2_k}

y_{s,kart}=-n_{yk}\; x_s+n_{xk}\;y_s

If y_{s,kart}&lt;0 turn right, if positive turn left. If you want to switch the signs, multiply by a negative.

Edit:
I like A.T.'s cross-product solution, it seems the PHP (which I don't know) is easy to implement. But it makes the same assumption that 'z' is always up.
 
Last edited:
Edit:
I like A.T.'s cross-product solution, it seems the PHP (which I don't know) is easy to implement. But it makes the same assumption that 'z' is always up.

I used the local z-axis of the object. It could point anywhere in the global space, even downwards during a loop. He just has to make sure that the local system of his car object is:
x : towards the right door of the car
y : towards the front of the car
z : towards the roof of the car
 
I believe that the simplest solution would be to use the cross product formula directly. Unlike dot product, the angle in cross products is signed (you can tell from the fact that AxB = - BxA). This is because there is a sine instead of cosine.

Therefore, if you always place one of your vectors first in the cross product formula and solve for theta, "+" will always mean counterclockwise (so the other vector is on the first vector's "left"), and minus is always clockwise (so the other vector is on the first vector's "right").
 
meldraft said:
I believe that the simplest solution would be to use the cross product formula directly. Unlike dot product, the angle in cross products is signed (you can tell from the fact that AxB = - BxA). This is because there is a sine instead of cosine.

Therefore, if you always place one of your vectors first in the cross product formula and solve for theta, "+" will always mean counterclockwise (so the other vector is on the first vector's "left"), and minus is always clockwise (so the other vector is on the first vector's "right").

How do you "solve the cross product formula for theta" to get a signed theta? Are you suggesting that you can get a signed angle from the two vectors alone, without a third vector?
 
Thanks for the responses, guys. Unfortunately, I'm currently in high school physics, so a lot of the stuff you've said is way over my head. I apologize for that.

However, dispersion123, your second method seems plausible, and I was able to convert that formula into Python:

Code:
import GameLogic as GL
import math

cont = GL.getCurrentController()
kart = cont.owner
turn = 0.06

steervec = cont.actuators['Steering'].steeringVec
kartvec = kart.localOrientation[1]

kx = kartvec.x
ky = kartvec.y
sx = steervec.x
sy = steervec.y

nkx = kx / math.sqrt(kx**2 + ky**2)
nky = ky / math.sqrt(kx**2 + ky**2)

dkart = -(nky)(sx) + (nkx)(sy)

if dkart < 0:
	turn = turn

elif dkart > 0:
	turn = -turn

else:
	turn = 0.0

By the way, z is indeed the upward axis, so it can be ignored. The kart will already ride along the ground.

I haven't tried to implement this code just yet, but I will when I have time. Thanks for all the responses, guys! Hope this works.
 
Last edited:
If the coordinate system is car centered and the z component is always 0 (or whatever coordinate system used never has a z component for position or velocity), then meldraft is correct. There's only component to the cross product and that lies on the z, either positive or negative. (In other words, it's essentially the same solution you guys already stated).

Using positive x being in the direction of the door is fine, but that's a little non-standard. If the positive x is towards the front of the car, positive z is towards the bottom of the car, and y is perpendicular to both (using the right hand rule), you essentially have roll, pitch, and yaw.

Not a huge difference, but using a standard system makes it easier to find other people that have had to solve the same problem. Additionally, the solution you find will also be more likely to be useful on future problems.
 
  • #10
Alright, the good news is that it works! There's a clear distinction between the positive and negative values when running the script.

The only problem is that the steering actuator's velocity and steering settings seem to override the car's steering and gas, which is a problem that just relates to Blender. Otherwise, it works perfectly. I've been trying to figure this out for months, so thanks for all of your help, guys!
 
  • #11
Indeed the solution is essentially the same, I merely pointed out that it should be simpler to just solve the formula for theta :)

Arcsin spans from -pi/2 to pi/2 (in contrast to acos which is always positive (0 to pi)) so that is how you get the signed angle (http://en.wikipedia.org/wiki/Inverse_trigonometric_functions)
 
  • #12
Glad it worked VX967! I just realized you may be able to just use n_{xk}=x_k and n_{yk}=y_k. I believe that would be equivalent to the just using the 'z-term' of the cross-product. If you find yourself needing a bit more speed out of the code, you may try that.

A.T. said:
I used the local z-axis of the object. It could point anywhere in the global space, even downwards during a loop. He just has to make sure that the local system of his car object is:
x : towards the right door of the car
y : towards the front of the car
z : towards the roof of the car

That is the problem though, I don't believe he is keeping track of a local kart coordinate system. His orientation vector is measured in the global coordinate system, even if you assume his orientation vector is equal to (0,1,0)local, that doesn't give you the full orientation of the kart in 3D space, unless you assume that (0,0,1)local is always equal to (0,0,1)global. Even if he did have a full description, he would need to transform the vector obtained from the cross-product, which would be represented in the global frame, into the frame of the kart.
 

Similar threads

  • · Replies 21 ·
Replies
21
Views
3K
  • · Replies 5 ·
Replies
5
Views
4K
  • · Replies 21 ·
Replies
21
Views
1K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 12 ·
Replies
12
Views
3K
  • · Replies 6 ·
Replies
6
Views
1K
  • · Replies 15 ·
Replies
15
Views
1K
  • · Replies 6 ·
Replies
6
Views
3K
  • · Replies 5 ·
Replies
5
Views
6K
  • · Replies 14 ·
Replies
14
Views
3K