Jump to content

Sort points

Recommended Posts

Hey Philip !

That's an interesting one.
I took a slightly different approach than you did

So basically, in a wrangle over detail, I set some general variables.
Mainly, two arrays. One to store the centers, and another one to store the ymin and ymax (as a vector2).

The idea is to then run over each points, and compare their position to the centers (with a threshold, like you did).
If the position match one of the centers, then we get the relevant ymin and ymax, and update them if the current position is higher or lower.
If there isn't a match to the centers, then that means we have a point from a new line. So we add the point as a new center, as well as ymin and ymax (initialized to the same value).

And that's it ! There is a second loop to create the polylines from the data collected by the main loop.

int almostEqual(float a, b, threshold){
    return b + threshold >= a && b - threshold <= a;

/* Those two arrays will always have the same length.
   Their index correspond to the same center */
vector centers[]; // contains x and z positions for each center
vector2 yvals[];  // contains ymin and ymax for each center

The idea is for each points, compare its position to the centers
When it matches, update the yvals if it is higher or lower

If there is no match, then we add a new entry to both centers and yvals

float threshold = 1; // this is the same as your tolerance
for(int i=0; i<npoints(1); i++){
    vector curP = point(1, "P", i);
    int found = 0;
    foreach(int j; vector center; centers){
        int x = almostEqual(curP.x, center.x, threshold);
        int z = almostEqual(curP.z, center.z, threshold);
        if(x==1 && z==1){
            found ++;
            // update yvals if the current height is higher or lower
            float ymin = yvals[j][0];
            float ymax = yvals[j][1];
            if(curP.y < ymin)
                yvals[j][0] = curP.y;
            else if(curP.y > ymax)
                yvals[j][1] = curP.y;
            // We already matched, so we know that no other center interrests us.
    if(found == 0){
        //add to center and yvals
        append(centers, set(curP.x, 0, curP.z));
        append(yvals, set(curP.y, curP.y));

// Create Lines
for(int i=0; i<len(centers); i++){
    vector center = centers[i];
    vector2 yval = yvals[i];
    vector p0 = center;
    p0.y = yval[0];
    vector p1 = center;
    p1.y = yval[1];
    int newP0 = addpoint(0, p0);
    int newP1 = addpoint(0, p1);
    addprim(0, "polyline", newP0, newP1);

Here's a quick gif overview

Hope that helps !


P.S. In retrospect, I could have used an array of vector4, used x and w to store the x and z center, and used y and z to store the ymin and ymax. That would leave us with only one array. Would it be cleaner ? Or simply harder to understand ? You can be the judge of that.

Edited by Alain2131
  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...