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.


Log in to reply