0

I have an array full of triangles. Triangles are composed of 3 Point objects (x and y coordinates). Some triangles are composed of the same points but in different order with previous as seen from the pictures. How can I filter out these duplicates? NOTE: I supplied the code which is not working below.

enter image description here

enter image description here

     let cleanedTriangles = [];

     for (let i = 0; i < triangles.length; i++)
     {
        if (i = 0)
        {
            cleanedTriangles.push(triangles[i])
        }
        else
        {
            for (let j = 0; j < cleanedTriangles.length; j++)
            {
              if (
                 !((triangles[i].p1.x === cleanedTriangles[j].p1.x || triangles[i].p1.x === cleanedTriangles[j].p2.x || triangles[i].p1.x === cleanedTriangles[j].p3.x)
                     &&
                     (triangles[i].p2.x === cleanedTriangles[j].p1.x || triangles[i].p2.x === cleanedTriangles[j].p2.x || triangles[i].p2.x === cleanedTriangles[j].p3.x)
                     &&
                     (triangles[i].p3.x === cleanedTriangles[j].p1.x || triangles[i].p3.x === cleanedTriangles[j].p2.x || triangles[i].p3.x === cleanedTriangles[j].p3.x)
                     &&
                     (triangles[i].p1.y === cleanedTriangles[j].p1.y || triangles[i].p1.y === cleanedTriangles[j].p2.y || triangles[i].p1.y === cleanedTriangles[j].p3.y)
                     &&
                     (triangles[i].p2.y === cleanedTriangles[j].p1.y || triangles[i].p2.y === cleanedTriangles[j].p2.y || triangles[i].p2.y === cleanedTriangles[j].p3.y)
                     &&
                     (triangles[i].p3.y === cleanedTriangles[j].p1.y || triangles[i].p3.y === cleanedTriangles[j].p2.y || triangles[i].p3.y === cleanedTriangles[j].p3.y)
                 )
              )
              {
                 cleanedTriangles.push(triangles[i])
              }
            }

        }
     }


function Point(x, y)
{

    this.x = x || 0;    

    this.y = y || 0;

}


function Triangle(point1, point2, point3)
{
    this.p1 = point1 || new Point(0, 0);    

    this.p2 = point2 || new Point(0, 0);

    this.p3 = point3 || new Point(0, 0);
}
5
  • Instead of your console logs add your original input and expected output. Commented Jun 16, 2019 at 15:38
  • you should add your code to question instead of screenshot Commented Jun 16, 2019 at 15:39
  • have same points the same id? Commented Jun 16, 2019 at 15:39
  • @NinaScholz no it can be different. The only same things are x and y coordinates. Commented Jun 16, 2019 at 15:44
  • @HienNguyen I added code of what I tried so far. Commented Jun 16, 2019 at 15:45

2 Answers 2

2

You could get the points in an array, sort by x and y ascending, create a string out of the coordinates and take this as key for a Set. Then filter.

var array = [{ p1: { x: 1, y: 1 }, p2: { x: 3, y: 1 }, p3: { x: 1, y: 4 } }, { p1: { x: 1, y: 1 }, p2: { x: 3, y: 1 }, p3: { x: 1, y: 4 } }, { p1: { x: 1, y: 1 }, p2: { x: 1, y: 4 }, p3: { x: 3, y: 1 } }, { p1: { x: 1, y: 1 }, p2: { x: 3, y: 1 }, p3: { x: 1, y: 4 } }, { p1: { x: 1, y: 1 }, p2: { x: 2, y: 7 }, p3: { x: 1, y: 4 } }, { p1: { x: 2, y: 5 }, p2: { x: 3, y: 1 }, p3: { x: 1, y: 4 } }],
    triangles = new Set,
    result = array.filter(({ p1, p2, p3 }) => {
        var key = JSON.stringify([p1, p2, p3].sort((a, b) => a.x - b.x || a.y - b.y));
        return !triangles.has(key) && triangles.add(key);
    });

console.log(result);
console.log([...triangles]);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

1 Comment

thank you so much for this concise and neat answer.
1

I'd do a very logical approach: calculate the circumference of the triangles. If two triangles don't have the same perimeter, then they cannot be identical, therefore their vertexes (or peaks? or whatever in English ;) ) cannot be the same.

const triangleArray = [{
    p1: {
      x: 10,
      y: 5
    },
    p2: {
      x: 11,
      y: 5
    },
    p3: {
      x: 10,
      y: 2
    }
  },
  {
    p1: {
      x: 8,
      y: 4
    },
    p2: {
      x: 7,
      y: 5
    },
    p3: {
      x: 10,
      y: 2
    }
  },
  {
    p1: {
      x: 10,
      y: 5
    },
    p2: {
      x: 11,
      y: 5
    },
    p3: {
      x: 10,
      y: 2
    }
  }
]


triangleArray.forEach(triangle => {
  triangle.perimeter = calcPerimeter(triangle.p1, triangle.p2, triangle.p3)
})

console.log(triangleArray)

// Math.hypot() - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/hypot
function calcSideLength(p1, p2) {
  return Math.hypot(p1.x - p2.x, p1.y - p2.y)
}

function calcPerimeter(p1, p2, p3) {
  return calcSideLength(p1, p2) + calcSideLength(p2, p3) + calcSideLength(p3, p1)
}

Then I would check those triangles that have the same perimeter if they have the same endpoints

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.