在画布上旋转点而不调用本机变换函数

时间:2017-10-06 12:46:35

标签: javascript html5-canvas transform trigonometry

我有一个正方形,它的顶点位置(当原点是画布的中心时)如下所示:

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];
}

请帮我计算正确的顶点(旋转和平移后)。

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];

我打电话给他们ab因为我不确定你为什么在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];