2

我正在尝试在画布上旋转 N 面多边形,但我遇到了坐标问题。这些形状似乎围绕着一个位于它们自身之外的原点旋转(我希望原点成为形状的中心)。任何提示将不胜感激。

var x = 50;
var y = 50;
var tranx;
var trany;

x -= tranx = x + shape.radius;
y -= trany = y + shape.radius;

elem.translate(tranx,trany);
elem.rotate(90 * radian);

var k = 0,
angle = 360/shape.sides;

elem.moveTo(x,y);

for (; k <shape.sides; k++) {
    elem.lineTo(x+=Math.cos( ( angle * k )* radian) * shape.radius, y+=Math.sin( ( angle * k )* radian) * shape.radius);
}
4

2 回答 2

2

我组合了几个函数来旋转正多边形。第一步是生成一个<canvas>完全独立的 (x, y) 坐标列表。需要注意的是,要获得相移(最终会导致多边形旋转),您必须将旋转添加到余弦和正弦函数中的语句中:

Math.cos(rotation + (i * 2 * Math.PI / numberOfSides))
Math.sin(rotation + (i * 2 * Math.PI / numberOfSides))

这是一个使用正多边形生成画布并围绕其自身原点旋转多边形的工作示例:

var canvas = document.querySelector('canvas');
var polygon = {
  sides: 3,
  radius: 50,
  phase: 0
};

document.addEventListener('click', function(e) {
  switch (e.target.id) {
    case "-side":
      polygon.sides--;
      break;
    case "+side":
      polygon.sides++;
      break;
    case "-phase":
      polygon.phase -= Math.PI / 12;
      break;
    case "+phase":
      polygon.phase += Math.PI / 12;
      break;
  }

  drawPolygon(canvas, polygon.sides, polygon.radius, polygon.phase);
});

function generateCoordinates(centerX, centerY, numberOfSides, radius, rotation) {
  var coordinates = [];
  for (var i = 0; i < numberOfSides; i++) {
    coordinates.push({
      x: parseFloat((centerX + radius * Math.cos(rotation + (i * 2 * Math.PI / numberOfSides))).toFixed(4)),
      y: parseFloat((centerY + radius * Math.sin(rotation + (i * 2 * Math.PI / numberOfSides))).toFixed(4))
    })
  }
  return coordinates;
};

function drawPolygon(canvas, numberOfSides, radius, rotation) {
  var context = canvas.getContext('2d');
  canvas.height = radius * 2;
  canvas.width = radius * 2;

  var coordinates = generateCoordinates(radius, radius, numberOfSides, radius, rotation);

  context.strokeStyle = "black";
  context.beginPath();

  coordinates.forEach(function(coordinate, index) {
    if (index === 0) {
      context.moveTo(coordinate.x, coordinate.y);
    } else {
      context.lineTo(coordinate.x, coordinate.y);
    }
  });
  context.closePath();
  context.stroke();
}

drawPolygon(canvas, polygon.sides, polygon.radius, polygon.phase);
<canvas></canvas>

<div>
  <button id="-side">fewer sides</button>
  <button id="+side">more sides</button>
</div>

<div>
  <button id="-phase">minus phase shift</button>
  <button id="+phase">plus phase shift</button>
</div>

于 2017-01-16T23:24:16.577 回答
1

嗯,第一个解决方案,有点 hack,如下:将参数 rotation_angle 添加到形状对象。然后你的循环应该以下列方式改变:

k=0;
elem.moveTo(
     x+=Math.cos( ( angle * k +shape.rotation_angle)* radian) * shape.radius,
     y+=Math.sin( ( angle * k +shape.rotation_angle)* radian) * shape.radius);
for(k=1;k<shape.sides;k++){
     elem.lineTo(
          x+=Math.cos( ( angle * k +shape.rotation_angle)* radian) * shape.radius,
          y+=Math.sin( ( angle * k +shape.rotation_angle)* radian) * shape.radius);
}

第二种解决方案依赖于假设 elem 是画布上下文并且多边形的中心应该在坐标 (x,y) 处。

那么我猜,正确的顺序如下:

elem.translate(x,y); //Translate the origin to the center of polygon.
elem.rotate(rotation_angle); // Rotate the context around the origin
var k=0;
elem.moveTo(shape.radius,0);
for(k=1;k<shape.sides;k++){
   elem.lineTo(Math.cos(k*angle*radian)*shape.radius,
               Math.sin(k*angle*radian)*shape.radius);
}
于 2013-02-05T17:53:29.817 回答