Rotating Spline Points



  • Hello!

    Does anyone know how to rotate all of the points of a spline in Python?



  • You multiply all the points with the desired transformation matrix.
    For the tangents, you need to bring them into the transformation center before multiplying, and afterwards you bring them back to the point (note: the new position of the point).

    In short:

    import c4d
    from c4d import gui
    
    def main():
        pointCount = op.GetPointCount()
        mat = c4d.utils.MatrixRotX(c4d.utils.DegToRad(45.0))
        for i in range(0,pointCount):
            point = op.GetPoint(i) #Point Vector
            tangent = op.GetTangent(i)
            vl = tangent['vl'] #Left Tangent Vector
            vr = tangent['vr'] #Right Tangent Vector
            print point
            
            vl = (vl - point) * mat
            vr = (vr - point) * mat
            point = point * mat
            vl = vl + point
            vr = vr + point
            op.SetTangent(i, vl, vr)
            op.SetPoint(i,point)
        op.Message (c4d.MSG_UPDATE)
        c4d.EventAdd()
    
    if __name__=='__main__':
        main()
    

    (I removed all tests for object type etc so call this only on a proper bezier curve!)

    Here, I define the transformation matrix as rotation around X by 45 degrees.
    Then I go through the points (your code) and do the transformation for the point and its tangents as mentioned.

    The challenge may be to assemble the transformation matrix if you want a different rotation axis than X, Y, or Z... but you didn't mention what axis, so I stay with X 😊


    Learn more about Python on C4D:
    https://www.patreon.com/cairyn
    (Matrix transformations haven't been handled yet but will follow soon...)



  • There is a long chapter on matrix operations in the docs:
    https://developers.maxon.net/docs/Cinema4DPythonSDK/html/manuals/data_algorithms/classic_api/matrix.html?highlight=rotation
    Build a matrix (for the correct reference system, center, and rotation axis) and multiply it with the points in question.

    Note: If you are using Bezier splines, there are tangents. These also need to be transformed, but keep in mind that tangents are vectors starting at the point, not at the object center.



  • Note that c4d.utils contains the most matrix building functions:
    c4d.utils.MatrixRotX(w)
    c4d.utils.MatrixRotY(w)
    c4d.utils.MatrixRotZ(w)
    c4d.utils.MatrixToRotAxis(m)
    c4d.utils.RotAxisToMatrix(v, w)

    etc.

    https://developers.maxon.net/docs/Cinema4DPythonSDK/html/modules/c4d.utils/index.html



  • Hi @Cairyn,
    Thank you very much for the reply and for pointing me to the utils. I am familiar with the Matrix documentation, however, I'm not sure how to multiply the points & tangents of my Spline by the target Matrix and apply the result. I know how to get the vectors of the Point, Left Tangent, & Right Tangent, but what comes next?

            pointCount = obj.GetPointCount()
            interpolation = obj.GetInterpolationType()
    
            if interpolation == c4d.SPLINETYPE_BEZIER:
                for i in range(0,pointCount):
                    point = obj.GetPoint(i) #Point Vector
                    tangent = obj.GetTangent(i)
                    vl = tangent['vl'] #Left Tangent Vector
                    vr = tangent['vr'] #Right Tangent Vector
    

    Thank you.



  • You multiply all the points with the desired transformation matrix.
    For the tangents, you need to bring them into the transformation center before multiplying, and afterwards you bring them back to the point (note: the new position of the point).

    In short:

    import c4d
    from c4d import gui
    
    def main():
        pointCount = op.GetPointCount()
        mat = c4d.utils.MatrixRotX(c4d.utils.DegToRad(45.0))
        for i in range(0,pointCount):
            point = op.GetPoint(i) #Point Vector
            tangent = op.GetTangent(i)
            vl = tangent['vl'] #Left Tangent Vector
            vr = tangent['vr'] #Right Tangent Vector
            print point
            
            vl = (vl - point) * mat
            vr = (vr - point) * mat
            point = point * mat
            vl = vl + point
            vr = vr + point
            op.SetTangent(i, vl, vr)
            op.SetPoint(i,point)
        op.Message (c4d.MSG_UPDATE)
        c4d.EventAdd()
    
    if __name__=='__main__':
        main()
    

    (I removed all tests for object type etc so call this only on a proper bezier curve!)

    Here, I define the transformation matrix as rotation around X by 45 degrees.
    Then I go through the points (your code) and do the transformation for the point and its tangents as mentioned.

    The challenge may be to assemble the transformation matrix if you want a different rotation axis than X, Y, or Z... but you didn't mention what axis, so I stay with X 😊


    Learn more about Python on C4D:
    https://www.patreon.com/cairyn
    (Matrix transformations haven't been handled yet but will follow soon...)



  • @Cairyn
    It works! 😄 This was VERY helpful, thank you!!!



  • You don't have to compensate the position of the tangent, if you use

    c4d.Matrix.MulV(self, v)
    

    to transform the direction vector.

    import c4d
    from c4d import gui
    
    def main():
        pointCount = op.GetPointCount()
        mat = c4d.utils.MatrixRotX(c4d.utils.DegToRad(45.0))
        for i in range(0,pointCount):
            
            point = op.GetPoint(i) #Point Vector
            point = point * mat
                   
            tangent = op.GetTangent(i)
            vl = tangent['vl'] #Left Tangent Vector
            vr = tangent['vr'] #Right Tangent Vector
            
            vl = mat.MulV(vl)
            vr = mat.MulV(vr)
         
            op.SetPoint(i,point)
            op.SetTangent(i, vl, vr)        
            
        op.Message (c4d.MSG_UPDATE)
        c4d.EventAdd()
    
    if __name__=='__main__':
        main()
    


  • @nophoto Very nice! Thank you 🏆


Log in to reply