Rotating Spline Points
-
Hello!
Does anyone know how to rotate all of the points of a spline in Python?
-
There is a long chapter on matrix operations in the docs:
https://developers.maxon.net/docs/py/2023_2/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/py/2023_2/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