Get rotational vector that matches normal [SOLVED]
-
On 09/02/2015 at 03:58, xxxxxxxx wrote:
I have a plane.
I can get the normal vector like this:
obj = GetObjectByName("Plane") obj_mat = obj.GetMg() p = obj.GetPolygon(0) points = obj.GetAllPoints() # Get global coords of points. p1, p2, p3 = points[p.a] * obj_mat, points[p.b] * obj_mat, points[p.c] * obj_mat # Calc the plane normal from three of the points. vec_normal = (p2 - p1).Cross(p3 - p1).GetNormalized() print vec_normal
How do I get the same angle with a null oriented the same way as the plane, or straight from the plane rotation?
I tried:
obj = GetObjectByName("Plane") obj_mat = obj.GetMg() obj_rot_vec, w = c4d.utils.MatrixToRotAxis(obj_mat) print obj_rot_vec
But, this didn't give me the same rotation vector. The 'w' rotation isn't needed.
I just want to get a 'normal' vector from the direction the null is pointed.Thanks.
-
On 09/02/2015 at 05:54, xxxxxxxx wrote:
Hello Christopher,
this matrix transformation might help you?
it gives you a null z rotatetd in the facenormal direction:import c4d from c4d import utils def main() : if not op:return if not op.IsInstanceOf(c4d.Opolygon) :return print op op_mat = op.GetMg() p = op.GetPolygon(0) points = op.GetAllPoints() # Get global coords of points. p1, p2, p3 = points[p.a] * op_mat, points[p.b] * op_mat, points[p.c] * op_mat # Calc the plane normal from three of the points. vec_normal = (p2 - p1).Cross(p3 - p1).GetNormalized() print vec_normal newMatrix = c4d.Matrix() newMatrix.v3 = vec_normal #in Z_direction newMatrix.v1 = c4d.Vector(0,1,0).Cross(newMatrix.v3) #in X_direction newMatrix.v2 = newMatrix.v3.Cross(newMatrix.v1) #in Y_direction null = c4d.BaseObject(c4d.Onull) null.SetMg(newMatrix) doc.InsertObject(null) print newMatrix c4d.EventAdd() if __name__=='__main__': main()
Best wishes
Martin -
On 09/02/2015 at 11:26, xxxxxxxx wrote:
Thanks Martin, but what if I never have a plane?
I want to calculate the same 'normal' rotation from an actual object rotation.I'd rather not create a plane, transfer the matrix, calculate the normal, and then delete the plane.
That seems kind of hackish.Chris
-
On 09/02/2015 at 11:37, xxxxxxxx wrote:
Hi Chris,
I´m not quite sure if I understand your problem right.
What to you mean by 'normal' rotation?
The rotation of an object is given by three vectors.#the components of a c4d matrix (rotation in x,y,z and the offset)
matr = op.GetMg()
print matr.v1, matr.v2, matr.v3, matr.offif you want set an object(op2) to the same rotation as another object(op), you simply overwrite the
Matrix like:matr = op.GetMg()
op2.SetMg(matr)Hope this helps?
Martin -
On 09/02/2015 at 12:27, xxxxxxxx wrote:
I'm using this plane class to calculate distance and intersections with a plane:
https://gist.github.com/andreberg/894257The problem is, to initialize the class it wants a rotation. The only rotation format I've found that will make it work properly is a calculated 'normal' rotation like above. But, I'm not starting with a plane, I'm starting with a rotated object in my program, and calculating distance and intersection to a virtual plane aligned to the same rotation as the object.
I've tried this:
obj_rot_vec, w = c4d.utils.MatrixToRotAxis(obj_mat)
But the rotation returned is not the same as a calculated 'normal' rotation with my method above.
So to use this class, I've had to create a plane, set its rotation to the same as the object, calculate the rotation of the plane poly normal, and then give this value to the class to initialize it.I'm missing something.
Isn't there some way to get the rotation that the class wants from the rotated object directly.It isn't eulers.
It isn't the 3 rotation vectors in the matrix.For a polygon, it is the direction of the normal.
But I don't have a polygon, I have a rotated object.
It is a rotation without the 'heading' or 'w' value.
I thought...c4d.utils.MatrixToRotAxis
would return the same thing a calculating a plane poly normal.
But it doesn't.What am I missing?
-
On 09/02/2015 at 12:58, xxxxxxxx wrote:
I see.
it needs a normal and a position two simple vectors to initialize.
n is the normal of a plane and pos a point which is lying on the plane.def __init__(self, pos, n) : super(Plane, self).__init__() self.pos = pos self.n = n.GetNormalized() if DEBUG: print "self.pos = %r, self.n = %r" % (pos, n)
if you want to use the xy_Plane corresponding to the object and it´s rotation
just use the z Vector of the objects matrix as n, which is z_vec = op.GetMg().v3
and the offset as pos. offset = op.GetMg().offif you want to use the xz-Plane corresponding to the object and it´s rotation
just use the y Vector of the objects matrix as n, which is y_vec = op.GetMg().v2
and the offset as pos. offset = op.GetMg().offand so on....
Best wishes
Martin -
On 09/02/2015 at 14:13, xxxxxxxx wrote:
Martin,
Of course... if you just take one of the 3 matrix rotation vectors you are getting the equivalent of a plane without the rotation around the axis perpendicular to the plane.
Thanks, I new it was something simple like that.