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