Manual Align Axis to Vector

I’m just wondering how to manually align an axis to a vector.


I don’t need this for a specific reason, I’m just interested in how it’s done; understanding how things work would allow me to implemented concepts into my code. On top of that, not all languages have such a convenient method for object types.

Thank you!

<disclaimer> I haven’t done any courses involving vectors properly, but here is my understanding. Anyone who see’s something that I’ve done wrong, then correct me.</disclaimer>

Do you understand what a vector is?

A vector is an angle, but represented as a 3D co-ordinate. The vector is visualised by drawing a line between this point and the origin.
By using vectors we can add, subtract and multiply them more easily.

So to align an axis to a vector, you first have to have a vector. So let’s make one up:

import mathutils

vec1 = mathutils.Vector((0,0,1))
vec2 = mathutils.Vector((0,1,0))

Vec1 is a vector pointing straight up, and vec2 is a vector pointing across on the positive Y axis.

Vectors don’t have to have a length of 1, and when representing things like velocity or forces, they don’t. If we have the vectors [0,0,1] and [0,0,2] they have the same angle, and thus the same result in the alignAxisToVect function, but they are different vectors.
A vector with a length of 1 is known as a normalized vector.

Vectors can be split into their X, Y and Z components. This is simple in blender:

x = vec1[0]
y = vec1[1]
z = vec1[2]

#Or we can use:

x = vec1.x
y = vec1.y
z = vec1.z

So, creating vectors and splitting them up is all very good, but sometimes we want to get vectors from things. BGE provides us with some good functions such as:

import bge

cont = bge.logic.getCurrentController()
obj = cont.owner

other = [o for o in bge.logic.getCurrentScene().objects if == 'Cube'][0]

distance, globalVector, localVector = obj.getVectTo(other) #Get's the vectors between two objects
ZAxisVect = obj.getAxisVect([0,0,1]) 

We can manipulate them. We can multiply them with a number to make them bigger (makes no difference to the angle), we can add two vectors etc.

Now, what can we do with them?
Well, BGE also has a number of good functions for this:

  • applyForce
  • applyTorque
  • alignAxisToVect
  • apply impulse
import bge

cont = bge.logic.getCurrentController()
obj = cont.owner

vect = mathutils.Vector((0,0,1))

obj.applyForce(vect, 1) #Applies a local force on the Z axis
obj.alignAxisToVect(vect, [0,1,0], 0.5) #Aligns the objects Y axis to the global Z axis with some smoothing

In many cases we don’t need to convert them to mathutils vectors. The only reason you may want to do this is if you want to use a mathitils function, such as normalizing, projecting, addition. Otherwise, just keep it as a simple list.

I hope that gave you somewhere to start.

manually? you mean with pen and paper? :smiley:
i know just a bit the “level below” …:slight_smile:

well, I have this , just right now i found another method , instead of interpolate the quaternion(after)
we can interpolate the vector before .
this can way become a lot more short.(and probably a bit more fast)

you have to grab 2 vector , the vector to align (we say the Y axis) and the vector to orient (target)
the vector have a function -> v1.rotation_difference(v2)
that return a quaternion .
so , you can interpolate this quaternion and then multiplicate it with the old matrices(trasfomed in to quaternion).this is the old method.

otherwise , you interpolate first the vector , then get the difference between the old vector and the vector interpolated.
then multiply this quaternion with a old matrices:

from mathutils import Vector
own = cont.owner

WO = own.worldOrientation
v1 = WO.col[1] #Y axis
v2 = Vector((0,0,1)) #note that this must be normalized if is not

#now, interpolation of the 2 vector
v3 = v1.lerp(v2, 0.1) #note that 0.1 is the equivalent of the 3° argument of alignAxisToVect()

#now get the quaternion difference
qDif = v1.rotation_difference(v3)

own.worldOrientation = qDif * WO.to_quaternion() # .to_matrix() is avoidable

voila :slight_smile:

If you really want to understand what’s going on when we do things like rotations and alignment, you should brush up on linear algebra. I personally find the stuff gives me a head ache and am glad we have built in methods to handle this stuff for us. Maybe someone more mathematically inclined can help explain the details to you.

If you want to know exactly how the alignAxisToVect method works, you can probably just take a look at the source code.

My understanding of vectors is basically everything you wrote, sdfgeoff, (at least regarding the concept and ideas you wrote) maybe a little more than that. I really only got into vectors when I started programming in BGE. Everything I know about them are little things people have told me about or ideas I have come to develop over time. However; I feel I understand the basics (at least to be able to use them consistently and efficiently in my code); magnitude, direction, angle, addition, normalization are all things I’m familiar with. :slight_smile:

MarcoIT: I’ll have to search up a few terms you’ve used to fully understand your explanation haha

Mobious: Ahh, linear algebra, that’s something I’m actually looking into in school right now. And the problem with looking at the source is that I’m not too familiar with C++. I know how to write code for it, but there’s a difference between being able to write in a computer language and program in a computer language. d:

Thanks for the comments!

someone can copy and paste the original code of alignAxisToVect() ?

just for curiosity