Home > Back-end >  Sort Coordinates by Distance to Origin Point - JavaScript
Sort Coordinates by Distance to Origin Point - JavaScript

Time:11-30

I have random rectangles on canvas stored in an array like so:

var rectangles = [
     {x: 10, y: 10},
     {x: 40, y: 50},
     {x: 1, y: 70},
     {x: 80, y: 5},
     {x: 30, y: 60}
];

I now want to label these rectangles based on their proximity to the origin point (0, 0).

My first thought was to loop through the x and y axis in different patterns, one example would be:

// 100 is the width and height of the canvas

for(var x = 0; x < 100; x  ){

   for(var y = 0; y < 100; y  ){

       // "intersects" loops through the array and returns the matching index or -1 if no match

       if(intersects(rectangles, x, y) > -1){

            console.log('Rectangle'   (intersects(rectangles, x, y)   1));

       }

   }

}

The issue i am having, is that no matter the pattern of the loop the result is not as expected.

enter image description here

My second thought was to draw rectangles to the origin point (seen on the last image) and sort the by the size of the rectangle. However, this (and calculating the line distance for that matter) also did not produce the expected result. This can be seen with the green rectangle, that is very close to X0, but should be last.

For example this should return the same result:

enter image description here

Does anyone know how I can achieve the correct labeling result? Thanks!

CodePudding user response:

Here's how to compare distances of coordinates against the origin and sort them (closest to furthest).

var rectangles = [
     {x: 10, y: 10},
     {x: 40, y: 50},
     {x: 1, y: 70},
     {x: 80, y: 5},
     {x: 30, y: 60}
];

const sumOfSquares = (x, y) => {
  return Math.pow(x, 2)   Math.pow(y, 2);
};

rectangles.sort((a, b) => {
  const sumA = sumOfSquares(a.x, a.y);
  const sumB = sumOfSquares(b.x, b.y);
  return sumA - sumB;
});

console.log(rectangles);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related