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, 3x3 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, 5x5 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, 7x7 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 theobj
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 theobj
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.
-
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 theaxis
.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) -
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:
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)
*/
}
CodePudding user response:
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, " ") "|"
}
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
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, " ") "|"
}
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
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]]
.