在形状内绘制角度弧

我有四分。 它的拖拉机。 在任何一点我点击“绘制”按钮我想显示角度。 我试过但它会在外面画出陡峭的角度。 但我想在任何一点绘制形状内的弧。

$(document).ready(function () { var c = document.getElementById('canvas'); var ctx = c.getContext("2d"); var a1 = parseInt($("#p1").css("left")) - 5; var a2 = parseInt($("#p1").css("top")) - 5; var b1 = parseInt($("#p2").css("left")) - 5; var b2 = parseInt($("#p2").css("top")) - 5; var c1 = parseInt($("#p3").css("left")) - 5; var c2 = parseInt($("#p3").css("top")) - 5; var d1 = parseInt($("#p4").css("left")) - 5; var d2 = parseInt($("#p4").css("top")) - 5; ctx.beginPath(); ctx.moveTo(a1, a2) ctx.lineTo(b1, b2) ctx.lineTo(c1, c2) ctx.lineTo(d1, d2) ctx.lineTo(a1, a2) ctx.fillStyle = '#E6E0EC'; ctx.fill(); ctx.strokeStyle = "#604A7B"; ctx.lineWidth = "3" ctx.stroke(); ctx.closePath(); $("#p1,#p2,#p3,#p4").draggable({ drag: function () { a1 = parseInt($("#p1").css("left")) - 5; a2 = parseInt($("#p1").css("top")) - 5; b1 = parseInt($("#p2").css("left")) - 5; b2 = parseInt($("#p2").css("top")) - 5; c1 = parseInt($("#p3").css("left")) - 5; c2 = parseInt($("#p3").css("top")) - 5; d1 = parseInt($("#p4").css("left")) - 5; d2 = parseInt($("#p4").css("top")) - 5; ctx.clearRect(0, 0, 500, 500); ctx.beginPath(); ctx.moveTo(a1, a2) ctx.lineTo(b1, b2) ctx.lineTo(c1, c2) ctx.lineTo(d1, d2) ctx.lineTo(a1, a2) ctx.fillStyle = '#E6E0EC'; ctx.fill(); ctx.strokeStyle = "#604A7B"; ctx.lineWidth = "3" ctx.stroke(); ctx.closePath(); } }); $("#draw").click(function () { var dx1 = a1 - b1; var dy1 = a2 - b2; var dx2 = c1 - b1; var dy2 = c2 - b2; var ax1 = Math.atan2(dy1, dx1); var ax2 = Math.atan2(dy2, dx2); var a = parseInt((ax2 - ax1) * 180 / Math.PI + 360) % 360; /// detect if arc is inside or outside polygon: var aa = ax1 + 0.25; var x = b1 + 20 * Math.cos(aa); var y = b2 + 20 * Math.sin(aa); var isInside = ctx.isPointInPath(x, y); ctx.save(); ctx.beginPath(); ctx.moveTo(b1, b2); ctx.arc(b1, b2, 20, ax1, ax2, !isInside); ctx.closePath(); ctx.fillStyle = "red"; ctx.globalAlpha = 0.25; ctx.fill(); ctx.restore(); ctx.fillStyle = "black"; ctx.fillText((isInside ? a : 360-a) + '°', b1 + 15, b2); }); }); 

请了解小提琴: http : //jsfiddle.net/AbdiasSoftware/BKK5z/6/

预先感谢。

在chrome我得到这样的结果

在此处输入图像描述

在Firefox中我得到这样的结果

在此处输入图像描述

好的,事实certificate问题并不是与路径点相关,而是与路径本身有关。

问题

当只有一个圆弧绘制时,前一个路径用于检测该点是否在多边形内部。

当添加其他三个弧时,前一个路径现在变为最后绘制的弧。 这样,内部多边形检测将无法返回正确的状态,因为它将使用弧进行测试。

这里更新了小提琴

对代码进行重新分解,以便在每次检查之前重新创建多边形的原始路径。 这是一个相对快速的过程,因为我们不需要绘制任何东西到canvas来获得有效路径(昂贵的部分是绘图本身)。

执行以下操作以修复 –

首先创建一个通用函数来创建路径。 此方法可用于渲染以及仅检查路径:

 function createPath(a1,a2, b1, b2, c1, c2, d1, d2) { ctx.beginPath(); ctx.moveTo(a1, a2); ctx.lineTo(b1, b2); ctx.lineTo(c1, c2); ctx.lineTo(d1, d2); //ctx.lineTo(a1, a2); /// not needed ctx.closePath(); } 

现在修改draw方法:

 drag: function () { a1 = parseInt($("#p1").css("left")) - 5; ... snipped ... ctx.clearRect(0, 0, 500, 500); createPath(a1, a2, b1, b2, c1, c2, d1, d2); /// use here ctx.fillStyle = '#E6E0EC'; ctx.fill(); ... snipped ... } 

这将像以前一样渲染多边形。

现在关键的是,为每个绘制的弧重建路径但不渲染它:

 $("#draw").click(function () { createPath(a1, a2, b1, b2, c1, c2, d1, d2); draw(a1,b1,c1,a2,b2,c2); createPath(a1, a2, b1, b2, c1, c2, d1, d2); draw(b1,c1,d1,b2,c2,d2); createPath(a1, a2, b1, b2, c1, c2, d1, d2); draw(c1,d1,a1,c2,d2,a2); createPath(a1, a2, b1, b2, c1, c2, d1, d2); draw(d1, a1, b1, d2, a2, b2); }); 

第二个小问题是臭名昭着的delta值的“敏感性”。 再调整一下再到~0.20-ish,你应该好好去。

正如我在上一个答案中提到的,这个值的理想解决方案是计算两个角度之间的“平均值”,使角度位于弧的中间。

[更新了带有可拖动角点的演示答案]

这是一个演示内部角度的演示,您可以其中拖动角点:

http://jsfiddle.net/m1erickson/6ujbL/

这是一个演示外部角度的演示,您可以在其中拖动角点:

http://jsfiddle.net/m1erickson/9kGmw/

如果要在内角上绘制角度符号,可以通过逆时针顺序提供角(顶点)点来调用此函数:point3,point2,point1:

 function drawAngleSymbol(pt3,pt2,pt1){ ... } 

如果要在外角绘制角度符号,可以调用相同的函数并按顺时针顺序提供角点:point1,point2,point3:

 function drawAngleSymbol(pt1,pt2,pt3){ ... }