如何在不使用 `context.rotate` 的情况下在七巧板游戏中旋转形状

How to rotate the shapes in a tangram game without using `context.rotate`

在canvas 600 * 600 三角形的三个点是 (100, 100), (300, 100), (200,200) 旋转中心是 (200, 100)

我想实现拖动三角形旋转。但我不知道如何改变这些点的坐标。

ps:我已经知道怎么计算旋转角度了 var rotateRadian = Math.atan2(mouseY - center.y, mouseX - center.x) - Math.atan2(startDragPosition.y - center.y, startDragPosition.x - center.x);

[来自下方评论的附加信息]

我想拼七巧板,有长方形、三角形、平行四边形

你有一个好的开始!

首先计算mouse-to-centerpoint角度:

// calc mouse angle
var dx=mouseX-centerX;
var dy=mouseY-centerY;
radianAngle=Math.atan2(dy,dx);

因为你有一个等边三角形,所以你的三角形是一个正多边形。使用三角函数计算多边形的 3 个旋转点:

// vertex#1
var x1=cx+radius*Math.cos(rotationAngle);
var y1=cy+radius*Math.sin(rotationAngle);

// vertex#2
rotationAngle+=PI2/3;
var x2=cx+radius*Math.cos(rotationAngle);
var y2=cy+radius*Math.sin(rotationAngle);

// vertex#3
rotationAngle+=PI2/3;
var x3=cx+radius*Math.cos(rotationAngle);
var y3=cy+radius*Math.sin(rotationAngle);

然后只需监听 mousemove 事件并相应地重绘三角形:

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var $canvas=$("#canvas");
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var scrollX=$canvas.scrollLeft();
var scrollY=$canvas.scrollTop();
ctx.fillStyle='red';
ctx.strokeStyle='blue';
ctx.lineWidth=2;

var isDown=false;
var startX;
var startY;

var PI2=Math.PI*2;
var cx=150;
var cy=150;
var sideLength=50;
var originalAngle=0;
var radius=sideLength*Math.sqrt(3)/3;

draw(200,200);

$("#canvas").mousemove(function(e){handleMouseMove(e);});


function draw(mx,my){

  //
  var dx=mx-cx;
  var dy=my-cy;
  var currentAngle=Math.atan2(dy,dx);
  var rotationAngle=currentAngle-originalAngle;
  // vertex#1
  var x1=cx+radius*Math.cos(rotationAngle);
  var y1=cy+radius*Math.sin(rotationAngle);
  // vertex#2
  rotationAngle+=PI2/3;
  var x2=cx+radius*Math.cos(rotationAngle);
  var y2=cy+radius*Math.sin(rotationAngle);
  // vertex#3
  rotationAngle+=PI2/3;
  var x3=cx+radius*Math.cos(rotationAngle);
  var y3=cy+radius*Math.sin(rotationAngle);

  ctx.clearRect(0,0,cw,ch);
  ctx.beginPath();
  ctx.moveTo(x1,y1);
  ctx.lineTo(x2,y2);
  ctx.lineTo(x3,y3);
  ctx.closePath();
  ctx.stroke();

  ctx.beginPath();
  ctx.arc(x1,y1,3,0,PI2);
  ctx.closePath();
  ctx.fill();

}


function handleMouseMove(e){
  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();

  mx=parseInt(e.clientX-offsetX);
  my=parseInt(e.clientY-offsetY);

  draw(mx,my);

}
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>The triangle will rotate according to the mouse</h4>
<canvas id="canvas" width=300 height=300></canvas>

[根据提问者评论添加]

数学原理类似,但更复杂,因为七巧板的形状不规则。

对于每个形状,您需要:

找到形状的质心,这是它的旋转中心

cx=average of all x vertices. 
cy=average of all y vertices.

求形状的 3 或 4 个径向长度

// for each radius
radial length=Math.sqrt(Math.pow(vx-cx,2)+Math.pow(vy-cy,2))

求形状的 3 或 4 个径向角

// for each radius
radial angle=Math.atan2(Math.pow(vy-cy,2),Math.pow(vx-cx,2))

现在在我的答案中使用相同的三角函数来围绕质心旋转顶点