Arrays 在二维空间中查找圆内的所有点

Arrays 在二维空间中查找圆内的所有点,arrays,performance,algorithm,optimization,geometry,Arrays,Performance,Algorithm,Optimization,Geometry,我表示我的2D空间(考虑一个窗口),其中每个像素显示为2D数组中的一个单元。i、 e.100x100窗口由相同尺寸的数组表示 现在给定窗口中的一个点,如果我画一个半径为r的圆,我想找到该圆中的所有点 我想我应该检查半径周围正方形区域中的每个点,如果它是否位于圆中,则使用side=2*r。我会用正常距离公式,也许 因此,可能出现以下情况: for (x=center-radius ; x<center+radius ; x++){ for (y=center-radius ; y&l

我表示我的2D空间(考虑一个窗口),其中每个像素显示为2D数组中的一个单元。i、 e.100x100窗口由相同尺寸的数组表示

现在给定窗口中的一个点,如果我画一个半径为r的圆,我想找到该圆中的所有点

我想我应该检查半径周围正方形区域中的每个点,如果它是否位于圆中,则使用
side=2*r
。我会用正常距离公式,也许

因此,可能出现以下情况:

for (x=center-radius ; x<center+radius ; x++){
    for (y=center-radius ; y<center+radius; y++) {
        if (inside) {
            // Do something
        }
    }
}
对于(x=中心半径;xIf),以下为真:

((xPos-centreX)^2+(yPos-centreY)^2)您可以绕过条件检查的需要:

for(x=center-radius; x<center+radius; x++) {
    yspan = radius*sin(acos((center-x)/radius));
    for(y=center-yspan; y<center+yspan; y++) {
        // (x,y) is inside the circle
    }
}
用于(x=中心半径;x
这对我有用吗

对于您的100x100,是的

我能快点吗

是的。例如,您可以:

  • 只检查一个象限,由于对称性,获取其他点
  • 计算距离时跳过平方根
代码:


for(x=xCenter-radius;x似乎是正确的。您可以通过找到minY,然后对当前x执行从-rangeY到+rangeY的DoSomething来稍微加快速度

for(dx=0;dx<rad; dx++)
{
  rangeY = 0;
  while (!inside(x, rangeY)) //inside == check if x*x + y*y <r*r
    rangeY++;

  for(y=center-rangeY;y<center+rangeY;y++) 
  {
    DoSomething(centerX - dx, y);
    DoSomething(centerX + dx, y);      }
}

for(dx=0;dx你可以通过计算尽可能多的循环外部来获得加速。也不需要做毕达哥拉斯定理的平方根…只需保持所有的平方。只需对四分之一的圆进行数学运算就可以得到最终的加速(因为它是对称的)…找到匹配项后,您只需在其他三个季度复制它

radiusSquared = radius*radius;
rightEdge = centerX+radius;
bottomEdge = centerY+radius;
for(x = centerX; x <= rightEdge; x++){
    xSquared = x*x;
    for(y = centerY; y <= bottomEdge; y++){
        ySquared = y*y;
        distSquared = xSquared+ySquared;
        if(distSquared <= radiusSquared){
            // Get positions for the other quadrants.
            otherX = centerX-(x-centerX);
            otherY = centerY-(y-centerY);
            // Do something for all four quadrants.
            doSomething(x, y);
            doSomething(x, otherY);
            doSomething(otherX, y);
            doSomething(otherX, otherY);
        }
    }
}
radiusSquared=半径*半径;
右边缘=中心X+半径;
底边=中心+半径;

对于(x=centerX;x我知道这个问题有一个公认的答案,但我有一个简单得多的答案。其他答案让我困惑不解,因为我不知道
center
xcenter
ycenter
是什么,函数背后的数学没有得到解释,我努力寻找自己的数学解决方案

我的方程式很简单:

cx
是圆中心的x点

cy
是圆中心的y点

rad
是圆的半径

我的方程/函数所做的是通过计算给定半径的每个可能点来计算点,并加上和减去
cx
cy
的偏移量

//Creates an array filled with numbers
function range(begin, end) {
    for (var i = begin, arr = []; i < end; i++) {
      arr.push(i);
    }

    return arr;
}

function calculateAllPointsInCircle(cx, cy, rad) {

   var rang = range(-rad, rad + 1);
   var px = [];
   var py = [];
   var xy = [];

   for (var i = 0; i < rang.length; i++) {
     var x = cx + rang[i];
     px.push(x);

     for (var l - rang.length - 1; l > 0; l--) {
        var y = cy + rang[l];
        if (!py.indexOf(y)===-1) { py.push(y); }

        xy.push(x+','+y);
     }
   }

   return {
     x: x,
     y: y,
     xy: xy
   }
}
//创建一个充满数字的数组
功能范围(开始、结束){
for(var i=begin,arr=[];i0;l--){
变量y=cy+rang[l];
如果(!py.indexOf(y)==-1){py.push(y);}
xy.推力(x+','+y);
}
}
返回{
x:x,
y:y,
xy:xy
}
}
性能远远高于其他答案:
您可以用数学检查我的公式,使用公式验证给定点是否在圆内
x*x+y*y,以获得圆内所有点的列表,您应该使用:

var radius = 100, r2 = radius * radius;
var circle = [];
for (var dx = -radius; dx <= radius; dx++) {
  var h = Math.sqrt(r2 - dx * dx) | 0;
  for (var dy = -h; dy <= h; dy++) {
    circle.push([dx, dy])
  }
}
var radius=100,r2=radius*radius;
var循环=[];

对于(var dx=-radius;dx模拟pi数,使用xx+yy使用毕达哥拉斯定理生成均匀分布的随机值,以确定当前“单元”的距离是否在圆内。我的解决方案;)我的代码给人的印象是,他必须用尽可能少的字符来完成。咳嗽:你说对于100X100它是有效的。它对其他维度不起作用吗?它总是有效的。问题是,速度有多快。在维度d=2时,它是O(r^2),其中r是半径。在d=3时,它是O(r^3),我们在球体中寻找点。通常是O(r^d).你的问题是“它能达到我的目的吗”,我理解为“它会跑得太快以至于我感觉不到它吗”.我说是的,因为对于现代计算机上的r=100和d=2,即使在JS中,时间也不会明显。但是,对于更大的r或d,时间会明显。哦,对不起,我的意思是如果尺寸100X100是其他东西,即500X300或任何东西。是的,它会工作。速度与网格大小无关。重要的是半径的大小算法的复杂度是O(r^d)。只有r(半径)和d(维数)重要。作为一个ES6数组,如果((x-中心)*(x-中心)+(y-中心)*(y-中心)
试试看,浪费了我的时间来检查它是否快速但不起作用。我假设,如果你的x中心和y中心坐标不同,它会变为循环的第一个坐标:center=xcenter,yspan:center=xcenter和循环的第二个中心=ycenter?是的。你甚至可以在
for
sin半径要得到一个椭圆,@Chandrapalsinghhala请直接在您的上方查看我的评论。
//Creates an array filled with numbers
function range(begin, end) {
    for (var i = begin, arr = []; i < end; i++) {
      arr.push(i);
    }

    return arr;
}

function calculateAllPointsInCircle(cx, cy, rad) {

   var rang = range(-rad, rad + 1);
   var px = [];
   var py = [];
   var xy = [];

   for (var i = 0; i < rang.length; i++) {
     var x = cx + rang[i];
     px.push(x);

     for (var l - rang.length - 1; l > 0; l--) {
        var y = cy + rang[l];
        if (!py.indexOf(y)===-1) { py.push(y); }

        xy.push(x+','+y);
     }
   }

   return {
     x: x,
     y: y,
     xy: xy
   }
}
function range(begin, end) {
  for (let i = begin; i < end; ++i) {
    yield i;
  }
}

function calculateAllPointsInCircle(cx, cy, rad) {
    return {
        x: [cx + i for (i of range(-rad, rad + 1))],
        y: [cy + i for (i of range(-rad, rad + 1))]
    };
}
var radius = 100, r2 = radius * radius;
var circle = [];
for (var dx = -radius; dx <= radius; dx++) {
  var h = Math.sqrt(r2 - dx * dx) | 0;
  for (var dy = -h; dy <= h; dy++) {
    circle.push([dx, dy])
  }
}