I am trying to create a triangle that can rotate between 0° - 360° using JavaScript and then draw this to a canvas.
The origin of the triangle is 1/2 height and 1/2 width (so in the center). The triangle will rotate relative to the origin.
I have worked out the position of point A (top of the triangle) from the origin (center of the triangle) using the following code
let aX = Math.cos(radians) * origin.x - Math.sin(radians) * origin.y;
let aY = Math.sin(radians) * origin.x + Math.cos(radians) * origin.y;
Now, I need to find the x & y position of point B (bottom right of triangle).
The information I have to work with is:
How can I find the x & y position of point B taking into consideration the angle to rotate?
I have tried
let bX = Math.cos(radians) * Width/2 + Math.sin(radians) * Height/2;
let bY = Math.sin(radians) * Width/2 - Math.cos(radians) * Height/2;
but this returned
*note ignore the inverted angle
If you are going to use canvas I would recommend using getTransform()
which returns the transform matrix that you can use to update you vertices. Here is a snippet showing the updated vertices while the triangle is being rotated.
As you'll see in this snippet I first calculate my centroid using the passed in values. Then I can subtract that amount from each vertex in order to get the transform origin to the center of the triangle.
To move the triangle around use this.translate()
. You could also pass in those values as an argument. Using setTransform()
we can pass in the rotation value and translate amounts and assigning getTransform()
to a variable allows us to pass that to a function that will calculate the new vertex position.
let canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d");
canvas.width = 400;
canvas.height = 400;
class Triangle {
constructor(ptA, ptB, ptC) {
this.ptA = ptA;
this.ptB = ptB;
this.ptC = ptC;
this.translate = {x: 155, y: 100 };
this.centroid = {
ox: (this.ptA.x + this.ptB.x + this.ptC.x) / 3,
oy: (this.ptA.y + this.ptB.y + this.ptC.y) / 3
};
this.c = "red";
this.a = 0;
this.rotation = this.a * (Math.PI / 180);
this.pts = [];
}
draw() {
let t;
this.a -= 0.5;
this.rotation = this.a * (Math.PI / 180);
const cos = Math.cos(this.rotation)
const sin = Math.sin(this.rotation)
ctx.save();
ctx.beginPath();
ctx.fillStyle = this.c;
ctx.setTransform(cos, sin, -sin, cos, this.translate.x, this.translate.y);
t = ctx.getTransform();
ctx.moveTo(this.ptA.x - this.centroid.ox, this.ptA.y - this.centroid.oy);
ctx.lineTo(this.ptB.x - this.centroid.ox, this.ptB.y - this.centroid.oy)
ctx.lineTo(this.ptC.x - this.centroid.ox, this.ptC.y - this.centroid.oy);
ctx.lineTo(this.ptA.x - this.centroid.ox, this.ptA.y - this.centroid.oy);
ctx.fill();
ctx.closePath();
ctx.restore();
this.updateVertices(t);
}
drawVertices() {
for (let i=0; i < this.pts.length; i++) {
ctx.beginPath();
ctx.fillStyle = "blue";
ctx.arc(this.pts[i].x, this.pts[i].y, 3, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
}
}
updateVertices(t) {
//Explanation:
//t is a variable for getTransform() passed in from draw() method.
//The 7th and 8th arguments are the original point of where the vertex is drawn for that point. The 9th and 10th arguments are how mush the shap has been translated by.
this.pts[0] = calcVertices(t.a, t.b, t.c, t.d, t.e, t.f, this.ptA.x - this.centroid.ox, this.ptA.y - this.centroid.oy, this.translate.x, this.translate.y)
this.pts[1] = calcVertices(t.a, t.b, t.c, t.d, t.e, t.f, this.ptB.x - this.centroid.ox, this.ptB.y - this.centroid.oy, this.translate.x, this.translate.y)
this.pts[2] = calcVertices(t.a, t.b, t.c, t.d, t.e, t.f, this.ptC.x - this.centroid.ox, this.ptC.y - this.centroid.oy, this.translate.x, this.translate.y)
}
}
let triangle = new Triangle({ x: 0, y: 0 }, { x: 50, y: 60 }, { x: 0, y: 100 })
function calcVertices(a, b, c, d, e, f, pX, pY, cx, cy) {
//pX and pY are the original vertex points
let x, y;
x = (e + pX - cx) * a + (f + pY - cy) * c + (e);
y = (e + pX - cx) * b + (f + pY - cy) * d + (f);
return {x: x, y: y}
}
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
triangle.draw();
triangle.drawVertices();
requestAnimationFrame(animate);
}
animate();
<canvas id="canvas"></canvas>