我正在尝试在画布上旋转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);
}
答案 0 :(得分:1)
嗯,第一个解决方案,有点像黑客,将是以下内容:向形状对象添加参数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);
}
答案 1 :(得分:0)
我整理了几个函数来旋转正多边形。第一步是生成一个完全与<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);
&#13;
<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>
&#13;