1

関連する live-javascript/jsbin: http://jsbin.com/ekuyam/2/edit

基本的には、キャンバスの中心を基準にして六角形に点を生成し、六角形の各点に円を描くだけですが、よく見ると円が正しく整列していません。ただし、大きな円を使用しない限り、実際には見えません。

小さな円を使用すると、次のように、キャンバス上にかなり正確に配置されているように見えます。 ここに画像の説明を入力

しかし、大きな円を使用して (ズームインのようなもので) 詳しく調べると、ここにある不要なスペース/領域からわかるように、数学に不正確さがあることが明らかになりました。 ここに画像の説明を入力

行は完全に整列するはずですが、代わりに不要なスペースができます。これはなぜですか、どうすれば修正できますか?

コード:

function hexagon(w, h, p) {
  var points = 6;
  var width = w;
  var height = h;
  var angle = ((2 * Math.PI) / points);
  var hexagon = [];

  for (i = 0; i < points; i++) {
    hexagon.push({
      x: width * Math.sin(angle * i) + p.x, 
      y: height * Math.cos(angle * i) + p.y
    })
  }

  return hexagon
}

var stage = new Kinetic.Stage({
  container: "container",
  width: 600,
  height: 600
});

var layer = new Kinetic.Layer();
var group = new Kinetic.Group({x: 600/2, y: 600/2, draggable: false});

var radius = 1000;
var s = new Kinetic.Circle({
  radius: radius,
  stroke: 'black',
  strokeWidth: 1,
  draggable: true
});
group.add(s);

var hex_points = hexagon(radius, radius, {x: 600/2, y: 600/2});
for (p in hex_points) {
  var s = new Kinetic.Circle({
    radius: radius,
    stroke: 'black',
    strokeWidth: 1,
    draggable: true
  });
  s.setPosition({x: hex_points[p].x - 600/2, y: hex_points[p].y - 600/2})
  group.add(s);
}

layer.add(group);
stage.add(layer);
4

2 に答える 2

2

これは、sin(2 * Math.PI) / 6 = sqrt(3)/2 が無理数であるためです。ただし、float は有理数しか表すことができません (実際には、分母が 2 のべき乗である場合のみ)。したがって、常に丸め誤差が発生します。円を十分に拡大すると、この丸め誤差が表示されます。これを防ぐには、倍率を制限する必要があります。

絶対に回避する必要がある場合、最も簡単な方法は、より高い算術精度を使用することです。

別のアプローチは、式 (x-x_0)^2 + (y-y_0)^2 = R^2 を使用し、三角関数を使用せずに既知の交点の周りで局所的に解くことです。より具体的には、関数 f(x,y):= (x-x_0)^2+(y-y_0)^2 は、x=x_0 と y=y_0 を除くすべての場所で逆関数定理の条件を満たします。円の例は、陰関数定理に関するウィキペディアの別の記事に含まれていることに注意してください。手元の例は正則関数であるため、局所逆関数も正則関数になります。特にテイラー級数展開による局所近似が良い。. このアプローチのポイントは、中心の周りに円を描くのではなく、「目的の交点を通って」描くことです。したがって、この点を「交差」させることができます。ただし、float は sqrt(3) またはその有理倍数を適切に表すことはないため、「交点」は近似にすぎないことに注意してください。

今何をすべきか?私がすること: 画面上に交点が 1 つしかないような倍率になったら、R^2 = (x_i-x_0)^2+(y_i-y_0)^2 (x_i , y_i) は目的の交点であり、「(x_0,y_0)」は円の中心です。次に、標準の円の公式に進みます。

非常に簡単な方法は、円の線もスケーリングされるようにすることです。したがって、高倍率の場合、不正確さは円の「厚い」周囲の下に隠されます。

于 2013-04-17T06:11:34.060 に答える