Discrepancy with point positions of Circle Spline Primitive
-
Hi guys,
to distribute a set of points in a circular manner one can use the following code:
from typing import Optional import c4d import math doc: c4d.documents.BaseDocument # The active document op: Optional[c4d.BaseObject] # The active object, None if unselected def main() -> None: # Called when the plugin is selected by the user. Similar to CommandData.Execute. radius = 100.0 count = 8 angle: float = (2 * math.pi) / count points: list[c4d.Vector] = [ c4d.Vector(radius * math.cos(i * angle), radius * math.sin(i * angle), 0) for i in range(count) ] for i, p in enumerate(points): print(i, p) """ def state(): # Defines the state of the command in a menu. Similar to CommandData.GetState. return c4d.CMD_ENABLED """ if __name__ == '__main__': main()
Which results in points with the following positions:
0 Vector(100, 0, 0) 1 Vector(70.711, 70.711, 0) 2 Vector(0, 100, 0) 3 Vector(-70.711, 70.711, 0) 4 Vector(-100, 0, 0) 5 Vector(-70.711, -70.711, 0) 6 Vector(0, -100, 0) 7 Vector(70.711, -70.711, 0)
We can clearly see that for index 1 the position is
Vector(70.711, 70.711, 0)
So I wonder why this doesn't hold true for a Circle Spline Primitive with uniform intermediate points set to 1? There the position is
Vector(70.75, 70.75, 0)
.Is that a bug?
I have attached a scene file where one can see the difference between a Circle Spline Primitive and a N-Side Spline Primitive.
Cheers,
Sebastian -
Hello @HerrMay,
Thank you for reaching out to us. The answer is fairly simple: Because a circle spline is only an approximation for a circle. In a certain sense, the n-Side spline is more of a circle than the circle spline. There are only four control points in a circle spline and there are no cubic polynomials (i.e., the math which describes the spline from one control point to the next) which can exactly describe a circle segment.
On a side note:
- What you consider to be the true value is not really the true value either because Cinema 4D rounds the outputs of vectors in the UI and console.
- I would really discourage using sine and cosine to rotate a point. It is not only slow, but also hard to read. Unless one is after understanding trigonometry, the circle functions, one should not touch them (for rotating points).
import c4d # The point to rotate, the number of steps, and the angle per step. p: c4d.Vector = c4d.Vector(100, 0, 0) steps: int = 8 theta: float = c4d.utils.DegToRad(360./steps) # Compute a rotated point #q for each #step. for i in range(steps): q: c4d.Vector = c4d.utils.MatrixRotZ(theta * i) * p print (q)
Vector(100, 0, 0) Vector(70.711, -70.711, 0) Vector(0, -100, 0) Vector(-70.711, -70.711, 0) Vector(-100, 0, 0) Vector(-70.711, 70.711, 0) Vector(0, 100, 0) Vector(70.711, 70.711, 0)
You can find about this subject in the Matrix Manual.
Cheers,
Ferdinand - What you consider to be the true value is not really the true value either because Cinema 4D rounds the outputs of vectors in the UI and console.
-
Hi @ferdinand,
thanks for taking the time to clarify that
Okay, I see. So one can view this "behavoiur" as intended since it is the result of the math behind how the circle spline is calculated?
Still I wonder why the circle spline primitive with 1 intermediate point, i.e. with four control points doesn't appear like the n-side spline with 8 sides? Wouldn't it be "cleaner" that way?
Regading the true values - I am well aware that the repr of
c4d.Vector
rounds in the GUI. It was only that those values were quite off compared to the values of the points of the n-side spline. That's why my initial question arose.Interesting and good to know that rotating points via sine and cosine is slow and no good option. Thank you for that insight. May I ask why that is? I mean why is
c4d.utils.MatrixRotZ
better? What does that function do differently in terms of performance? In the end it has to do the math as well, does it not?Sorry for constantly asking all this stupid questions. It is only that I want to understand these things thoroughly.
Thanks for your time,
Sebastian