how to create an offset for a spline



  • On 24/04/2013 at 11:56, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   r14 
    Platform:   Windows  ;   
    Language(s) :     C++  ;

    ---------
    Hi,

    can someone point me into the direction how i can create a copy of a spline with a certain offset? i have no real clue at the moment, how i can achive this practically.

    thanks for all input.

    cheers,
    Ello



  • On 24/04/2013 at 13:34, xxxxxxxx wrote:

    what do you mean by offset ? basically it is just:

    newpos = oldpos + (normal % tangent) * offsetdistance

    i am not so sure about the tagents for a bezier spline, i think you have somewhat to scale 
    them with the offset, but i am not sure how. generally speaking the spline help class might
    be helpfull for you.



  • On 25/04/2013 at 11:50, xxxxxxxx wrote:

    thank you for the input.



  • On 11/05/2013 at 03:40, xxxxxxxx wrote:

    Hi, i finally got it working to a certain degree. anyhow, if you look at the image you see that it looks a bit strange in the corners. how can i create a parallel offset?

    Vector *points = static_cast<SplineObject*>(spline)->GetPointW(); 
    SplineObject *newSpline = (SplineObject* )spline->GetClone(COPYFLAGS_0,NULL);
    Vector *newPoints = newSpline ->GetPointW();
    LONG pointCount = spline->GetPointCount();
    for(LONG i=1; i<pointCount-1; i++)
    {
       Vector dir = VectorToHPB(points[i-1] - points[i+1]);
       Matrix m = HPBToMatrix(dir, ROTATIONORDER_DEFAULT);
       newPoints[i] = points[i] + offset * m;
    }
    

    thanks for your help.

    cheers,
    Ello



  • On 11/05/2013 at 08:57, xxxxxxxx wrote:

    Take a look at the values you are giving "i" in your "for" loop.
    You are not allowing the loop to use the end points in the points array. And that's what is creating that pinched shape.

    If you want to make a mirrored copy of your spline.
    Here's an example that shows how to mirror both the points and the tangents along the X-Axis:

        BaseObject *spline = doc->SearchObject("Arc");                    //Find the arc spline in the OM (Not a primitive!!)  
      SplineObject *sp = ToSpline(spline);                              //Cast it to a spline object type so we can work on it if desired  
      
      SplineObject *newSpline = (SplineObject* )spline->GetClone(COPYFLAGS_0,NULL); //Clone the arc spline object  
      doc->InsertObject(newSpline,NULL,NULL);                                      //Add it to the OM  
      Vector *newPoints = newSpline->GetPointW();                                  //Get it's array of points  
      Tangent *tangents = newSpline->GetTangentW();                                //Get it's array of tangents  
      
      LONG pointCount = newSpline->GetPointCount();  
      for(LONG i=0; i<pointCount; i++)  
      {  
          newPoints[i].x = newPoints[i].x * -1;                //Mirror the points along the X-axis  
          tangents[i].vl.x = tangents[i].vl.x * -1;            //Mirror the left tangents along the X-axis  
          tangents[i].vr.x = tangents[i].vr.x * -1;            //Mirror the right tangents along the X-axis  
      }
    

    -ScottA



  • On 11/05/2013 at 11:51, xxxxxxxx wrote:

    Hi Scott, I was referring to the edges on the left side in the image. 
    the first and last point are not changed as I dont need them, so this is intentionally. I just need the inner points of the spline. the offset is applied mathematically correct, but the problem is that the generated spline isnt parallel.



  • On 11/05/2013 at 12:16, xxxxxxxx wrote:

    The results you show in the image are correct (for the way you are implementing your 'offset' algorithm).  You are using something like a vertex normal distance transition.  The distance from the corner points is the same as the others (but it is at a 45d angle - following the normal at those two points).  You will not get the shape retention (parallel movement) using that algorithm.

    How about something like this:

    Vector normal;  
    for(LONG i=1; i<pointCount-1; i++)  
    {  
      normal =    !((points[i-1]-points[i])%(points[i+1]-points[i]));  
      newPoints[i] = points[i] + (offset * normal);  
    }
    

    If that doesn't work, you may need to look into Convolution using Minkowski Sums:

    http://dev.gentoo.org/~dberkholz/tutorials/cairo/siggraph.pdf

    (3.1 and 3.2)

    and

    http://www.cgal.org/Manual/latest/doc_html/cgal_manual/Minkowski_sum_2/Chapter_main.html#Section_24.3



  • On 11/05/2013 at 12:59, xxxxxxxx wrote:

    Thank you Robert.. the normal solution you posted doesn't give the desired results either. i remember there once was a free plugin creating offsetted spline outlines. but i dont know who did this to ask if he shares some info about how it was accomplished. atm, i dont understand the documents you linked. maybe what i am trying to do is a bit to heavy stuff for me


Log in to reply