简体   繁体   中英

Draw the angle marks of a triangle in canvas

I've been striving for while trying to draw the angle marks of a triangle in canvas and got nothing so far. I've tried using the arc method without success. Maybe I lack the math knowledge necessary to do this so I just ask please give me a function that takes 3 points ({x,y} type of objects) and draws a figure simillar to this one:

在此处输入图片说明

thanks!

Here is how to do it..

Two handy functions distance and direction get the length of a line and the direction of a line. Because direction is cyclic we "in this case" keep it positive and the modulo of 2PI (360 degrees) and we have to do a little checking because the angles we get between lines may be negative even though one may be 300Deg and the other 370Deg but will appear as 300Deg and 10Deg.

There is lots of room for optimization as a lot of stuff is recalculated, and the arc can at times cross a line if the triangle has a very long edge with an inner angle close to PI.

The angle stroke radius is 1/5th of the shortest line. You may want to set this per angle. I have not included the text render but just get half the sweepAng add to startAngle in function drawAngle to get x and y for the text.

var textX = x + Math.cos(startAngle + sweepAng / 2) * minDist *2;
var textY = y + Math.sin(startAngle + sweepAng / 2) * minDist *2;

Think I have plenty of comments to help but do ask if you do not understand.

// ctx is the canvas context

// function to get distance
function distance(x, y, xx, yy) {
   return Math.sqrt(Math.pow(x - xx, 2) + Math.pow(y - yy, 2) );
}

// function gets the direction of a line
function direction(x, y, xx, yy) {
   var angV = Math.acos( (xx - x) / Math.sqrt( Math.pow(x - xx, 2) + Math.pow(y - yy, 2) ) );

   if (y - yy > 0) angV = - angV; // check the sign

   return (angV + Math.PI * 2) % (Math.PI * 2); // makes the angle positive. 
                                                // Not needed but for this 
                                                // makes it easier to understand
}

// function to draw a triangle with angle marks
// pass it the 3 points at the corners of the triangle.
// will handle any triangle
function drawTriangle(x1,y1,x2,y2,x3,y3){ 
    // function to draw angle
    function drawAngle(x, y, dirA, dirB){
        dirB += Math.PI;              // revers second direction
        var sweepAng = dirB - dirA;   // angle between lines
        var startAng = dirA;          // angle to start the sweep of the arc
        if(Math.abs(sweepAng) > Math.PI){  // if the angle us greater the 180
            sweepAng = Math.PI * 2 - sweepAng;  // get the smaller angle
            startAng = dirB;          // and change the start angle
        }
        ctx.beginPath();
        if(sweepAng < 0){                  // if the angle is sweeping anticlockwise
            ctx.arc(x, y, minDist ,startAng + sweepAng , startAng);
        }else{                        // draw clockwise angle
            ctx.arc(x, y, minDist, startAng, startAng + sweepAng);
        }
        ctx.stroke();                 // all done
    }

     ctx.lineWidth = 3;               // draw the lines of the triangle
     ctx.strokeStyle = "black";
     ctx.beginPath();
     ctx.moveTo(x1, y1);
     ctx.lineTo(x2, y2);
     ctx.lineTo(x3, y3);
     ctx.closePath();
     ctx.stroke();

     // now work out the radius of the angle stroke
     var dist1 = distance(x1, y1, x2, y2);  // get the 3 distance of the lines
     var dist2 = distance(x2, y2, x3, y3);
     var dist3 = distance(x3, y3, x1, y1);
     var minDist = Math.min(dist1, dist2, dist3); // get the min dist;
     if(minDist === 0){
        return; // there are no angles to draw and exit 
                // to avoid divide by zero in direction function
     }
     minDist /= 5; // get the amgle arc radius 1/5th

     var dir1 = direction(x1, y1, x2, y2);  // get the 3 directions of the lines
     var dir2 = direction(x2, y2, x3, y3);
     var dir3 = direction(x3, y3, x1, y1);

    drawAngle(x1, y1, dir1, dir3); // draw the angle stoke first corner;
    drawAngle(x2, y2, dir2, dir1); // draw the angle stoke second corner;
    drawAngle(x3, y3, dir3, dir2); // draw the angle stoke third;
} 

Have not run it so hope there are no typos. Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM