我正在开发一个基于三 Angular 形图案的 Canvas 项目,但我遇到了旋转问题。我想生成 6 个相同的三 Angular 形,然后通过边将它们连接在一起。到目前为止,我已经计算了旋转所需的 Angular 并生成了三 Angular 形。
我正在使用此处描述的旋转矩阵公式:HTML5 Canvas: Calculating a x,y point when rotated 除了值有点偏离之外,它几乎可以工作。
x = (200-cX) * Math.cos(sAngle*radians) - (150-cY) * Math.sin(sAngle*radians) + cX;
y = (200-cX) * Math.sin(sAngle*radians) + (150-cY) * Math.cos(sAngle*radians) + cY
这是迄今为止我的代码:https://jsfiddle.net/bdrmm5n3/
我之前也几乎通过将距离更改为 100 并稍微修改中心来实现此工作,但图案中存在间隙。
https://jsfiddle.net/7cezjnjo/
我猜形状旋转后我的旋转中心值是错误的,但我不知道如何纠正这个问题。
感谢您的帮助。
最佳答案
你的三 Angular 形配置形成一个正多边形。
要计算正多边形的中心点(==旋转点),您需要:
- 起始侧点 (p0),
- 结束侧点 (p1),
- 边数(sidecount)
您可以这样计算中心点:
关于此插图:
- 蓝点是已知的中心点(计算出的中心点要命中的目标)
- 给定边上的金色线段,
- 给定线段中点的紫色点
- 与中点成 90 度 Angular 的绿色边心线段
- 计算中心点末尾的红点
function getCenter(sidecount,p0,p1){
var dx=p1.x-p0.x;
var dy=p1.y-p0.y;
var sidelength=Math.sqrt(dx*dx+dy*dy);
var sideangle=Math.atan2(dy,dx);
var apothemAngle=sideangle+PI/2;
var apothem=sidelength/(2*Math.tan(deg2rad(180/sidecount)));
var midX=(p0.x+p1.x)/2;
var midY=(p0.y+p1.y)/2;
var cx=midX+apothem*Math.cos(apothemAngle);
var cy=midY+apothem*Math.sin(apothemAngle);
return({x:cx,y:cy});
}
这里是示例代码和演示
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
// testing: get the vertices of a regular polygon
var points=regularPolygonPoints(cw/2,ch/2,7,75);
// draw the polygon
drawPoints(points,5,'black');
// draw a dot at the actual centerpoint of the polygon
// (we want to hit this centerpoint with our getCenter() function)
dot(cw/2,ch/2,'blue',8);
// some utilities
var PI=Math.PI;
var deg2rad=function(d){return(d*PI/180);}
// Given sidecount and starting+ending points of one side
var sidecount=7;
var p0=points[0];
var p1=points[1];
// ask getCenter to calc the centerpoint
var center=getCenter(sidecount,p0,p1);
//
function getCenter(sidecount,p0,p1){
var dx=p1.x-p0.x;
var dy=p1.y-p0.y;
var sidelength=Math.sqrt(dx*dx+dy*dy);
var sideangle=Math.atan2(dy,dx);
var apothemAngle=sideangle+PI/2;
var apothem=sidelength/(2*Math.tan(deg2rad(180/sidecount)));
var midX=(p0.x+p1.x)/2;
var midY=(p0.y+p1.y)/2;
var cx=midX+apothem*Math.cos(apothemAngle);
var cy=midY+apothem*Math.sin(apothemAngle);
// testing
// draw a gold line segment over the given side
// draw a purple dot at the given segment's midpoint
// draw a green apothem line segment at 90 degrees from the midpoint
// draw a red dot at the end of the apothem (==centerpoint)
//
// side line segment from p0 to p1
ctx.beginPath();
ctx.moveTo(p0.x,p0.y);
ctx.lineTo(p1.x,p1.y);
ctx.lineWidth=3;
ctx.strokeStyle='gold';
ctx.stroke();
// midpoint
dot(midX,midY,'purple',7);
// apothem line segment
ctx.beginPath();
ctx.moveTo(midX,midY);
ctx.lineTo(cx,cy);
ctx.lineWidth=3;
ctx.strokeStyle='green';
ctx.stroke();
// calculated centerpoint
dot(cx,cy,'red',4);
// return the centerpoint
return({x:cx,y:cy});
}
function dot(x,y,color,r){
ctx.beginPath();
ctx.arc(x,y,r,0,Math.PI*2);
ctx.closePath();
ctx.fillStyle=color;
ctx.fill();
}
function drawPoints(points,linewidth,strokestyle){
ctx.beginPath();
ctx.moveTo(points[0].x,points[0].y);
for(var i=1;i<points.length;i++){
ctx.lineTo(points[i].x,points[i].y);
}
ctx.closePath();
ctx.lineWidth=linewidth
ctx.strokeStyle=strokestyle;
ctx.stroke();
}
function regularPolygonPoints(cx,cy,sideCount,radius){
var sweep=Math.PI*2/sideCount;
var points=[];
for(var i=0;i<sideCount;i++){
var x=cx+radius*Math.cos(i*sweep);
var y=cy+radius*Math.sin(i*sweep);
points.push({x:x,y:y});
}
return(points);
}
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<h4>Draw a gold line segment over the given side
<br>Draw a purple dot at the given segment's midpoint
<br>Draw a green apothem line segment at 90 degrees from the midpoint
<br>Draw a red dot at the end of the apothem (==centerpoint)
</h4>
<canvas id="canvas" width=300 height=300></canvas>
关于javascript - HTML5 Canvas 计算旋转点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30423379/