简体   繁体   English

如何在Javascript中获取特定坐标(x,y)周围的坐标

[英]How to get coordinates around specific coordinate (x, y) in Javascript

As in title I am struggling with getting coordinates that are around specific coordinate.正如标题一样,我正在努力获取特定坐标附近的坐标。 In this example I will say 24, 7.在这个例子中,我会说 24、7。

在此处输入图片说明

I usually use two loops in this case: 在这种情况下,我通常使用两个循环:

 const results = [];

  for(const dx of [-1, 0, 1]) {
   for(const dy of [-1, 0, 1]) {
     if(dx === 0 && dy === 0) continue;
     results.push({ x: x + dx, y: y + dy });
  }
}

Or just: 要不就:

 const neighbours = [
    [-1, -1], [-1,  0], [-1,  1],
    [ 0, -1], /*0, 0*/  [ 0,  1], 
    [ 1, -1], [ 1,  0], [ 1,  1]
 ];

 const results = neighbours.map(([dx, dy]) => ({ x: x + dx, y: y + dy }));

It's good that you want to not only achieve this, but achieve it nicely! 不仅要实现这一目标,而且还要很好地实现,这很好! In my personal opinion, this could be made "nice" by working with a definition of "adjacency" explicit in the code. 我个人认为,可以通过使用代码中显式的“邻接”定义来使其“很好”。

 // This code makes "adjacency" explicit by working with "adjacency offset generators" // These are functions which return all offsets that move a point to all of its adjacent points let manhattanAdjacencyOffsets = dist => { // Returns adjacency offsets corresponding to all points within a manhattan distance of `dist` let ret = []; for (let x = -dist; x <= dist; x++) { for (let y = -dist; y <= dist; y++) { if (x === 0 && y === 0) continue; // Don't include the 0,0 point ret.push({ x, y }); }} return ret; }; // Now `nCoordinates` becomes very short: let nCoordinates = (x0, y0, adjacencyOffsets) => { return adjacencyOffsets.map(({ x, y }) => ({ x: x + x0, y: y + y0 })); }; // Here's manhattan adjacency offsets with a distance of 1 let adjacencyOffsets = manhattanAdjacencyOffsets(1); // And here's all neighbours of the point (10,20), with regard to those offsets let neighbours = nCoordinates(10, 20, adjacencyOffsets); console.log(neighbours); 

I like this approach because it makes "adjacency" explicit. 我喜欢这种方法,因为它使“邻接”变得明确。 You could even define new adjacency functions to change your code's definition of "adjacency". 您甚至可以定义新的邻接函数来更改代码的“邻接”定义。

For example you could use cartesian distance instead of manhattan distance (all points within a circular range of the source tile): 例如,您可以使用笛卡尔距离而不是曼哈顿距离(源图块的圆形范围内的所有点):

let cartesianAdjacencyOffsets = dist => {
  let sqrDist = dist * dist;
  let ret = [];
  let min = Math.ceil(-dist);
  let max = Math.floor(dist);
  for (let x = min; x <= max; x++) { for (let y = min; y <= max; y++) {
    if (x === 0 && y === 0) continue; // Don't include the 0,0 point
    if (sqrDist < x * x + y * y) continue; // Don't include points too far away
    ret.push({ x, y });
  }}
  return ret;
};

There are two basic ways, both O(n).有两种基本方法,都是 O(n)。

  1. The first one is so simple, efficient and ugly that i think it's a sin in CS to do such things.第一个是如此简单、高效和丑陋,以至于我认为在 CS 中做这样的事情是一种罪过。

 var neighborFunctions = [ (x,y) => [x+1,y] , (x,y) => [x+1,y+1] , (x,y) => [x,y+1] , (x,y) => [x-1,y+1] , (x,y) => [x-1,y] , (x,y) => [x-1,y-1] , (x,y) => [x,y-1] , (x,y) => [x+1,y-1] ], getNeigborCoords = (x,y) => Array.from({length:8}, (_,i) => neighborFunctions[i](x,y)), result = getNeigborCoords(24,7); console.log(JSON.stringify(result));

  1. Now lets dive into another sin but a functional one, Math.sin() .现在让我们深入研究另一个罪过,但一个功能性的罪, Math.sin()

 var getNeigborCoords = (x,y) => Array.from( {length:8} , (_,i) => [ x+Math.round(Math.cos(Math.PI*i/4)) , y+Math.round(Math.sin(Math.PI*i/4)) ] ), result = getNeigborCoords(24,7); console.log(JSON.stringify(result));

Since the second one is a functional solution you may develop it further to calculate the second neighbors and whatnot.由于第二个是功能解决方案,您可以进一步开发它以计算第二个邻居等等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM