I have hero coordinates, target coordinate and range.
Let's say my hero is at x: 1, y: 1;
Target coordinates are: x: 4, y: 4;
I'm getting every coordinate from target within range. So if range is 1 then I create array of objects like this:
[
{x: 3, y: 3},
{x: 4, y: 3},
{x: 5, y: 3},
{x: 3, y: 4},
{x: 5, y: 4},
{x: 3, y: 5},
{x: 4, y: 5},
{x: 5, y: 5}
]
just 1 sqm - 8 coordinates around target. I'm getting that with simple algorithm
const hero = {x: 1, y: 1};
const closest = {x: 4, y: 4};
const range = 1;
const coordsAround = [];
for (let i = 0; i <= range * 2; i++) {
for (let j = 0; j <= range * 2; j++) {
let newCoord = { x: closest.x - range + j, y: closest.y - range + i };
//here note
if(!((newCoord.x === 3 && newCoord.y === 3) || (newCoord.x === 4 && newCoord.y === 3))) {
coordsAround.push(newCoord);
}
}
}
but additionally before push to coordsAround I'm executing some function which check collisions. Here in example I just added if statement to simplify it a bit. And with this if I excluded 3,3 and 4,3.
So now my dashboard is like this:
( I accidently made this dashboard so it's in y,x pattern instead of x,y srr)
where pink is hero (1,1) red are collisions, gold is the target (4,4) and greens are around the target (gained from above code snippet)
Now it's pretty simple to say which green is closest if it would be without red tiles (collisions):
const realClosest = {
x: hero.x > closest.x
? closest.x + 1
: closest.x - 1,
y: hero.y > closest.y
? closest.y + 1
: closest.y - 1
};
console.log('real closest is:', realClosest, 'but it is not within coordsAournd:', coordsAround,
'so next closest coord is 3,4 or 4,3 but 3,4 is not within coordsAournd as well' +
'so closest coord is 4,3');
but as far as I have this red tiles I don't know how to tell which is second best, third best and so on..
Sort the tiles with a custom function so that coordsAround[0] is the tile that is the closest to the hero, coordsAround[coordsAround.length - 1] is the tile that is thefarthest:
function dist2(a, b) {
let dx = a.x - b.x;
let dy = a.y - b.y;
return dx*dx + dy*dy;
}
coordsAround.sort(function (a, b) {
let da = dist2(a, hero);
let db = dist2(b, hero);
if (da < db) return -1;
if (da > db) return 1;
return 0;
})
The auxiliary function dist2 calculates the square of the distance. The sorting rder will be the same, because sqrt(x) < sqrt(y) when x < y (and both values are non--negative). Given that your range is reates a square, not a circly, you could also use dist = Math.max(Math.abs(dx), Math.abs(dy)).
Related
I have one array of objects which have pair of numbers and i have one given pair
let points = [{x:20,y:30}, {x:34,y:40}, {x:45,y:30}, {x:55,y:30}]
let givenNumber= {x:19,y:25}
How i can find nearest pair from array which is near to my given pair number
Anyone can help?
You could get the distance and then reduce the array by taking the smaler distance of two points of the array.
const distance = (p1, p2) => Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2);
let points = [{ x: 20, y: 30 }, { x: 34, y: 40 }, { x: 45, y: 30 }, { x: 55, y: 30 }],
point = { x: 19, y: 25} ,
result = points.reduce((a, b) => distance(a, point) < distance(b, point) ? a : b);
console.log(result);
This question already has answers here:
How to find the coordinate that is closest to the point of origin?
(2 answers)
Closed 4 years ago.
I am wondering how can I calculate my coordinates to an array of coordinates and find out which one is closest?
Lets say:
var player = {
x: 10,
y: 20
}
var box = [
{x: 17, y: 30},
{x: 41, y: 14},
{x: 20, y: 30}
];
So my player stays on 10, 20. And i have 3 different boxed, and i need to find out which one is closest. Is there any easy way to caluculate that?
You could calculate the distance and reduce the array by checking each distance and return the object with the shortest.
function getDistance(p1, p2) {
return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2))
}
var player = { x: 10, y: 20 },
box = [{ x: 17, y: 30 }, { x: 41, y: 14 }, { x: 20, y: 30 }];
console.log(box.reduce((a, b) => getDistance(a, player) < getDistance(b, player) ? a : b));
To find the least distance (the closest point) just find the least difference in the sum of the squares of their x and y offsets. You don't need to take the square root to find the actual distance as per Pythagorous's theorom. If you have trouble writing the code don't forget to include what you have tried.
You can use 2 points canvas formla and sort it based on distance
let positions = [
{x: 17, y: 30},
{x: 41, y: 14},
{x: 20, y: 30}
];
let x=10;
let y= 20;
let positions_close=positions.sort(p=>Math.hypot(p.x-x, p.y-y));
console.log(positions_close[0]);
//check the distance
let distances=positions.map(p=>Math.hypot(p.x-x, p.y-y));
console.log(distances);
I have some javascript code that tries to place some objects above each other relative from a center point in this case 0,0
The thing is that the amount of objects, size of the objects, and spacing between the objects are all variable.
See this image below that explains my situation the best (hopefully ;)):
So in this case the center point is the green dot and the mesh center positions are the yellow dots.
The Mh stands for Mesh Height (variable)
The Sh stands for Spacing height (variable)
I tried to show the logic behind the calculation of the yellow dots. But when i try to implement this in javascript it works for 3 lines but it breaks on other amount of lines.
This is what i have tried so far:
var data = {
text : ["THE NEXT","POINT","OF VIEW"],
size : 5,
height : 2,
curveSegments : 12,
line_height : 2
};
function generateTextGeometry(mesh) {
var scaled_lineheight = map_r(data.size, 2, 75, 0.5, 20);
var y_start = (0 - data.text.length * data.size / 2 - data.size / 2 - (data.text.length - 1) * scaled_lineheight)/2;
var loader = new THREE.FontLoader();
loader.load( 'data/suisse_2.json', function ( font ) {
for (var i = data.text.length - 1; i >= 0; i--) {
var geometry = new THREE.TextGeometry( data.text[i], {
font: font,
size: data.size,
height: data.height,
curveSegments: data.curveSegments
});
geometry.center();
mesh.children[i].geometry = geometry;
mesh.children[i].position.y = y_start;
console.log(mesh.children[i].position);
if (i < data.text.length) {
y_start += (data.size + scaled_lineheight);
}else{
y_start += data.size;
}
}
console.log('-----------------------');
});
}
and When i console.log the position for 3 lines it is ok:
p {x: 0, y: -6.301369863013699, z: 0}
p {x: 0, y: 0, z: 0}
p {x: 0, y: 6.301369863013699, z: 0}
but for any other amount of lines it is wrong:
p {x: 0, y: -4.4006849315068495, z: 0}
p {x: 0, y: 1.9006849315068495, z: 0}
So my final question is how do i always get the yellow positions on the right location relative from the green center? What is wrong in my current logic?
If anything is unclear please let me know! So i can clarify.
So after reading my own question about 20 times. The light shined upon my brains haha.
So i just made a mistake when calculating the initial start Here is the updated line:
var y_start = 0 - (((data.text.length - 1) * data.size) + ((data.text.length - 1) * scaled_lineheight))/ 2;
Issue
I am writing a program which involves calculating how many pixels one moving object overlaps the other. I'd have to return this value many times a second, so the program would have to be efficient. The example that I have come up with seems not to be.
Example
Let's scale-down for a minute and imagine we have an object that is 3*3 pixels and one that is 3*2
a b c
d e f j k l
g h i m n o
Each letter represents an individual pixel of each object. The 3*3 object sits on the left, and the 3*2 object sits on the right, with an x value 4 greater than that of the larger object. They are not overlapping.
Code
Currently, I am returning the number of overlapping pixels through a simple function that checks every pixel in object one against every pixel in object two for overlaps:
var a = {
width: 3,
height: 3,
x: 0,
y: 0
}
var b = {
width: 3,
height: 2,
x: 4,
y: 0
}
function overlappingPixels(object_1, object_2) {
var overlapping = 0;
for (var w_1 = 0; w_1 < object_1.width; w_1++) {
for (var h_1 = 0; h_1 < object_1.height; h_1++) {
for (var w_2 = 0; w_2 < object_1.width; w_2++) {
for (var h_2 = 0; h_2 < object_1.height; h_2++) {
if (w_1 + object_1.x == w_2 + object_2.x && h_1 + object_1.y == h_2 + + object_2.y) {
overlapping++;
}
}
}
}
}
return overlapping;
}
overlappingPixels(a, b); returns 0, because the two objects have no overlapping pixels.
Recap
To recap, I have built a function that compares each pixel of object one to each pixel of object two for any overlaps. This seems horribly inefficient, and I was curious as to whether there was a quicker option if this calculation needed to be performed very quickly for moving objects. The speed of the function breaks down quickly as the size of the objects increase. I'd be performing this calculation on larger objects anyway, so this isn't ideal.
Thanks!
There is an easy and efficient way to check if two rectangles collide.
var rect1 = {x: 5, y: 5, width: 50, height: 50}
var rect2 = {x: 20, y: 10, width: 10, height: 10}
if (rect1.x < rect2.x + rect2.width &&
rect1.x + rect1.width > rect2.x &&
rect1.y < rect2.y + rect2.height &&
rect1.height + rect1.y > rect2.y) {
// collision detected!
}
See MDN 2D object collision detection
To get the size of overlap is also quite easy once you know there is collision for sure. Just get the heigth and width where they overlap, and get the area by multiplying them. See the calculateCollisionLength function in the snippet to see how you can calculate the overlap without going over it pixel by pixel.
const calculateCollisionLength = (point1, point2, length1, length2) => {
const pointb1 = point1 + length1;
const pointb2 = point2 + length2;
const diff1 = Math.abs(point1 - point2);
const diff2 = Math.abs(pointb1 - pointb2);
return (length1 + length2 - diff1 - diff2) / 2;
}
function checkCollusion(rect1, rect2) {
if (rect1.x < rect2.x + rect2.width &&
rect1.x + rect1.width > rect2.x &&
rect1.y < rect2.y + rect2.height &&
rect1.height + rect1.y > rect2.y) {
// collision detected!
const collision = { xLength: 0, yLength: 0 };
collision.xLength = calculateCollisionLength(rect1.x, rect2.x, rect1.width, rect2.width);
collision.yLength = calculateCollisionLength(rect1.y, rect2.y, rect1.height, rect2.height);
return collision.xLength * collision.yLength;
}
else return null;
}
var rect1 = { x: 5, y: 5, width: 50, height: 50 }
var rect2 = { x: 20, y: 10, width: 10, height: 10 }
console.log(checkCollusion(rect1, rect2))
I know there are many many questions about sorting javascript arrays by multiple values, but none of the answers solved my problem.
I have an array of coordinates like:
x | y
--------
10 20
12 18
20 30
5 40
100 2
How can I get the coordinate that is closest to the point of origin?
Calculate the distance of each point using
Math.sqrt( Math.pow(x, 2) + Math.pow(y, 2) );
Take the result that's the lowest
var points = [
{x: 10, y: 20},
{x: 12, y: 18},
{x: 20, y: 30},
{x: 5, y: 40},
{x: 100, y: 2}
];
function d(point) {
return Math.pow(point.x, 2) + Math.pow(point.y, 2);
}
var closest = points.slice(1).reduce(function(min, p) {
if (d(p) < min.d) min.point = p;
return min;
}, {point: points[0], d:d(points[0])}).point;
closest;
// {x: 12, y:18}
You'll notice that we're skipping the Math.sqrt step here. As Mark Setchell points out, calculating the square root is a sort of "lowest common denominator" operation; We can still determine the closest point by getting the smallest x^2 + y^2 value.
For each x,y pair, square x, square y and add together. Smallest number is nearest to the origin.