+ Reply to Thread
Results 1 to 7 of 7

Thread: Function for finding a point along curve that is a linear distance from start point

  1. #1

    Function for finding a point along curve that is a linear distance from start point

    I built* this function months ago and use it pretty frequently - for example, when packing things of various known sizes along a curve, or when translating a design to meatspace (where the subtleties of varying arc lengths along a curve are just unnecessary complications). There are probably better ways of writing this code, but I think it's useful enough that something like it should be included by default in rhino.python.

    Python Code:
      def LinearDistAlongCurve(pathCurve, startPt, distance, tolerance = 0.1):
          """
          Uses a binary search to find a point at a given linear distance
          along a curve.
          """
         
          tmin = rs.CurveClosestPoint(pathCurve, startPt)
          tmax = rs.CurveDomain(pathCurve)[1]
          t0 = tmin
          t1 = tmax
          endPt = rs.EvaluateCurve(pathCurve, tmax)
          maxDist = rs.Distance(startPt,endPt)
          if distance > maxDist: return
         
          while True:
              t = 0.5 * (t0 + t1)
              tempPt = rs.EvaluateCurve(pathCurve,t)
              tempDist = rs.Distance(startPt, tempPt)
              if abs(tempDist - distance) < tolerance: break
              if tempDist > distance: t1 = t
              else: t0 = t
             
          return tempPt


    Or maybe there's already a way to do this that I've missed?


    *Copied and modified the code from a nearly identical but functionally different tutorial example on binary searches
    Last edited by nhfoley; 09-23-2012 at 04:02 PM.

  2. #2
    | CurveArcLengthPoint(curve_id, length, from_start=True) | Returns the point on the curve that is a specified arc length
    | from the start of the curve.

    try this method. maybe this is what you are looking for.
    slightly i come, slightly i gone.

  3. #3
    Quote Originally Posted by stjackin View Post
    | CurveArcLengthPoint(curve_id, length, from_start=True) | Returns the point on the curve that is a specified arc length
    | from the start of the curve.

    try this method. maybe this is what you are looking for.
    Unfortunately, there are many instances in which arc length is mostly irrelevant - the code I presented finds points based on an absolute (linear) distance.

  4. #4
    I would check out the Intersection methods to get rid of the iteration part of your code.

    If you have a planar curve construct a circle around the startpoint of the curve. Then find the Intersection-Points of pathCurve and circle. You might have to convert from Circle to NurbsCurve:

    Code:
    events = Rhino.Geometry.Intersect.Intersection.CurveCurve(pathCurve, circle.ToNurbsCurve(), intersection_tolerance, overlap_tolerance)
    for e in events:
        print e.PointA

    For non-planar curves go with a sphere around the startpoint of the basecurve.

  5. #5
    Super Moderator Mitch's Avatar
    Join Date
    May 2010
    Location
    Switzerland
    Posts
    313
    Check out rs.DivideCurveEquidistant in the Rhinoscript syntax methods as well.

    DivideCurveEquidistant
    Divides a curve such that the linear distance between the points is equal.
    Unlike the DivideCurve and DivideCurveLength, which divides a curve based on arc length, or the distance along the curve between two points, this function divides a curve based on the linear distance between points.

    I use the circle/sphere methods fairly often as well, especially where the 'from' point is not the start point of the curve.
    --Mitch

  6. #6
    I had built a circle-based intersection version previously... it seemed slower, though that may have just been the the application I was using it for at the time. Sphere-based intersection methods definitely seem slower. Maybe some testing is in order...

  7. #7
    Super Moderator Mitch's Avatar
    Join Date
    May 2010
    Location
    Switzerland
    Posts
    313
    I just briefly tested your algorithm, rs.DivideCurveEquidistant, and a circle-curve intersection with rs.CurveCurveIntersection. They all seem to run about equally fast - as long as you exclude adding the time it takes to add the circle to the document in the third method. This takes a huge amount of time, it's like 100x slower if you include that. If you avoid this by using RhinoCommon methods so you don't have to add the circle to the document, the run time is much better but the first two methods are still better by a factor of about 2...

    --Mitch

+ Reply to Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts