Solved Spline notRealOffset to RealOffset


I have a unclosed spline with 5 points and an offset from 0 to 1 where 0.0 is on point 0, 0.25 is on point 1, 0.5 on point 2 and so on. I think this is meant as not realoffset. The distances between the points are different. But for example the sweep growth works with real offsets, I guess. How can I convert an notRealOffset into a RealOffset? I tried to use SplineHelp(), but dont get I to work rigth now.

Thx for any hints

Hi Rownn, thanks for reaching us.

With regard to your question, as pointed out in our documentation you can move back and forth from percentage to unit offset by using:

A few observations now:

  • the curve parameter or "offset" as called in Cinema 4D, always ranges (on a specific segment) from 0 to 1.
  • depending on the curve parametrization, actually how "intermediate points" are generated the offset can be equal to the curve percentage: this happens only if the Uniform mode as been set.

Let's see two simple cases:

  • given a certain curve with Intermediate Points generation set to Natural and an "arbitrary" distance of 400 units we obtain:
    splineLength: 849.075096635
    customLength: 400
    lengthRatio (customLength / splineLength): 0.471100850308
    GetOffsetFromReal(lengthRatio,0): 0.452809444459
    GetOffsetFromUnit(customLength,0): 0.452809444459
  • given the same curve with Intermediate Points generation set to Uniform and an "arbitrary" distance of 400 units we obtain:
    splineLength: 845.774079501
    customLength: 400
    lengthRatio (customLength / splineLength): 0.472939535148
    GetOffsetFromReal(lengthRatio,0): 0.472783546885
    GetOffsetFromUnit(customLength,0): 0.47278354688

In the second case the ratio expressed by the arbitrary length and the overall curve length matches the offset which is completely correct considering the Uniform option

Let me know if it helps to address your question or if there are further points to better discuss.


EDIT: I've fixed the naming convention the text snippets to make it more readable

Hi Riccardo,
thanks for your detailed reply. I think I will need some more concentration to get it clear. Is lengthRatio=custom/spline length ratio and customLength=custom lenght=400?

I´ll be back with more time.

Thx and greetings

@rownn: I've fixed the naming convention in the previous post to make it more clear.



I´ve fixed it in another way. It isn´t very interesting how, because it is pretty case specific.
I wasn´t able to use the informations above to get it to work, because I wasnt able to get the "customlength" by offset.

But to clarify what I wandet to do here a screenshot:

But thx again

Hi rownn, thanks for following up.

Can you elaborate more on I wasnt able to get the "customlength" by offset.?
Actually looking at your screenshot and assuming that the red-labelled refers to what you actually consider "wrong" and the green-labelled to the right, I think that the red-labelled is indeed correct since it actually lies in the middle of spline considering that the start point is the top/right vertex.

At the same time, the green-labelled point is the one that you can obtain when passing 0.5 to SplineHelp::GetPosition() which is the 50% of the spline parametrization not of the spline length.

Assuming a linear rectangle is used as shown above the code below shows the behavior I describe:

def main():
    sh = c4d.utils.SplineHelp()
    splineLength =  sh.GetSplineLength()
    halfLength = splineLength / 2
    midPointOffsetIncorrect = halfLength / splineLength
    midPointOffsetFromReal = sh.GetOffsetFromReal(midPointOffsetIncorrect,0)
    midPointOffsetFromUnit = sh.GetOffsetFromUnit(halfLength,0)
    mtx = c4d.Matrix() 
    midpointRed = sh.GetPosition(midPointOffsetFromUnit) # which in this case is the same of offsetFromReal
    midNullRed = c4d.BaseObject(c4d.Onull)
    midNullRed[c4d.ID_BASEOBJECT_USECOLOR] = 2
    midNullRed[c4d.ID_BASEOBJECT_COLOR] = c4d.Vector(1,0,0)
    midNullRed[c4d.ID_BASELIST_NAME] = "MidRed" = midpointRed

    midpointGreen = sh.GetPosition(midPointOffsetIncorrect)
    midNullGreen = c4d.BaseObject(c4d.Onull)
    midNullGreen[c4d.ID_BASEOBJECT_USECOLOR] = 2
    midNullGreen[c4d.ID_BASEOBJECT_COLOR] = c4d.Vector(0,1,0)
    midNullGreen[c4d.ID_BASELIST_NAME] = "MidGreen" = midpointGreen

Best, Riccardo