How to rotate a triangle without turning the entire canvas?

I am new to working with <canvas>and terrible at math. I draw a simple equilateral triangle on my canvas with this function, which takes the code from someone else (don't hate me):

drawTriangle(PosX, PosY, SideLength, Orientation) {
    context.beginPath();

    var sides = 3;

    var a = ((Math.PI * 2) / sides);

    context.moveTo(PosX + SideLength, PosY);

    for (var i = 1; i < sides + 1; i++) {
        context.lineTo(PosX + SideLength * Math.cos(a*i), PosY + SideLength * Math.sin(a*i));
    }

    context.closePath();

    return true;
}

The function will know only the central coordinates of the triangle and the orientation to indicate it, nothing more.

Currently, he draws a triangle successfully, but "points" to the east.

How to rotate a triangle using a parameter Orientation(in degrees) without rotating the entire canvas, as other answers suggest?

+4
source share
5 answers

, :

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

var sideCount=3;
var size=40;
var centerX=50;
var centerY=50;
var strokeWidth=4;
var strokeColor='purple';
var fillColor='skyblue';
var rotationDegrees=0;
var rotationIncrement=1;
var nextTime=0;
var delay=1000/60*1;

requestAnimationFrame(animate);

function animate(time){
    if(time<nextTime){requestAnimationFrame(animate);return;}
    nextTime=time+delay;
    ctx.clearRect(0,0,cw,ch);
    drawPolygon(centerX,centerY,sideCount,size,strokeWidth,strokeColor,fillColor,rotationDegrees);
    rotationDegrees+=rotationIncrement;
    requestAnimationFrame(animate);
}

function drawPolygon(centerX,centerY,sideCount,size,strokeWidth,strokeColor,fillColor,rotationDegrees){
    var radians=rotationDegrees*Math.PI/180;
    ctx.translate(centerX,centerY);
    ctx.rotate(radians);
    ctx.beginPath();
    ctx.moveTo (size * Math.cos(0), size * Math.sin(0));          
    for (var i = 1; i <= sideCount;i += 1) {
        ctx.lineTo (size * Math.cos(i * 2 * Math.PI / sideCount), size * Math.sin(i * 2 * Math.PI / sideCount));
    }
    ctx.closePath();
    ctx.fillStyle=fillColor;
    ctx.strokeStyle = strokeColor;
    ctx.lineWidth = strokeWidth;
    ctx.stroke();
    ctx.fill();
    ctx.rotate(-radians);
    ctx.translate(-centerX,-centerY);    }
<canvas id="canvas" width=512 height=512></canvas>
<canvas id="canvas" width=512 height=512></canvas>
Hide result
+4

, fiddle. . "", "", "", "". , .

` drawTriangle (PosX, PosY, SideLength, Orientation) {

if (!Orientation) {
   Orientation = 'east';
}

context.beginPath();

var sides = 3;

var a = ((Math.PI * 2) / sides);
// the components have negative contributions
if (Orientation === 'west' || Orientation === 'north') {
    SideLength *= -1;
}

if (Orientation === 'east' || Orientation === 'west') {
    context.moveTo(PosX + SideLength, PosY);

    for (var i = 1; i < sides + 1; i++) {
        context.lineTo(PosX + SideLength * Math.cos(a*i), PosY + SideLength * Math.sin(a*i));
    }
}
else if (Orientation === 'south' || Orientation === 'north') {
    context.moveTo(PosY, PosX + SideLength);

    for (var i = 1; i < sides + 1; i++) {
        context.lineTo(PosY + SideLength * Math.sin(a*i), PosX + SideLength * Math.cos(a*i));
    }
}
context.stroke();
context.closePath();

} `

+4

. , (. ). , , SideLength . . ​​:

        /* here, radius means the radius of circle, inside of which polygon is drawn */
        function drawTriangle(context, PosX, PosY, radius, rotate) {
            context.beginPath();

            /* number of vertices for polygon */
            var sides = 3;
            /* angle between vertices of polygon */
            var a = ((Math.PI * 2) / sides);

            for (var i = 0; i < sides; i++) {
                context.lineTo(PosX + radius * Math.cos(a*i+rotate), PosY + radius * Math.sin(a*i+rotate));
            }

            context.closePath();
            context.stroke();

            return true;
        }

        var canvas = document.getElementById("demo")
        if (canvas.getContext) {
            var ctx = canvas.getContext('2d');
            var PosX = 50;
            var PosY = 50;
            var radius = 40;
            drawTriangle(ctx, PosX, PosY, radius, Math.PI / 4);
        }
canvas#demo
{
  border: thin solid green;
}
<canvas id="demo" width="200" height="200">
    This browser or document mode doesn't support canvas
</canvas>
Hide result
+2

, , , , .

check out this example I created, it does not use any functions canvas APIfor rotation, and the translation also draws any regular polygon.

var ctx = document.getElementById("cnv").getContext('2d');
var id = 0;

var Point2d = function(x, y) {
  this.x = x || 0;
  this.y = y || 0;
}

Point2d.prototype.set = function(x, y) { 
  this.x = x;
  this.y = y;
};

Point2d.prototype.translate = function(p) { 
  this.x += p.x;
  this.y += p.y;
  return this;
};

//rotation around origin
Point2d.prototype.rotate = function(phi) {
  this.set(
    this.x*Math.cos(phi) - this.y*Math.sin(phi),
    this.x*Math.sin(phi) + this.y*Math.cos(phi)
  );
  return this;
};


function getRegularPolygonPoints(center, numSides, sideLength) {
  var points = [];
  var alpha = 2*Math.PI / numSides;  
  for (var i = 0; i < numSides; i++) {
    points.push(new Point2d( 
      center.x + sideLength*Math.cos(alpha*i),
      center.y + sideLength*Math.sin(alpha*i))
    )
  }  
  return points;
}


function drawPolygon(points) {
  ctx.beginPath();
  ctx.moveTo(points[0].x, points[0].y); 
  for (var i = 1; i < points.length; i++) {
    ctx.lineTo(points[i].x, points[i].y);
  }
  ctx.lineTo(points[0].x, points[0].y);//  close the shape
  ctx.lineWidth = 1;
  ctx.fillStyle = "#899";
  ctx.fill();
  ctx.stroke();
  ctx.closePath();
}

function rotatePolygon(polygonPoints, phi, pointAround) {
  var pointAroundInv= new Point2d(-pointAround.x, -pointAround.y);
  
  for (var i = 0; i < polygonPoints.length; i++) {
    polygonPoints[i].translate(pointAroundInv);//  translate to origin
    polygonPoints[i].rotate(phi);//  rotate
    polygonPoints[i].translate(pointAround);// translate back to it original position
  }
}

var center = new Point2d(250, 120);
var regPolPoints = getRegularPolygonPoints(center, 3, 50);
var currentFrame = (new Date).getTime();
var lastFrame = currentFrame;
var dt = 0;

var render = function() {
  ctx.clearRect(0, 0, 400, 400);
  currentFrame = (new Date).getTime();
  dt = currentFrame - lastFrame;
  lastFrame = currentFrame; 
  
  rotatePolygon(regPolPoints, -dt/600, center);
  drawPolygon(regPolPoints);
  id = requestAnimationFrame(render);
}

id = requestAnimationFrame(render);
<canvas id="cnv" width="400" height="400"></canvas>
Run codeHide result
+2
source

To rotate the triangle

drawTriangle(PosX, PosY, SideLength, Orientation) {
    context.setTransform(1,0,0,1,PosX,PosY); // Set position
    context.rotate(Orientation);  // set rotation in radians
    context.beginPath();
    var sides = 3;
    var a = ((Math.PI * 2) / sides);
    context.moveTo(SideLength,0);

    for (var i = 1; i < sides + 1; i++) {
        context.lineTo(SideLength * Math.cos(a*i), SideLength * Math.sin(a*i));
    }

    context.closePath();
    context.fill()
    context.setTransform(1,0,0,1,0,0);// reset the transform

    return true;
}
+1
source

All Articles