2013-02-05 121 views
2

我想旋轉畫布上的N面多邊形,並且出現座標問題。這些形狀似乎圍繞着自身之外的原點旋轉(我希望原點是形狀的中心)。 任何提示將不勝感激。在HTML畫布上旋轉多邊形

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

什麼是ELEM?我是否正確理解這是一個畫布上下文? – begemotv2718

+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); 
} 
+0

這個工程,除了你只繪製'sides-1'邊。你需要去'k

+0

@JeffB是的。但我認爲elem.closePath()會被調用。我相信最初的代碼就是這樣的。 – begemotv2718

+0

啊,有道理。 –

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);
<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>