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
Reading Every Nth Frame from Videocapture in Opencv
What Is a Lambda Expression in C++11
How to Detect Unsigned Integer Overflow
Meaning of 'Const' Last in a Function Declaration of a Class
How to Create a Contiguous 2D Array in C++
In Which Scenario Do I Use a Particular Stl Container
C++ Preprocessor _Va_Args_ Number of Arguments
Finding Version of Microsoft C++ Compiler from Command-Line (For Makefiles)
Countdown Until Matching Digits
Where Do I Find the Current C or C++ Standard Documents
How to Pass Objects to Functions in C++
Read Whole Ascii File into C++ Std::String
Array Index Out of Bound Behavior
Raii and Smart Pointers in C++
What Will Happen When I Call a Member Function on a Null Object Pointer