I’m trying to calculate the angle between two vectors and get it in degrees, and then rotate an object by this angle. Problem is that in some cases, I get an angle that is off by exactly 180 degrees. PyMEL has datatypes for Vectors and Matrices, and I would prefer to use these if possible instead of writing the formulas by hand in Python.

print math.degrees(v1.angle(v2)) * sign[/QUOTE]
Thanks a lot. Flipping v2 was what I had missed to do!

Another similiar problem:
I’m trying to get the offset vector between two line segments (normalized vectors) like in the picture below. I know the positions of the points in the coordinate system if that is of any help:

Problem is that I get random end-to-end vectors like in the picture below, instead of getting the vector from and to the midpoints.

If you need to find exactly the same vector as drawn on the picture, you can do next:
v1 = pm.Vector(p2[0] - p0[0], p2[1] - p0[1], 0)
v2 = pm.Vector(p3[0] - p1[0], p3[1] - p1[1], 0)
v3 = (v1 + v2) * 0.5

[QUOTE=Styler;29842]If you need to find exactly the same vector as drawn on the picture, you can do next:
v1 = pm.Vector(p2[0] - p0[0], p2[1] - p0[1], 0)
v2 = pm.Vector(p3[0] - p1[0], p3[1] - p1[1], 0)
v3 = (v1 + v2) * 0.5

This will give you a midpoint vector

[/QUOTE]
Actually it’s the KM vector that I’m after.
Btw where did you find that picture?

I was after the other bimedian and not the one you specified. However I got the formula right now:

# targetP0 - target vector point 0, in the form of pm.datatypes.Point()
# sourceP1 - source vector point 1...
# etc...
# Calculate midpoints for the offset vector
targetMid = []
targetMid.append((targetP0[0] + targetP1[0]) / 2)
targetMid.append((targetP0[1] + targetP1[1]) / 2)
sourceMid = []
sourceMid.append((sourceP0[0] + sourceP1[0]) / 2)
sourceMid.append((sourceP0[1] + sourceP1[1]) / 2)
offsetVector = pm.datatypes.Vector(targetMid[0] - sourceMid[0], targetMid[1] - sourceMid[1], 0.0)
# Win

Either way, that was off-topic actually. So to get back to the original problem: It turns out that the problem I have in my original post of this thread is still there. I still don’t get the correct rotation angle for the vectors!!

# targetP0 - target vector point 0, in the form of pm.datatypes.Point()
# sourceP1 - source vector point 1...
# etc...
# Create vectors
sourceVector = pm.datatypes.Vector(sourceP1[0] - sourceP0[0], sourceP1[1] - sourceP0[1], 0.0)
targetVector = pm.datatypes.Vector(targetP0[0] - targetP1[0], targetP0[1] - targetP1[1], 0.0)
# Calculate dot product and get sign for the angle
temp = sourceVector.dot(targetVector)
if temp > 0: # Same
sign = 1
elif temp < 0: # Opposite
sign = -1
sourceVector = -sourceVector
else: # Perpendicular
sign = 0
# Calculate angle - returns unsigned angle as degrees
angle = math.degrees(sourceVector.angle(targetVector))
# Set correct sign
angle = angle * sign
# Rotate by the value in angle

What end result I get is dependant on the directions of the targetVector and sourceVector. If I rotate one of them juuust enough, everything turns out all right. But if their directions happen to be “wrong” somehow, I get an error of either 180 degrees minus the angle, or the angle but with an inverted sign.

This is really frustrating. The math looks solid so what am I missing?
Maybe the function angle() is incorrectly used? The docs says it returns the angle in radians, and that the returned value is unsigned and that axis() should be used to find the sign. But I’ve already calculated the dot product so why is this even needed?