Reputation: 1258
I have a square whose vertex positions (when the origin is the center of the canvas) are given below:
let canvasCenter = [canvas.width / 2, canvas.height / 2],
halfSize = this.size / 2,
vertexPositions = [
[halfSize, halfSize],
[-halfSize, halfSize],
[halfSize, -halfSize],
[-halfSize, -halfSize],
];
Of course, it's trivial for me to draw, for example, a circle at each of the vertices when the coordinate system is rotated. I just call the native transform functions:
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]);
However, I don't just want to draw the vertices. I also want to calculate the new positions of the vertices on the canvas when each is rotated and translated (for example, to tell whether they are within the bounds of the canvas). I've tried using the standard formula, as below, but when I draw those vertices, it gives me a skewed shape, not a rotated square, so there is obviously something wrong with my calculation:
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];
}
Please can you help me to calculate the correct vertices (after rotation and translation).
Upvotes: 0
Views: 79
Reputation: 54041
Cause
v[1] = v[1] * cos - v[0] * sin;
v[0] = v[1] * sin + v[0] * cos;
You change v[1]
on the first line and then using it on the second line. Thus you use the transformed V[1]
to find the transformed v[0]
which is incorrect.
Solution is separate the variables.
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];
I called them a
,b
as I am unsure why you have v[1]
in the x coordinate and v[0]
in the y. The standard transform is
const x1 = x * cos - y * sin;
const y1 = x * sin + y * cos;
x = x1 + canvasCenter[0];
y = y1 + canvasCenter[1];
Upvotes: 3