# Wrap helix around spline

On 08/04/2015 at 12:23, xxxxxxxx wrote:

I know I can use Spline Wrap to wrap a spline around another spline.

So, I want to wrap or align a helix around, for example, a circle.
At this moment I am doing this straight forward, just buy adding the helix point x,y coordinates to the spline point x,z coordinates:

``````        newPoints = []
for i,point in enumerate(splinePoints) :     #set position
#print i, point
newVector = c4d.Vector(point.x + helixPoints[i].x, point.y, point.z + helixPoints[i].z)
newPoints.append(matr*newVector)

newSpline = CreateSpline(null, newPoints)

``````

But as you can see, it is not taking "align" into account.
The sides are ok, but the top and bottom are too flat.

How can I solve this?

-Pim

On 09/04/2015 at 06:43, xxxxxxxx wrote:

Hi,
this problem does not seem to be an SDK related question, so I leave the actual solution to the forum community. Just want to mention, that there's a SplineHelp class, which might come in handy, when solving this problem.

On 09/04/2015 at 08:04, xxxxxxxx wrote:

Yes, I use the splinehelp class frequently.
But sometimes i wonder about the difference between the splinehelp and the normal spline.

-Pim

On 09/09/2015 at 17:12, xxxxxxxx wrote:

I'm also trying to find a solution to wrapping a helix around a spline, but am not getting the results I was expecting multiplying the normal or tangent to my point.  Here is my code:

``````#sh = c4d.utils.SplineHelp()
#spLen = sh.GetSplineLength()
def Helix(myLine, sh, spLen, stitchAmount) :
v = c4d.Vector
offSet = 0
ptIncrement = 0
a = 0
direction = [v(0, 1, 0), v(0, 0, 1), v(0, -1, 0), v(0, 0, -1)]
myHelix = c4d.SplineObject(64*stitchAmount,c4d.SPLINETYPE_BEZIER)
seg = (spLen/stitchAmount)/64
xx = 0
for i in range(64*stitchAmount) :
n = sh.GetNormal(offSet)
pos = sh.GetPosition(offSet)
myHelix.SetPoint( xx, v(pos.x + 40*n.x*direction[a].x, pos.y + 40*n.y*direction[a].y, pos.z + 40*n.z*direction[a].z))
offSet = offSet + seg/spLen
xx += 1
a += 1
if a == 4:
a = 0

myHelix[c4d.SPLINEOBJECT_TYPE] = 1
myHelix[c4d.SPLINEOBJECT_INTERPOLATION] = 2
myHelix[c4d.SPLINEOBJECT_SUB] = 4
myHelix.Message(c4d.MSG_UPDATE)
``````

Did you find a solution Pim?

On 10/09/2015 at 01:38, xxxxxxxx wrote:

Hello,

I just want to add that there may be some problems with the SplineHelp class, see "c4d.utils.splinehelp".

best wishes,
Sebastian

On 10/09/2015 at 14:16, xxxxxxxx wrote:

Thanks for the tip Sebastian.  I haven't come up with a working solution yet even after trying the cross normal and other combinations, but when I do, I'll post my results.

On 11/09/2015 at 00:08, xxxxxxxx wrote:

Hi visualride,

No, I did not find a solution yet.
If you find one, I would be very interested.

-Pim

On 11/09/2015 at 09:11, xxxxxxxx wrote:

It's good to hear that I'm not the only one not figuring this out Pim.  You know when you have looked for something for hours and then start to look even in the most un-logical locations, such as for a missing sock in the refrigerator?  That's where I'm at with combinations of changing point directions combined with normal/tangent/crossnormal, and recently, trying various up vector directions in the SplineHelp.InitSpline.  I get close results with the helix spiraling around my winding spline great in some directions, but then flattening out on some axis in others.  Seems to be a problem getting the correct normals off the spline that I'm using.  I'll try to sneak in another hour of trial and error Python programming from my usual day of C4D work.  Programming is never appreciated as billable work by my employers probably because it can't be billed on a current job.  Hence the constant "sneaking" in of time to program. But it's fun!

On 11/09/2015 at 16:55, xxxxxxxx wrote:

Ok, I've finally got it.  It may not be beautiful, and of course the real programmers may wince at some of my inefficiencies, but it works.  Here it is:

``````def Helix(myLine, stitchAmount) :
v = c4d.Vector
sh = c4d.utils.SplineHelp()
sh.InitSpline(myLine,c4d.Vector( 0, 0, 0 ),None,True,True,True,False)
spLen = sh.GetSplineLength()
offSet = 0
a = 0
myHelix = c4d.SplineObject(64*stitchAmount,c4d.SPLINETYPE_BEZIER)
myHelix[c4d.SPLINEOBJECT_TYPE] = 1
myHelix[c4d.SPLINEOBJECT_INTERPOLATION] = 2
myHelix[c4d.SPLINEOBJECT_SUB] = 4
seg = (spLen/stitchAmount)/64

for i in range(64*stitchAmount) :
n = sh.GetNormal(offSet)
t = sh.GetTangent(offSet)
pos = sh.GetPosition(offSet)

if a == 0:
myHelix.SetPoint( i, v(pos.x + 40*n.z, pos.y, pos.z + 40*n.x*-1)) # Inward spline
if a == 1:
myHelix.SetPoint( i, v(pos.x, pos.y + 40*t.y, pos.z)) # Lower spline
if a == 2:
myHelix.SetPoint( i, v(pos.x + 40*n.z*-1, pos.y, pos.z + 40*n.x)) # Outward spline
if a == 3:
myHelix.SetPoint( i, v(pos.x, pos.y + 40*t.y*-1, pos.z)) # Upper spline

offSet = offSet + seg/spLen
a += 1
if a == 4:
a = 0

myHelix.Message(c4d.MSG_UPDATE)
sh.FreeSpline()

return myHelix
``````

On 12/09/2015 at 08:06, xxxxxxxx wrote:

Indeed, great work!
Thanks for sharing.

And I agree with you, it is sometimes frustrating, but most of the time great fun!

-Pim

On 29/09/2015 at 07:46, xxxxxxxx wrote:

Now I realize why this thread hasn't been closed.  Perhaps the moderators realize that they would just be spoiling our fun solving our puzzles if they offered fixes to obvious mistakes?  I dunno, but this has been a fun puzzle.  Of course completed I see how simple it is.  After finally getting around to using this function in a plugin outside of my simple flat test scene, I found out that it didn't work correctly, with the dreaded flattening out of my helix at some locations.  Here is my corrected code, which has at least worked on a couple other test splines bending in all directions:

``````]
# seg = (spLen/stitchAmount)/(16*wrapNum)
# offSet = 0
# wrapNum is the number of times the helix will wrap around my spline
# stitchAmount is the number of spline "stitches" to make
# spLen = sh.GetSplineLength()
for i in range((16*wrapNum)*stitchAmount) :
n = sh.GetNormal(offSet)
t = sh.GetTangent(offSet)
cn = sh.GetCrossNormal(offSet)
pos = sh.GetPosition(offSet)

if a == 0:
if a == 1:
if a == 2: