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.
    In my case I want to have more control and learn more about splines and transformations.

    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
    # rad is the radius of the helix
    # 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:
                    myHelix.SetPoint( i, v(pos.x - rad*cn.x, pos.y - rad*cn.y, pos.z - rad*cn.z)) # Inward spline
                if a == 1:
                    myHelix.SetPoint( i, v(pos.x + rad*t.x, pos.y + rad*t.y, pos.z + rad*t.z)) # Lower spline
                if a == 2:
                    myHelix.SetPoint( i, v(pos.x + rad*cn.x, pos.y + rad*cn.y, pos.z + rad*cn.z)) # Outward spline
                if a == 3:
                    myHelix.SetPoint( i, v(pos.x - rad*t.x, pos.y - rad*t.y, pos.z - rad*t.z)) # Upper spline
                offSet = offSet + seg/spLen
                a += 1
                a %= 4
    


  • On 29/09/2015 at 07:54, xxxxxxxx wrote:

    Yeah, we would never want to spoil the fun of our community 😉
    Usually we leave threads open for a few more days (especially on open discussions like this) to see, if there are any follow up questions. And to be honest I lacked the time to check for "closeable" threads during the last weeks.
    Anyway, good to see you have fun and come up with optimized solutions. Please forgive my laziness.


Log in to reply