Relate Two Vectors to an Angle?

In summary, the conversation revolved around using vectors to steer an AI kart in a 3D racing game being created in Blender. The challenge was to relate the steering vector and the kart's local orientation vector to determine the angle in which the kart should turn. Various solutions were suggested, including using the dot product rule, rotating the steering vector into the kart's reference frame, and using the cross product formula. A visual representation was also created to explain the concept in more detail. The conversation also touched upon assumptions about the kart's local system and the use of the z-axis. One of the participants shared a Python code that implements the solution using the cross product formula. The conversation concluded with the hope that the code will be implemented successfully.
  • #1
VX967
3
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: 486
Last edited:
Physics news on Phys.org
  • #2
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.
 
  • #3
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:
  • #4
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, [itex]\theta=arccos\left(\frac{A\cdot B}{\left\|A\right\|\;\left\|B\right\|}\right)[/itex], 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.

[itex](x_k,y_k)[/itex] - kart
[itex](x_s,y_s)[/itex] - steering

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

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

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

If [itex]y_{s,kart}<0[/itex] 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:
  • #5
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
 
  • #6
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").
 
  • #7
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?
 
  • #8
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:
  • #9
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 [itex]n_{xk}=x_k[/itex] and [itex]n_{yk}=y_k[/itex]. 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.
 

Related to Relate Two Vectors to an Angle?

What is the definition of a vector?

A vector is a mathematical object that has both magnitude (size) and direction. It is typically represented by an arrow pointing in the direction of the vector and with a length representing its magnitude.

How are vectors related to angles?

Vectors can be used to represent angles in a geometric or mathematical context. The direction of a vector can be thought of as the direction of an angle, and the magnitude of a vector can be thought of as the measure of an angle.

How can two vectors be related to an angle?

Two vectors can be related to an angle by using the dot product or the cross product. The dot product of two vectors yields the cosine of the angle between them, while the cross product yields the sine of the angle. These relationships can be used to calculate the angle between two vectors.

What is the difference between the dot product and the cross product?

The dot product is a scalar quantity that yields the cosine of the angle between two vectors. The cross product is a vector quantity that yields the sine of the angle between two vectors. Additionally, the dot product is commutative, while the cross product is anti-commutative.

Can vectors be used to represent three-dimensional angles?

Yes, vectors can be used to represent angles in three-dimensional space by using the concept of vector components. Instead of just having a magnitude and direction, three-dimensional vectors have three components: x, y, and z. These components can be used to calculate the angle between two three-dimensional vectors.

Similar threads

  • Other Physics Topics
Replies
5
Views
5K
Replies
21
Views
2K
Replies
2
Views
1K
  • Introductory Physics Homework Help
Replies
15
Views
296
Replies
14
Views
1K
Replies
5
Views
1K
Replies
2
Views
2K
  • Calculus and Beyond Homework Help
Replies
4
Views
2K
  • Introductory Physics Homework Help
Replies
2
Views
2K
  • Programming and Computer Science
Replies
1
Views
2K
Back
Top