装满圆形区域二维数组 [英] Fill a 2d Array with circular area

查看:287
本文介绍了装满圆形区域二维数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想一个数组看起来像这样:

  [
[0,0,1,1,1,0,0]
[0,1,1,1,1,1,0]
[1,1,1,1,1,1,1]
[1,1,1,1,1,1,1]
[1,1,1,1,1,1,1]
[0,1,1,1,1,1,0]
[0,0,1,1,1,0,0]
]

我的第一个办法是让周长

  VAR步骤= 100;
变种坐标= [];
VAR的x,y;
对于(VAR I = 0; I<步骤;我++){
    VAR阶段= 2 * Math.PI * I /步骤;
    X = Math.round(CENX +范围* Math.cos(相位));
    Y = Math.round(ceny +范围* Math.sin(相位))    如果(X GT; = 0&放大器;&放大器y与其所连接; = 0){
        coord.push([X,Y]);
    }
}

和用所得COORDS我可以有篡改周围以获得圆形区域。但我怀疑这将是高性能的。

所以,我的第二个方法是检查数组是否有一定的距离(即半径)到我的圆心的每个条目。但对于庞大的地图,不会是高性能无论是。也许只有在检查一个合理的框架将是明智。

但即时通讯一定有这种问题的一个更好的办法。
IM需要这个战争实现的雾。


解决方案

我会使用中点圈算法,看到了数组作为位图。

我这样做的JavaScript实现而回,在这里修改为使用数组作为目标源的像素。只要注意一个圈将产生奇怪的宽度和高度为距离总是从一个单一的中心点,我们只能在这种情况下使用的整数值。

提示:为了提高速度,你可以使用类型数组,而不是常规的一(如下图所示)

示例

请确保使用整数值作为输入,code将夹位图之外的值/阵列 -

\r
\r

VAR WIDTH = 7,高度= 7,\r
    阵列=新Ui​​nt8Array(宽*高);\r
\r
//画圈到数组\r
圈(3,3,3);\r
renderDOM();\r
\r
//圈例如2\r
宽度=身高= 17;\r
阵列=新Ui​​nt8Array(宽*高);\r
\r
圈(8,8,8);\r
renderDOM();\r
\r
功能圈(XC,YC,R){\r
  如果(R< 1)返回;\r
\r
  变种x = R,Y = 0,//用于布氏/中点圆\r
      CD = 0,\r
      XOFF = 0,\r
      YOFF = R,\r
      B = -r,\r
      P0,P1,W0,W1;\r
\r
  而(XOFF< = YOFF){\r
    P0 = XC - XOFF;\r
    P1 = XC - YOFF;\r
    W0 = XOFF + XOFF;\r
    W1 = YOFF + YOFF;\r
\r
    HL(P0,YC - YOFF,YC + YOFF,W0); //一补行\r
    百升(P1,YC - XOFF,YC + XOFF,W1);\r
\r
    如果((B + = XOFF +++ XOFF)> = 0){\r
      b - = --yoff + YOFF;\r
    }\r
  }\r
\r
  //为填充\r
  函数HL(X,Y1,Y2,w)的{\r
    W¯¯++;\r
    变种XW = 0;\r
    而(w--){\r
      XW = X + W;\r
      与setPixel(XW,Y1);\r
      与setPixel(XW,Y2);\r
    }\r
  }\r
\r
  函数与setPixel(X,Y){\r
如果(X LT;宽度放大器;&放大器; Y&下;高度&放大器;&放大器; X> = 0&放大器;&放大器y与其所连接; = 0)\r
数组[Y *宽+ X] = 1;\r
  }\r
}\r
\r
功能renderDOM(){\r
  对于(VAR I = 0,海峡=; I< array.length,我++){\r
    如果(ⅰ大于0&放大器;&放大器;!(ⅰ%的宽度))STR + =&所述峰; br>中;\r
    STR + =阵列[我]\r
  }\r
  document.body.innerHTML + = STR +< BR>< BR>中;\r
}

\r

{体字体:18像素等宽}

\r

\r
\r

I want an array looking like this:

[
[0,0,1,1,1,0,0],
[0,1,1,1,1,1,0],
[1,1,1,1,1,1,1],
[1,1,1,1,1,1,1],
[1,1,1,1,1,1,1],
[0,1,1,1,1,1,0],
[0,0,1,1,1,0,0],
]

My first approach was to get the circumference

var steps = 100;
var coord = [];
var x,y;
for (var i = 0; i < steps; i++) {
    var phase = 2 * Math.PI * i / steps;
    x = Math.round(cenx + range * Math.cos(phase));
    y = Math.round(ceny + range * Math.sin(phase))

    if(x>=0 && y >=0){
        coord.push([x,y]);
    }
}

and with the resulting coords i could have juggled around to get the circular area. but i doubt that would be performant.

So my second approach would be to check every entry of the array whether it has a certain distance (i.e. radius) to the center of my circle. but for huge maps that wouldnt be performant either. perhaps checking only in a reasonable frame would be wiser.

but im certain there is a better approach for this problem. im needing this for a fog of war implementation.

解决方案

I would use the mid-point circle algorithm and see the array as a bitmap.

I did this JavaScript implementation a while back, modified here to use an array as target source for the "pixel". Just note that a circle will produce odd widths and heights as the distance is always from a single center point and we can only use integer values in this case.

Tip: For speed improvements you could use typed array instead of a regular one (shown below).

Example

Make sure to use integer values as input, the code will clip values outside the "bitmap"/array -

var width = 7, height = 7,
    array = new Uint8Array(width * height);

// "draw" circle into array
circle(3, 3, 3);
renderDOM();

// circle example 2
width = height = 17;
array = new Uint8Array(width * height);

circle(8, 8, 8);
renderDOM();

function circle(xc, yc, r) {
  if (r < 1) return;

  var x = r, y = 0,  // for Bresenham / mid-point circle
      cd = 0,
      xoff = 0,
      yoff = r,
      b = -r,
      p0, p1, w0, w1;

  while (xoff <= yoff) {
    p0 = xc - xoff;
    p1 = xc - yoff;
    w0 = xoff + xoff;
    w1 = yoff + yoff;

    hl(p0, yc - yoff, yc + yoff, w0);  // fill a "line"
    hl(p1, yc - xoff, yc + xoff, w1);

    if ((b += xoff+++xoff) >= 0) {
      b -= --yoff + yoff;
    }
  }

  // for fill
  function hl(x, y1, y2, w) {
    w++;
    var xw = 0;
    while (w--) {
      xw = x + w;
      setPixel(xw, y1);
      setPixel(xw, y2);
    }
  }

  function setPixel(x, y) {
	if (x < width && y < height && x >= 0 && y >= 0)
		array[y * width + x] = 1;
  }
}

function renderDOM() {
  for(var i = 0, str = ""; i < array.length; i++) {
    if (i > 0 && !(i % width)) str += "<br>";
    str += array[i];
  }
  document.body.innerHTML += str + "<br><br>";
}

body {font:18px monospace}

这篇关于装满圆形区域二维数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