Search code examples
objective-cmathgeometrycalculus

Uniform distance between points


How could I, having a path defined by several points that are not in a uniform distance from each other, redefine along the same path the same number of points but with a uniform distance. I'm trying to do this in Objective-C with NSArrays of CGPoints but so far I haven't had any luck with this. Thank you for any help.

EDIT

I was wondering if it would help to reduce the number of points, like when detecting if 3 points are collinear we could remove the middle one, but I'm not sure that would help.

EDIT

Illustrating: Reds are the original points, blues the post processed points:

alt text

The new path defined by the blue dots does not correspond to the original one.


Solution

  • I think the problem is simple and easily solvable actually :)

    The basic idea is:

    • First check if the distance between your current point (P) and the end point of the line segment you are on is >= the distance between P and the next point (Q).

    • If it is, great, we use some simple trigonometry to figure it out.

    • Else, we move to the adjacent line segment (in your ordering) and deduct the distance between P and the endpoint of the line segment you are on and continue the process.

    Pseudocode:

    Defined previously

    struct LineSegment
    {
      Point start,end;
      int ID;
      double len; // len = EuclideanDistance(start,end);
      LineSegment *next_segment;
      double theta; // theta = atan2(slope_of_line_segment);
    }
    
    Function [LineSegment nextseg] = FindNextLineSegment(LineSegment lineseg)
    Input: LineSegment object of the current line segment
    Output: LineSegment object of the adjacent line segment in your ordering. 
    nextseg.ID = -1 if there are no more segments
    

    Function: Find the next point along your path

    Function [Point Q, LineSegment Z] = FindNextPt(Point P, LineSegment lineseg, int dist): 
    Input: The current point P, the distance between this point and the next, and the LineSegment of the line segment which contains P.
    Output: The next point Q, and the line segment it is on
    
    Procedure:
    distToEndpt = EuclideanDistance(P,lineseg->end);
    if( distToEndpt >= d )
    {
     Point Q(lineseg->start.x + dist*cos(lineseg.theta), lineseg->start.y + dist*sin(lineseg.theta));
     Z = lineseg;
    }
    else
    {
     nextseg = lineseg->next_segment;
        if( nextseg.ID !=-1 )
        {
      [Q, Z] = FindNextPt(nextseg->start,nextseg->ID,dist-distToEndpt);
     }
        else
        {
      return [P,lineseg];
     }
    }
     return [Q,Z]
    

    Entry point

    Function main()
    Output: vector of points
    Procedure:
    
    vector<LineSegment> line_segments;
    // Define it somehow giving it all the properties
    // ....
    
    vector<Point> equidistant_points;
    const int d = DIST;
    
    [Q Z] = FindNextPoint(line_segments[0].start,line_segments[0],DIST);
    while( Z.ID != -1 )
    {
     equidistant_points.push_back(Q);
     [Q Z] = FindNextPt(Q,Z,d);
    }