在不调用本机变换函数的情况下旋转 canvas 上的点
Rotate points on canvas without calling native transform functions
我有一个正方形,其顶点位置(当原点是 canvas 的中心时)如下所示:
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]);
但是,我不只是想绘制顶点。我还想计算每个顶点在 canvas 上旋转和平移时的新位置(例如,判断它们是否在 canvas 的范围内)。我试过使用标准公式,如下所示,但是当我绘制这些顶点时,它给了我一个倾斜的形状,而不是一个旋转的正方形,所以我的计算显然有问题:
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];
}
请你帮我计算正确的顶点(旋转和平移后)。
原因
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];
我有一个正方形,其顶点位置(当原点是 canvas 的中心时)如下所示:
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]);
但是,我不只是想绘制顶点。我还想计算每个顶点在 canvas 上旋转和平移时的新位置(例如,判断它们是否在 canvas 的范围内)。我试过使用标准公式,如下所示,但是当我绘制这些顶点时,它给了我一个倾斜的形状,而不是一个旋转的正方形,所以我的计算显然有问题:
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];
}
请你帮我计算正确的顶点(旋转和平移后)。
原因
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];