Forgot password?

Create an account!

Forum

« back

RhinoScript – Rebuild polyline with tolerances?

Messages

Please log in to write a message.

  • 8. ledisnomad (May 24, 2011 18.04):

    OK, what about this approach (in pseudo-code):

    arrCurveKnots = Rhino.GetCurveKnots(strCrv)

    arrCrvSegments = Rhino.CurveDivide(strCrv, arrCurveKnots)

    Dim i : i = 0
    For Each strCrvSegment In arrCrvSegments

        ReDim Preserve arrNewControlPoints(i) = 'add control point at start of curve segment
        ReDim Preserve arrNewControlPoints(i+1) = 'add control point at midpoint of curve segment

        i = i+3
    Next

    ReDim Preserve arrNewControlPoints(i) = 'add control point at end of strCrv

    test_curve = Rhino.AddCurve(arrNewControlPoints)

    While dlbDeviationMax > MAX_DEVIATION

        For every segment (three points) along test_curve
            'test deviation at midpoints of test_curve to strCrv
            'If deviation > MAX_DEVIATION Then add a control point on strCrv closest
            'to midpoint of test_curve.
        Next
       
        'make a new test_curve and try again

    Next

    I think it starts to get at a new way to approach the original curve but with fewer points. The user is only responsible for adding the distance s/he wants the new curve to deviate from the original.

  • 7. ledisnomad (May 23, 2011 21.57):

    Hmm, interesting approach. I like that logic. With your description, Hanno, I'm starting to understand what Johannes was suggesting. I'm thinking that a recursive algorithm might work better than what I have. Then instead of only comparing adjacent points, I could compare results of one iteration to the next. I think this will be a nice project, more advanced than the down-and-dirty tools I usually write. Let me see what I can come up with. Thanks for the brainstorming help Hanno and Johannes.

  • 6. ledisnomad (May 23, 2011 21.18):

    OK, so here's the first version that I think works reasonably well. I'd like it to take into account overall curvature now, but I think this is a good start. I'll post it, too, but keep working on a better version.

    Option Explicit
    'Script written by Damon Sidel
    'Script copyrighted by Damon Sidel
    'Script version Sunday, May 23, 2011 3:20 PM

    Call RebuildPolylineTolerances()
    Sub RebuildPolylineTolerances()
           
            Dim MAX_ANGLE, MAX_DIST

            Dim strPolyline : strPolyline = Rhino.GetObject("Select the polyline to be rebuilt",4)
            If IsNull(strPolyline) Then Exit Sub
           
            Dim intCurvePointCount : intCurvePointCount = Rhino.CurvePointCount(strPolyline)
           
            MAX_ANGLE = Rhino.GetReal("What maximum angle do you want?",20)
            If IsNull(MAX_ANGLE) Then Exit Sub
           
            MAX_DIST = Rhino.GetReal("What maximum distantce do you want?",10)
            If IsNull(MAX_DIST) Then Exit Sub
           
            Dim arrCurvePoints : arrCurvePoints = Rhino.CurvePoints(strPolyline)
           
            Dim i, j, arrPrev, arrCurr, arrNext, dblAngle, dblDist
            ReDim arrNewCurvePoints(0) : arrNewCurvePoints(0) = arrCurvePoints(0)
            j=1
            For i=0 To intCurvePointCount-3
                   
                    arrPrev = arrNewCurvePoints(j-1)
                    arrCurr = arrCurvePoints(i+1)
                    arrNext = arrCurvePoints(i+2)
                    dblAngle = Rhino.Angle2(Array(arrCurr,arrPrev),Array(arrCurr,arrNext))
                    dblDist = Rhino.Distance(arrCurr, arrPrev)
                                   
                    Call Rhino.Print(CStr(180-dblAngle(0)))

                    If (dblDist < MAX_DIST) And (180.0-dblAngle(0) < MAX_ANGLE) Then
                            'Don't include the point and leave j as-is
                    Else
                            ReDim Preserve arrNewCurvePoints(j)
                            arrNewCurvePoints(j) = arrCurr
                            j = j+1
                    End If
                   
            Next
           
            ReDim Preserve arrNewCurvePoints(j)
            arrNewCurvePoints(j) = arrCurvePoints(intCurvePointCount-1)
           
            Call Rhino.AddCurve(arrNewCurvePoints,1)
            'Call Rhino.DeleteObject(strPolyline)
           
    End Sub
  • 5. Hanno (May 23, 2011 21.00):

    Hi,

    Maybe use a different approach: Don't ask the user about a minimum angle he wants in his result but about a number of control points to throw out.
    On that basis you can start to think about an algorithm that throws out the least relevant points (here the angle approach would be a good start).

    Once this works, you could try to produce an algorithm that not only throws out points but tries to find different set of CVs, hopefully optimizing results, like Johannes was suggesting.

    Hanno

  • 4. ledisnomad (May 23, 2011 15.33):

    True, the rebuild functions have a number of options, but result in a curve of degree 2 or 3. I'm starting with a curve of degree 1 and need to end with a curve of degree 1. Maybe I'm missing something, but I don't think any of the rebuild functions will simplify a curve and keep it a degree 1 curve.

  • 3. Johannes (May 23, 2011 08.18):

    what about to move the points? you just take the points out of the new polyline. take a look on the rebuild functions. you get less points but on another position.

  • 2. ledisnomad (May 23, 2011 02.54):

    So here is my first attempt at a rebuild polyline with tolerances for angle. On the one hand it works, but it may be too simplistic. My concern is that if there is a series of control points that one after the other are close to straight, but that gradually curve, my script will straighten the whole thing out, not just simplify it. Any thoughts?

    Option Explicit
    'Script written by Damon Sidel
    'Script copyrighted by Damon Sidel
    'Script version Sunday, May 22, 2011 7:23:09 PM

    Call RebuildPolylineTolerances()
    Sub RebuildPolylineTolerances()

            Dim strPolyline : strPolyline = Rhino.GetObject("Select the polyline to be rebuilt",4)
            If IsNull(strPolyline) Then Exit Sub
           
            Dim intPolyline : intPolyline = Rhino.CurvePointCount(strPolyline)
           
            Dim dblTolerance : dblTolerance = Rhino.GetReal("What angle tolerance do you want?",20)
            If IsNull(dblTolerance) Then Exit Sub
           
            Dim arrCurvePoints : arrCurvePoints = Rhino.CurvePoints(strPolyline)
           
            Dim i, j, p1, p2, p3, dblAngle
            ReDim arrNewCurvePoints(0) : arrNewCurvePoints(0) = arrCurvePoints(0)
            j=1
            For i=0 To intPolyline-3
                   
                    p1 = arrCurvePoints(i)
                    p2 = arrCurvePoints(i+1)
                    p3 = arrCurvePoints(i+2)
                    dblAngle = Rhino.Angle2(Array(p2,p1),Array(p2,p3))
                                   
                    Call Rhino.Print(CStr(180-dblAngle(0)))
                    If 180.0-dblAngle(0) > dblTolerance Then
                            ReDim Preserve arrNewCurvePoints(j)
                            arrNewCurvePoints(j) = p2
                            j = j+1
                    End If
                   
            Next
           
            ReDim Preserve arrNewCurvePoints(j)
            arrNewCurvePoints(j) = arrCurvePoints(intPolyline-1)
           
            Call Rhino.AddCurve(arrNewCurvePoints,1)
            Call Rhino.DeleteObject(strPolyline)
           
    End Sub
  • 1. ledisnomad (May 21, 2011 21.14):

    I'd like to write a script that rebuilds a polyline taking into account angle tolerances. For example, a curve that has a sharp bend at one end and then is rather straight should have quite a few control points at the sharp bend and only a few along the straight. I haven't started thinking this one through, yet, and would appreciate hearing different approaches people might take.

    Here's my first idea in pseudo-code:

    While there are still some angles under the tolerance
      For i=0 To UBound(crvControlPts)-2

        a = angle made from crv control points i, i+1, i+2
     
        If a < tolerance angle Then
          delete i+1
        EndIf

      Next
    Next

    Remake curve using remaining control points

    As you can see, there's a lot to figure out, including if this is a good approach. What do you think?

Recommend

Why are these buttons gray?