在画布中绘制三角形的角度标记

时间:2015-09-24 17:10:48

标签: javascript html5 canvas graphics geometry

我一直在努力尝试在画布上绘制三角形的角度标记,到目前为止一无所获。我尝试过使用arc方法但没有成功。也许我缺乏必要的数学知识,所以我只是请问我给一个需要3点({x,y}类型的对象)的函数,然后绘制一个相似的图形:

enter image description here

谢谢!

1 个答案:

答案 0 :(得分:3)

以下是如何做到这一点..

两个方便的函数distancedirection获取一条线的长度和一条线的方向。因为方向是循环的,所以“在这种情况下”保持正和2PI(360度)的模数,我们必须做一点检查,因为我们在线之间得到的角度可能是负的,即使一个可能是300Deg而另一个370Deg但会显示为300Deg和10Deg。

有很多优化空间,因为很多东西都会被重新计算,如果三角形的边长很长,内角接近PI,则弧线有时会越过一条直线。

角行程半径是最短行的1/5。您可能希望为每个角度设置此值。我没有包含文字渲染,只是将sweepAng的一半添加到函数startAngle中的drawAngle以获取文本的x和y。

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

认为我有很多评论可以提供帮助,但如果您不理解,请询问。

// 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;
} 

没有运行它,所以希望没有错别字。希望这会有所帮助。