Algorithm 二维循环搜索模式

Algorithm 二维循环搜索模式,algorithm,math,2d,Algorithm,Math,2d,我需要一个算法来给我坐标到最近的细胞(按距离的顺序)到另一个细胞在二维网格。这是一个搜索算法,然后检查这些坐标是否适合各种情况。不管怎样,到目前为止我想到了这个: 函数测试(cx、cy、idx){ 变量半径=数学地板(数学sqrt(idx/Math.PI)); var段=数学圆(idx-(半径*数学圆周率)); 可变角度=段/半径; var x=数学圆(cx+半径*数学cos(角度)); 变量y=数学圆(cy+半径*数学正弦(角度)); 返回[x,y]; } addEventListener(

我需要一个算法来给我坐标到最近的细胞(按距离的顺序)到另一个细胞在二维网格。这是一个搜索算法,然后检查这些坐标是否适合各种情况。不管怎样,到目前为止我想到了这个:

函数测试(cx、cy、idx){
变量半径=数学地板(数学sqrt(idx/Math.PI));
var段=数学圆(idx-(半径*数学圆周率));
可变角度=段/半径;
var x=数学圆(cx+半径*数学cos(角度));
变量y=数学圆(cy+半径*数学正弦(角度));
返回[x,y];
}
addEventListener(“加载”,函数(){
var canv=document.createElement(“画布”);
文件.正文.附件(canv);
canv.宽度=800;
canv.高度=600;
var ctx=canv.getContext(“2d”);
var量表=5;
var-idx=0;
var idx_end=10000;
var func=函数(){
var xy=testy(0,0,idx++);
var x=xy[0]*比例+canv.width/2;
变量y=xy[1]*比例+canv.height/2;
ctx.rect(x,y,scale,scale);
ctx.fill();
if(idx});不要考虑整圈,而是考虑一个象限。稍后将其调整为完整的循环应该相当容易。为方便起见,使用(0,0)作为圆的中心。所以你想用x,y列出网格单元 ≥ 按非递减x²的顺序为0 + y²

一种有用的数据结构是优先级队列。它可以用于跟踪每个x值的下一个y值,并且可以提取最小x²的y值 + 你很容易就学会了

q = empty priority queue, for easy access to element with minimal x²+y²
Insert (0,0) into queue
while queue is not empty:
  remove minimal element from queue and call it (x,y)
  insert (x,y+1) into queue unless y+1 is off canvas
  if y = 0:
    insert (x+1,0) into queue unless x+1 is off canvas
  do whatever you want to do with (x,y)
因此,对于大小为n的画布,这将枚举所有n²点,但优先级队列最多只包含n个元素。整个循环以O(n²)运行 对数(n))。如果你因为找到了你想要的东西而放弃了循环,它会变得更便宜,而不是简单地对所有的点进行排序。另一个好处是,您可以专门使用整数算术,因此数字错误不会成为问题。一个缺点是JavaScript没有现成的优先级队列,但我相信您可以找到一个可以重用的实现,例如

当进行整圈时,您将生成(−x、 y)除非x=0,对于(x,−y) 及(−x,,−y) 。你可以利用对称性多一点,只要有循环⅛ 如果x=y,则不插入(x,y+1),然后也生成(y,x)作为单独的点,除非x=y。对于许多用例来说,性能上的差异应该是微不足道的

“严格使用”;
功能比较(a,b){
常数a2=a.x*a.x+a.y*a.y;
常数b2=b.x*b.x+b.y*b.y;
返回a2b2-1:0;
}
//在-w1范围内产生点;
const pointgen=带偏移量(cx、cy、w、h);
设cntr=0;
var func=函数(){
const{value,done}=pointgen.next();
如果(完成)返回;
如果(cntr++%16==0){
//使旧零件变亮,使最近的活动更可见
ctx.fillStyle=“rgba(255255,0.01)”;
ctx.fillRect(0,0,cw,ch);
ctx.fillStyle=“rgb(0,0,0)”;
}
ctx.fillRect(value.x*比例,value.y*比例,比例,比例);
setTimeout(func,0);
}
func();
});
module={};

您的目标不明确。是否要列出(或生成器)所有栅格点,这些栅格点与给定点的距离不断增加?在上市期间,距离必须增加还是可以稍微减少?将“螺旋”模式从给定点移开有什么问题吗?这些点在垂直和水平段中移开,但基本模式离给定点越远?(这最后一个很容易编程,似乎对大多数搜索都足够了。)我想这就是你真正想要的。