【问题标题】:HTML5 Canvas Calculating rotation pointHTML5 Canvas 计算旋转点
【发布时间】:2015-08-06 01:14:01
【问题描述】:

我正在开发一个基于三角形图案的画布项目,但我遇到了旋转问题。我想生成 6 个相同的三角形,然后将它们连接在一起。到目前为止,我已经计算了旋转和生成三角形所需的角度。

我正在使用此处描述的旋转矩阵公式: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/

我猜我的旋转中心值在形状旋转后是错误的,但我不知道如何纠正这个问题。

感谢您的帮助。

【问题讨论】:

  • 我已经通过计算点之间的差异并像jsfiddle.net/gwms568q 那样平移三角形来解决这个问题,尽管知道公式出错的地方仍然会有所帮助。

标签: javascript math rotation html5-canvas trigonometry


【解决方案1】:

您的三角形配置形成一个正多边形。

要计算您需要的正多边形的中心点(==旋转点):

  • 一个起始侧点(p0),
  • 结束侧点 (p1),
  • 边数(sidecount)

您可以这样计算中心点:

关于这幅插图:

  • 蓝点是已知中心点(计算出的中心点要命中的目标)
  • 给定边上的金线段,
  • 给定段中点的紫色点
  • 与中点成 90 度的绿色 apothem 线段
  • 计算出的中心点末端的红点

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>

【讨论】:

    猜你喜欢
    • 2012-02-14
    • 2019-05-29
    • 1970-01-01
    • 2022-01-10
    • 2012-02-27
    • 2019-04-06
    • 1970-01-01
    • 2011-06-06
    • 2012-10-14
    相关资源
    最近更新 更多