Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape.

First time visiting? Here are some places to start:
  1. Looking for a certain topic? Check out the categories filter or use Search (upper right).
  2. Need support? Ask a question to our Community Support category.
  3. Please submit support tickets for bugs but you can request improvements in the Product Feedback category.
  4. Be respectful, on topic and if you see a problem, Flag it.

If you would like to contact our Community Manager personally, feel free to send a private message or an email.

Find duplicate vertices in an array?

EvanReeseEvanReese Member, Mentor Posts: 2,144 ✭✭✭✭✭
Anyone have a good suggestion on finding duplicate vertices in an array? Id like to find them and be able to remove duplicates.

I was considering looping over the whole array, and comparing each item to a copy of the array with that item removed in a nested loop. Is that a decent direction or is there a simpler way?
Evan Reese

Best Answers

  • xTimRicexTimRice Member Posts: 61 PRO
    Answer ✓
    Handcrafted furniture in Boston
    https://thesmoothcut.com/
  • _anton_anton Member, Onshape Employees Posts: 410
    Answer ✓
    Easy (quadratic) algorithm is to make a result array, iterate over the input array, check if the current vertex is within a tolerance of any of the verts in the result array - if not, then append to the result array. Performance with modestly-sized input should be all right.
  • Alex_KempenAlex_Kempen Member Posts: 248 EDU
    Answer ✓
    deduplicate won't work for vertices, as deduplicate uses map key access (so ==) for comparison, not tolerantEquals. Practically speaking, == is probably okay, but there are edge cases like selecting a vertex in sketch A and a vertex in sketch B which has been coincidented to the vertex in sketch A where == will fail.

    The best alternative to deduplicate is likely qUniqueVertices, although that requires you to have original queries. Otherwise, clusterPoints should do the trick. If you do use it, you'll probably want to pass `TOLERANCE.zeroLength * meter` as the tolerance, and note the output is of the following form:
    Given an input `[vertex a, vertex b, vertex c, vertex a]`, clusterPoints will return `[[0, 3], [1], [2]]`. Hopefully it's clear how you can convert the given result back into a list of vertices.
    CS Student at UT Dallas
    Alex.Kempen@utdallas.edu
    Check out my FeatureScripts here:



  • EvanReeseEvanReese Member, Mentor Posts: 2,144 ✭✭✭✭✭
    Answer ✓
    Here's what I ended up going with. Thanks, Alex!

    /**
     * Takes an array of vectors and returns it with duplicates removed.
     */
    export function deduplicatePoints(points is array) returns array
    {
        const pointClusters = clusterPoints(points, TOLERANCE.zeroLength * meter);
    
        var result = [];
        for (var pointCluster in pointClusters)
            result = append(result, points[pointCluster[0]]);
        return result;
    }

    Evan Reese

Answers

  • xTimRicexTimRice Member Posts: 61 PRO
    Answer ✓
    Handcrafted furniture in Boston
    https://thesmoothcut.com/
  • _anton_anton Member, Onshape Employees Posts: 410
    Answer ✓
    Easy (quadratic) algorithm is to make a result array, iterate over the input array, check if the current vertex is within a tolerance of any of the verts in the result array - if not, then append to the result array. Performance with modestly-sized input should be all right.
  • EvanReeseEvanReese Member, Mentor Posts: 2,144 ✭✭✭✭✭
    @TimRice
    That's exactly what I'm looking for, and Anton, thanks for the rundown. That makes sense too. I was searching for it with autocomplete, but it wasn't there because deduplicate() isn't part of common.fs or geometry.fs. Thanks!
    Evan Reese
  • Alex_KempenAlex_Kempen Member Posts: 248 EDU
    Answer ✓
    deduplicate won't work for vertices, as deduplicate uses map key access (so ==) for comparison, not tolerantEquals. Practically speaking, == is probably okay, but there are edge cases like selecting a vertex in sketch A and a vertex in sketch B which has been coincidented to the vertex in sketch A where == will fail.

    The best alternative to deduplicate is likely qUniqueVertices, although that requires you to have original queries. Otherwise, clusterPoints should do the trick. If you do use it, you'll probably want to pass `TOLERANCE.zeroLength * meter` as the tolerance, and note the output is of the following form:
    Given an input `[vertex a, vertex b, vertex c, vertex a]`, clusterPoints will return `[[0, 3], [1], [2]]`. Hopefully it's clear how you can convert the given result back into a list of vertices.
    CS Student at UT Dallas
    Alex.Kempen@utdallas.edu
    Check out my FeatureScripts here:



  • _anton_anton Member, Onshape Employees Posts: 410
    > qUniqueVertices/clusterPoints

    I totally didn't forget about these and just didn't want to steal your thunder.  :p
  • EvanReeseEvanReese Member, Mentor Posts: 2,144 ✭✭✭✭✭
    Answer ✓
    Here's what I ended up going with. Thanks, Alex!

    /**
     * Takes an array of vectors and returns it with duplicates removed.
     */
    export function deduplicatePoints(points is array) returns array
    {
        const pointClusters = clusterPoints(points, TOLERANCE.zeroLength * meter);
    
        var result = [];
        for (var pointCluster in pointClusters)
            result = append(result, points[pointCluster[0]]);
        return result;
    }

    Evan Reese
Sign In or Register to comment.