# 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,

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

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.off

if 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/894257

The 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().off

if 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().off

and 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.