Drawing Rotated Triangles

Drawing a rotating triangle

You can just draw the triangle always with the same path, but before drawing the path rotate the canvas to the desired rotation angle.

canvas.save();
canvas.rotate(degrees);
//draw your triangle here
canvas.restore();

There is also a

canvas.rotate(degrees, x, y);

if you need to give it a pivot point.

Rotating triangle around a center point like a wheel

Use the matrix transformations to rotate, scale and translate an shape. The Operations rotate, scale and translate define a new transformation matrix and multiply the current matrix with the new matrix.

If you want to transform a single shape (triangle), you nee to save current matrix before the transformation with push and restore the matrix after the transformation with pop.

push();

// [...] scale, rotate, translate

// [...] draw shape

pop();

If you want to rotate a shape about a local pivot point, you need to draw the shape around (0, 0). Rotate the shape and move the rotated shape to its target position:

shapeTrasformation = translate * rotate * scale

Local rotation of an equilateral triangle:

push()

translate(this.x, this.y, this.z);
rotate(this.angle)
scale(30);

triangle(-0.866, 0.5, 0.866, 0.5, 0, -1);

pop();
this.angle += 0.01;

let triangle1;
let speedX;
let speedY;
let startColor;
let endColor;
let amt = 0;

function setup() {
startColor = color("hsl(144, 100%, 61%)");
endColor = color("hsl(0,77%,36%)");
createCanvas(windowWidth, windowHeight);
//creer notre triangle
triangle1 = new Triangles(200, 100, 0, 4);
}

function draw() {
colorMode(RGB);
background(252, 238, 10);
triangle1.show();
triangle1.move();
}

class Triangles {
//configuration de l'objet
constructor(triX, triY, speedX, speedY) {
this.x = triX;
this.y = triY;
this.speedX = speedX;
this.speedY = speedY;
this.angle = 0;
}

show() {
if (amt >= 1) {
amt = 0;
let tmpColor = startColor;
startColor = endColor;
endColor = tmpColor;
}
amt += 0.03;
let colorTransition = lerpColor(startColor, endColor, amt);
noStroke();
fill(colorTransition);

push()

translate(this.x, this.y, this.z);
rotate(this.angle)
scale(30);

triangle(-0.866, 0.5, 0.866, 0.5, 0, -1);

pop();
this.angle += 0.01;
}

move() {
this.x += this.speedX;
this.y += this.speedY;

if (this.x > width || this.x < 0) {
this.speedX *= -1;
}

if (this.x + 25 > width || this.x + 25 < 0) {

this.speedX *= -1;

}

if (this.x - 25 > width || this.x - 25 < 0) {

this.speedX *= -1;

}

if (this.y > height || this.y < 0) {

this.speedY = this.speedY * -1;

}

if (this.y + 40 > height || this.y + 40 < 0) {

this.speedY = this.speedY * -1;
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.min.js"></script>

How do I get the bottom-right X & Y of a rotated triangle

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>

Rotate triangle around circle (2D)

I just edited the code you linked and replaced the rectangle with a triangle, and animate() with a mouse move listener, of course:

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var cx = 100;
var cy = 100;
var radious = 10;
var gap = 5;
var triangleHeight = 25;
var triangleBase = 10;
redraw(cx + 1, cy);

function redraw(mx, my)
{
mox = mx-cx;
moy = my-cy;
rotation = Math.atan2(moy, mox);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.arc(cx, cy, radious, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
ctx.save();
ctx.translate(cx, cy);
ctx.rotate(rotation);
ctx.beginPath();
ctx.moveTo(radious+gap, -triangleBase/2);
ctx.lineTo(radious+gap, triangleBase/2);
ctx.lineTo(radious+gap+triangleHeight, 0);
ctx.lineTo(radious+gap, -triangleBase/2)
ctx.stroke();
ctx.restore();

}

canvas.addEventListener("mousemove", function (e) {
redraw(e.pageX, e.pageY);
}, false);
<canvas id="canvas"></canvas>

Rotate individual triangles on javascript canvas

One approach is to create a Slice class and move the paint functions into this class. Now you create for each slice a Slice object/instance (new Slice(...)) which you can style separately (slices[0].setColor('red')). See the snippet below.

I'd suggest to improve the sample below by creating slices with identical coordinates and rotating the slice at it's correct position by a ctx.rotate.

    var Slice = function(Xcenter, Ycenter, size, number, numberOfSides) {        this.scale = 1.0;        this.color = 'blue';        this.pos = [];        this.pos.push({x:Xcenter, y:Ycenter});        this.pos.push({            x:Xcenter + size * Math.cos((number+1) * 2 * Math.PI / numberOfSides),            y:Ycenter + size * Math.sin((number+1) * 2 * Math.PI / numberOfSides)        });        this.pos.push({            x: Xcenter + size * Math.cos(number * 2 * Math.PI / numberOfSides),            y: Ycenter + size * Math.sin(number * 2 * Math.PI / numberOfSides)        });    };    Slice.prototype.setScale = function(scale) {        this.scale = scale;    };    Slice.prototype.setColor = function(color) {        this.color = color;    };    Slice.prototype.draw = function(ctx) {        ctx.save();        ctx.scale(this.scale,this.scale);        ctx.beginPath();        for (var i=0; i<this.pos.length; i++) {            ctx.lineTo(this.pos[i].x, this.pos[i].y);        }        ctx.closePath();        ctx.fillStyle = this.color;        ctx.fill();        ctx.stroke();        ctx.restore();    };
function ready() {
var canvas=document.getElementById("myCanvas"); var ctx=canvas.getContext("2d");
var numberOfSides = 6, size = 100, Xcenter = 0, Ycenter = 0, prevX, prevY, startPX, startPY, angle = 0.1, angleChange=Math.PI/180;
var slices = []; for (var i = 1; i <= numberOfSides;i += 1) { slices.push(new Slice(Xcenter, Ycenter, size, i, numberOfSides)); } slices[0].setScale(0.9); slices[0].setColor('red');
requestAnimationFrame(animate);
function animate(time){ requestAnimationFrame(animate); ctx.clearRect(0,0,canvas.width,canvas.height); ctx.save();
// translate and rotate the canvas ctx.translate(canvas.width/2,canvas.height/2); ctx.rotate(angle); for (var i = 1; i <= numberOfSides;i += 1) { slices[i-1].draw(ctx); }
// restore the context to its untranslated & unrotated state ctx.restore(); angle+=angleChange; } ctx.closePath(); ctx.strokeStyle = "#ffffff"; ctx.lineWidth = 1; ctx.stroke(); }
<body onload="ready();"><canvas id="myCanvas" width="300" height="300" style="border:1px solid #d3d3d3;"></canvas></body>


Related Topics



Leave a reply



Submit