Skip to content

Generate and sort cartesian coordinates around (0,0) in all quadrants using Javascript’s nested array loops

I have an variable obj that has the element count that needs a cartesian coordinate.

So I want to generate the following matrix.

obj = 9, Square root of obj = 3, 3×3 matrix
(-1,1) (0,1) (1,1)
(-1,0) (0,0) (1,0)
(-1,-1) (0,-1) (1,-1)
obj = 25, Square root of obj = 5, 5×5 matrix
(-2,2) (-1,2) (0,2) (1,2) (2,2)
(-2,1) (-1,1) (0,1) (1,1) (2,1)
(-2,0) (-1,0) (0,0) (1,0) (2,0)
(-2,-1) (-1,-1) (0,-1) (1,-1) (2,-1)
(-2,-2) (-1,-2) (0,-2) (1,-2) (2,-2)
obj = 49, Square root of obj = 7, 7×7 matrix
(-3,3) (-2,3) (-1,3) (0,3) (1,3) (2,3) (3,3)
(-3,2) (-2,2) (-1,2) (0,2) (1,2) (2,2) (3,2)
(-3,1) (-2,1) (-1,1) (0,1) (1,1) (2,1) (3,1)
(-3,0) (-2,0) (-1,0) (0,0) (1,0) (2,0) (3,0)
(-3,-1) (-2,-1) (-1,-1) (0,-1) (1,-1) (2,-1) (3,-1)
(-3,-2) (-2,-2) (-1,-2) (0,-2) (1,-2) (2,-2) (3,-2)
(-3,-3) (-2,-3) (-1,-3) (0,-3) (1,-3) (2,-3) (3,-3)

What I did was hardcoded the first set that is when the obj value is 9 to be created inside a loop, and pushed those in a list called coordinates.

All I then did was call the loop by passing the Math.sqrt(obj).

Problem:

  • There are missing coordinates, when the obj value is greater than 9.
    For eg: when the obj value is 49. It would create the adjacent previous element, but it won’t create the previous element of the previous element (coordinates like (-1, 3), (1, 3), (-3, 1), (3, 1), (-3, -1), (3, -1), (-1, -3), (1, -3)).
    This is happening because I hardcoded the logic to create the previous coordinate by subtracting with 1. As the obj value increases the current number of missing coordinates is twice the previous number of missing elements (not sure).
    I can’t seem to figure out a way to create the logic to create the missing elements.
  • Another problem is repeating coordinates. Which happened because I used the logic to create the missing elements wrong.
  • Hard to check if all coordinates are correct when the count (obj) value increases.

Note:

I would like to know different approaches to create the cartesian coordinates around (0, 0). Apparently all my efforts in building the logic ends up with missing elements or repeating elements. And it is hard to actually check if all the coordinates are correct when the obj values increases.

I want to create a cartesian coordinate matrix with any value. Currently I’m stuck with using the squares of odd numbers (I plan to substitute the 0 axis for when the number is less than or greater than squares of odd numbers).

Approach ideas/concepts to test:

As I’m a beginner in graphics programming, I would like to know better approaches to do this. Also here are some approaches I just came up with. I am not sure if this works yet, but I’ll add an update.

  1. I could maybe create a cross for just the 0’s (x,y) axis. And then try to create the rest of the elements by subtracting or adding to each coordinate in the axis.

    As there are 4 quadrants, I could create 4 individual loops that creates just that particular quadrant’s missing coordinates.

    (0,1)
    (-1,0) (0,0) (1,0)
    (0,-1)
  2. Another approach could be like to sort the coordinates and then check to see the distance between 2 adjacent coordinates if it is greater than 1 create a new element, else continue checking.

Current Code:

My demo code at JSFiddle

const speak = 'these are the COORDINATES you are looking for!'
// 9, 25, 49, 81, 121 => substitutable values for variable 'obj'
const obj = 49 // loop using this variable
const coordinates = []

// hardcodes
const start = [0,0]
const points = []
/* points.push(start) */


