我有一个正方形,它的顶点位置(当原点是画布的中心时)如下所示:
let canvasCenter = [canvas.width / 2, canvas.height / 2],
halfSize = this.size / 2,
vertexPositions = [
[halfSize, halfSize],
[-halfSize, halfSize],
[halfSize, -halfSize],
[-halfSize, -halfSize],
];
当然,例如,当旋转坐标系时,在每个顶点处绘制一个圆圈是微不足道的。我只是调用原生变换函数:
context.translate(canvasCenter[0], canvasCenter[1]);
context.rotate(this.rotation);
for (let i = 0; i < 4; ++i) {
let v = vertexPositions[i];
context.beginPath();
context.arc(v[0], v[1], 10, 0, 2 * Math.PI);
context.fill();
}
context.rotate(-this.rotation);
context.translate(-canvasCenter[0], -canvasCenter[1]);
但是,我并不想绘制顶点。我还想计算每个旋转和平移时画布上顶点的新位置(例如,判断它们是否在画布的范围内)。我已尝试使用标准公式,如下所示,但是当我绘制这些顶点时,它会给我一个倾斜的形状,而不是旋转的方形,所以我的计算显然有问题:
let cos = Math.cos(this.rotation),
sin = Math.sin(this.rotation);
for (let i = 0; i < 4; ++i) {
let v = vertexPositions[i];
v[1] = v[1] * cos - v[0] * sin;
v[0] = v[1] * sin + v[0] * cos;
v[0] += canvasCenter[0];
v[1] += canvasCenter[1];
}
请帮我计算正确的顶点(旋转和平移后)。
答案 0 :(得分:3)
原因
v[1] = v[1] * cos - v[0] * sin;
v[0] = v[1] * sin + v[0] * cos;
您在第一行更改v[1]
,然后在第二行使用它。因此,您使用已转换的V[1]
来查找不正确的已转换v[0]
。
解决方案将变量分开。
const a = v[1] * cos - v[0] * sin;
const b = v[1] * sin + v[0] * cos;
v[0] = b + canvasCenter[0];
v[1] = a + canvasCenter[1];
我打电话给他们a
,b
因为我不确定你为什么在x坐标中有v[1]
而在y中有v[0]
。标准转换是
const x1 = x * cos - y * sin;
const y1 = x * sin + y * cos;
x = x1 + canvasCenter[0];
y = y1 + canvasCenter[1];