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.