/**
 * FIX!.
 *
 * needs to also create coordinates from initial coordinate substracted
 * by more than 1, currently it gets the previous element by substracting 1,
 * we need to get previous elements of the previous elements based on number
 * of elements.
 */

// creating array from coordinates in all quadrants
function demo (n) {
    // pushing initial coordinates
    for (let i = 1; i <= Math.sqrt(n); i++) {
    
    coordinates.push([-i, i], [i-1, i], [i, i], [-i, i-1], [i-1, i-1], [i, i-1], [-i, -i], [i-1, -i],  [i, -i])
    for (let j = 3; j < Math.sqrt(n); j++) {
        coordinates.push([-i, i-j], [i-j, i-j], [i, i-j], [i-j, -i])
    }
  }
  // pushing missing coordinates
/*   for (let i = 1; i <= Math.sqrt(n); i++) {
    coordinates.push([i-2, i], [-i, i-2], [i-2, i-2], [i, i-2])
  } */

for (let i = 0; i < obj; i++) {
      points.push(coordinates[i])
  }
}

demo(obj)
// sorting multidimensional array
points.sort(function (a, b) {
  return a[1] - b[1]
})

/* // print array as row and column of coordinates
for (let x = 0; x < Math.sqrt(obj); x++) {
  let el = []
  for (let i = 0; i < Math.sqrt(obj); i++){
    el.push(points[i + Math.sqrt(obj) * x])
  }
  console.log(el)
*/
}

Answer

If I understand you correctly you want to have the coordinates in an order so that the left upper corner is first and right lower corner is last, right?

You can try it this way

let
  size = 81, //ie a 7x7 grid,
  rc = Math.floor(Math.sqrt(size))  //number of rows/columns
  max = Math.floor(rc / 2),  //maximum x and y coordinates
  min = -1 * max;  //minimim x and y coordinates
  coords = [] //the array of coordinates
  
//as the positive y coordinates should be first, iterate from max down to min
for (let y = max; y >= min; y--) 
  //for each row, iterate the x cooridinates from min up to max
  for (let x = min; x <= max; x++)
    coords.push([x,y]);
    
    
    
for (let i = 0; i < rc; i++) {
  let row = coords.slice(i*rc, (i+1)*rc);  //get one full row of coordinates
  console.log(row.map(x => formatCoordinate(x)).join(""));  //and display it
}


function formatCoordinate(x) {
  return "|" + `${x[0]}`.padStart(3, " ") + "/" + `${x[1]}`.padStart(3, " ") + "|"  
}

Another way, is, just put your coordinates in the array in any order, and sort the values afterwards. But you have to sort by x and y coordinate,

let
  size = 81, //ie a 7x7 grid,
  rc = Math.floor(Math.sqrt(size))  //number of rows/columns
  max = Math.floor(rc / 2),  //maximum x and y coordinates
  min = -1 * max;  //minimim x and y coordinates
  coords = [] //the array of coordinates

//coords will be [[-3, -3], [-3, -2], [-3, -1] ..., [3, 3]]
for (let i = min; i <= max; i++)
  for (let j = min; j <= max; j++)
    coords.push([i,j]);
    


//sort coords to be [[-3, 3], [-2, 3], [-1, 3], ... [3, -3]]
coords.sort((a, b) => {
  if (a[1] != b[1])  //if y coordinates are different
    return b[1] - a[1];  //higher y coordinates come first
   
  return a[0] - b[0];  //lower x coordinates come firs
})

for (let i = 0; i < rc; i++) {
  let row = coords.slice(i*rc, (i+1)*rc);  //get one full row of coordinates
  console.log(row.map(x => formatCoordinate(x)).join(""));  //and display it
}

function formatCoordinate(x) {
  return "|" + `${x[0]}`.padStart(3, " ") + "/" + `${x[1]}`.padStart(3, " ") + "|"  
}

Both approaches assume that size is the square of an odd number, but you can of course adapt them any way you want, ie in principle you just need to set min and max to any values you want, and both approaches will create a square of coordinates from [[min/max] ... [max/min]].