Home > Software design >  Python (mathutils module) Problem finding closest vector in a list to a given rotation vector
Python (mathutils module) Problem finding closest vector in a list to a given rotation vector

Time:02-19

I'm writing a script to determine, for a given rotation, which of 8 vectors the rotation is closest to.

Each of these vectors corresponds to, e.g., looking straight on at a particular corner of a cube.

Corner 0: Vector( [45,  0, 135 ] )
Corner 1: Vector( [135, 0, 135 ] )
Corner 2: Vector( [45,  0, 45  ] )
Corner 3: Vector( [135, 0, 45  ] )
Corner 4: Vector( [45,  0, -135] )
Corner 5: Vector( [135, 0, -135] )
Corner 6: Vector( [45,  0, -45 ] )
Corner 7: Vector( [135, 0, -45 ] )

I noticed my approach was working correctly about 3/4 of the time. On further research, I noticed something odd. Corner 2 is treated as identical to Corner 1, and Corner 6 as identical to Corner 5.

import bpy
from mathutils import Vector

v1 = Vector( [135, 0, 135 ] )
v2 = Vector( [45,  0, 45  ] )
v5 = Vector( [135, 0, -135] )
v6 = Vector( [45,  0, -45 ] )

print( "Angle between v1 and v2: ", v1.angle( v2 ) )
print( "Angle between v5 and v6: ", v5.angle( v6 ) )

There is clearly a flaw in my understanding of the Vector.angle method. I have two questions.

  1. What am I missing, and
  2. What should I be doing instead to get my desired result?

EDIT: For clarity, The Corner 0: ... section is not actually code but was apparently edited to appear as such in order to be more readable.


EDIT 2: I just realized that I never specifically mentioned that this was a Python question (other than mentioning the mathutils module). I have updated the title accordingly.

CodePudding user response:

If you use the law of cosines you can write your own function to find the angle between any two vectors you want.

C^2 = A^2   B^2 - 2*A*B*cos(angle) 

If you do the math show in the video https://www.khanacademy.org/math/linear-algebra/vectors-and-spaces/dot-cross-products/v/defining-the-angle-between-vectors

You can get to this -> A dot B = lenthA * LengthB * Cos(angle)

If we solve for the angle we get

inverseCos(A dot B / (lenthA * LengthB)) = angle

so you can make a function that can calculate this to get the angle.

assuming you made the functions within such as length and dot for the dot product...

var angle = Math.acos(A.dot(B) /(length(A) * length(B)));

Maybe something like this will help ( I will assume you can find or make a function that returns a dot product between A and B)

function myAngle(A, B) {
  var lengthA = new Point(A).length;
  var lengthB = new Point(B).length;
  return Math.acos(A.dot(B) / (lengthA * lengthB));
}

CodePudding user response:

If you normalize your vectors, you can see that vector1 and vector2 are pointing in the same direction as [1,0,1]. I would suggest using numpy for vector computing.

As for your question here, I wonder if you are tring to use Rodrigues rotation axis. The relative rotation between Rodrigues rotation axes are not simple as regular vector operations. Maybe you could explain your vector meanings to help us understand your question.

  • Related