Calculate Rotation Based On Two Points?

Hi All,

I am trying to make and auto-aligner for the particle system. Each particle has a previous location and current location. So I want to use those two values to determine a rotation for an object placed at the current current location. This way the object would align to the path the particle was traveling.

@CoDEManX: At this link you mention “you can turn any two points into a direction”.

Do you or anyone know how to take two points and return a rotation_euler(x,y,z) angles or radians?


import bpy

ob_emitter = bpy.data.objects.get("Cube")
psys = ob_emitter.particle_systems[0]
if psys != None:
    print("
particle_list")
    c = 0
    for p in psys.particles:
        print("Particle #%i" %c)
        print(p.location)
        print(p.prev_location)
        print(p.location-p.prev_location)
        # Need a line here to calculate the ROT (X,Y,Z) from locations.
        print("")
        c = c + 1

I am digging around and wonder if atan2 might be part of the solution.


angle=math.atan2(-(pos1[1]-pos2[1]), pos1[0]-pos2[0])

Not sure how to factor in the third dimensions though…

I think I have a solution for you. First you need two vectors instead of just the one you generate from those two particle locations, I’ll call them vector A and B.

Vector A is the (normalized) ‘forward’ axis of the object you want to place at the particle.
Vector B is “p.location-p.prev_location”

Then do something like this:


# make sure this stuff is imported
from mathutils import Vector, Quaternion

# normalize B (A and B should both be normalized)
B.normalize()

# cross and dot products of A and B
C = A.cross(B)
D = A.dot(B)

# create and normalize a quaternion
Q = Quaternion((D+1, C[0], C[1], C[2]))
Q.normalize()

# now you can apply the quaternion to your Object
bpy.data.objects['myObject'].rotation_quaternion = Q

# or convert it to euler rotation
Rot = Q.to_euler()

Hope this helps :wink: I needed a similar piece of code myself and found some useful answers on this page: http://stackoverflow.com/questions/15101103/euler-angles-between-two-3d-vectors

The tilt direction is undefined.

An example


import bpy
from mathutils import Vector, Quaternion

#empty Plain Axes
A = bpy.data.objects['A']
B = bpy.data.objects['B']
#empty Single Arrow - align its z-axis with the direction from b to a
C = bpy.data.objects['C']

a = A.location
b = B.location

direction  = (a - b).normalized()
axis_align = Vector((0.0, 0.0, 1.0))

angle = axis_align.angle(direction)
axis  = axis_align.cross(direction)

q = Quaternion(axis, angle)

C.location = b
C.rotation_euler = q.to_euler('XYZ')
#if rotation_mode == "QUATERNION":
#C.rotation_quaternion = q

You can turn two points into a direction vector and assume it to be e.g. the Z-vector of a 3x3 matrix, but you actually need a third point to find out the different in rotation…

Maybe have a look here: http://blender.stackexchange.com/a/7152/1363

If there’s a reference like a global axis, you could calculate the angle between your vector and this axis (another vector).