Jump to content

Recommended Posts

I am trying to find points with the same xz but different y.

Keep the lowest and highest of each xz pile .

Make a new clean polyline from those.

i need some help with my vex code, argsort isnt working as i expected, i cant find out why


Edited by papsphilip

Share this post

Link to post
Share on other sites

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

Share this post

Link to post
Share on other sites

thank you very much for the detailed explanation, i am going to study this and try to find what was wrong with my vex

its really frustrating when you cant find your mistake

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now