# Spline Tangents

On 05/12/2013 at 12:36, xxxxxxxx wrote:

Hello all,

I'm working with Python trying to make some code where it takes a spline, and I can return a new spline that looks similar but with a number of points that the user inputs.

``````

for y in range(len(points)) :

x = 1/len(points)*y
point = spline.GetSplinePoint(x)
tangent =spline.GetSplineTangent(x)
``````

So I've been testing it on a circle spline.

Original circle: ``````

# The circle tangents are:

tangent1a = c4d.Vector(0,-83,0)
tangent1b = c4d.Vector(0,83,0)
tangent2a = c4d.Vector(83,0,0)
tangent2b = c4d.Vector(-83,0,0)
tangent3a = c4d.Vector(0,83,0)
tangent3b = c4d.Vector(0,-83,0)
tangent4a = c4d.Vector(-83,0,0)
tangent4b = c4d.Vector(83,0,0)
``````

My spline in the center: So my spline is in the middle, I have it returning the spline with four points, so if it was working correcting they should look the same.  GetSplineTangent() seems to be returning the directions for the handles, but not the amount.

``````

# My tangents are:

tangent1a = c4d.Vector(0,-1,0)
tangent1b = c4d.Vector(0,1,0)
tangent2a = c4d.Vector(1,0,0)
tangent2b = c4d.Vector(-1,0,0)
tangent3a = c4d.Vector(0,1,0)
tangent3b = c4d.Vector(0,-1,0)
tangent4a = c4d.Vector(-1,0,0)
tangent4b = c4d.Vector(1,0,0)
``````

I multiplied the tangent that was returned so I could show that they're the same direction. ``````

# The my new tangents are:

tangent1a = c4d.Vector(0,-20,0)
tangent1b = c4d.Vector(0,20,0)
tangent2a = c4d.Vector(20,0,0)
tangent2b = c4d.Vector(-20,0,0)
tangent3a = c4d.Vector(0,20,0)
tangent3b = c4d.Vector(0,-20,0)
tangent4a = c4d.Vector(-20,0,0)
tangent4b = c4d.Vector(20,0,0)
``````

So my question is how would I find the amount I need to multiple the tangent to get the correct one?  It seems proportional to the distance between that point and the neighboring points, but I can't figure out the specifics.  In this case I would need to multiple by 83 and then it would be correct, but I'm not sure how to dynamically figure that out.

Sorry for the long post,
Dan

On 05/12/2013 at 17:56, xxxxxxxx wrote:

Originally posted by xxxxxxxx

``````
for y in range(len(points)) :
x = 1/len(points)*y
point = spline.GetSplinePoint(x)
tangent =spline.GetSplineTangent(x)
``````

Hi,

you have to use SplineObject.GetTangent(). SplineObject.GetSplineTangent() is for
retrieving a tangent at a given offset on the quadratic spline equation (which is
normalized, as there are no length informations). Those tangents are not the same
as control point tangents. You have to calculate the actual control point tangent
yourself out of the neighboring control point tangents and the offset between those
two control points.

Happy rendering,
Ferdinand

On 12/12/2013 at 14:13, xxxxxxxx wrote:

Thanks Ferdinand,  I've been busy with a bunch of other Cinema stuff so I haven't been able to spend a ton on time on this yet.    I think I understand what you mean, but I'm having trouble finding the neighboring control points.  If I use this:

``````

for y in range(len(points)) :

x = 1/len(points)*y

``````

So x is just a percentage down the spline, how would I find out which two actual points are closest?   Since points aren't going to be evenly divided and the spline could crisscross itself no type of distance comparison could work.

Thanks,
Dan

On 13/12/2013 at 14:30, xxxxxxxx wrote:

You can convert a percentage offset into a natural offset with splinehelp.GetOffsetFromReal()
(at least I think that is the correct method there are two of them and I always do mix them up,
as they are awkwardly named for my taste). However if it is the correct method name I have given
you the percentage offset is the offset along your non interpolated spline. If you want to place
a control point between CPn and CPn+1 than your percentage offset is :

offset = |CP1 - CP0| + ... + |CPn-CPn-1| + |CPn+1-CPn| / 2

With |A-B| i mean the length of that vector. I hope this makes sense for you, I am a bit sleepy
right now ;)

Happy rendering,
Ferdinand

On 17/12/2013 at 16:31, xxxxxxxx wrote:

Hi Ferdinand,

Thanks for continuing to help me.  I think I'm starting to follow, but I'm still slightly confused.  The other function you were talking about was GetOffsetFromUnit() right?  I understand how that one works, I pass an offset and that returns the percentage down the spline that distance is.

But GetOffsetFromReal() doesn't seem to be working the way I would think it would.  I have a standard circle spline and I get this from it:

``````
print "SPLINE LENGTH:", splinehelp.GetSplineLength()  #returns 1256.72

print  "REAL:", splinehelp.GetOffsetFromReal(.5) #returns .5
``````

Shouldn't GetOffsetFromReal()  be returning something around 623, which would be the halfway point?

Thanks again!
Dan

On 25/12/2013 at 06:37, xxxxxxxx wrote:

Hi,

first of all happy holidays. I have been a bit busy, so I wasn't able to answer earlier. I think
there is a major misunderstanding of yours about spline space. Offsets are always >= 0.0
and <=1.0.

Here is a quick image, don't take the numbers for real I just did estimate them. S1 is an
interpolated spline and S2 its linear repr. If you want to subdivide a spline you take an offset
on the linear spline and project it onto the interpolated. what is a bit unclear in the image is,
that c4d calls 0.25 the percentage offset while 0.33 is the real offset. Here is also a small c4d file showing the concept as a little python tag (there is a float slider
on the python tag to set the offset).