Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在形状内绘制角度弧[陡角]_Javascript_Jquery_Html_Canvas_Html5 Canvas - Fatal编程技术网

Javascript 在形状内绘制角度弧[陡角]

Javascript 在形状内绘制角度弧[陡角],javascript,jquery,html,canvas,html5-canvas,Javascript,Jquery,Html,Canvas,Html5 Canvas,我有四点意见。它是拖拉的。在任何点,我点击“绘制”按钮,我想显示角度。我试过了,但它会在外面画出一个陡峭的弧线。但是我想在形状的任何一点上画一条弧 $(document).ready(function () { var c = document.getElementById('canvas'); var ctx = c.getContext("2d"); var a1 = parseInt($("#p1").css("left")) - 5; var a2 = parseInt($("#p1")

我有四点意见。它是拖拉的。在任何点,我点击“绘制”按钮,我想显示角度。我试过了,但它会在外面画出一个陡峭的弧线。但是我想在形状的任何一点上画一条弧

$(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);

});
});
请注意小提琴:

先谢谢你

在chrome中,我得到的结果如下

在firefox中,我得到这样的结果


[更新的答案,带有允许拖动角点的演示]

这是一个演示,显示了内角,您可以在其中拖动角点:

这是一个演示,显示了外角,您可以在其中拖动角点:

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

function drawAngleSymbol(pt3,pt2,pt1){ ... }
如果要在外角上绘制角度符号,可以调用此函数并按顺时针顺序提供角点:点1、点2、点3:

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

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

这是一个演示,显示了内角,您可以在其中拖动角点:

这是一个演示,显示了外角,您可以在其中拖动角点:

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

function drawAngleSymbol(pt3,pt2,pt1){ ... }
如果要在外角上绘制角度符号,可以调用此函数并按顺时针顺序提供角点:点1、点2、点3:

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

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

这是一个演示,显示了内角,您可以在其中拖动角点:

这是一个演示,显示了外角,您可以在其中拖动角点:

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

function drawAngleSymbol(pt3,pt2,pt1){ ... }
如果要在外角上绘制角度符号,可以调用此函数并按顺时针顺序提供角点:点1、点2、点3:

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

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

这是一个演示,显示了内角,您可以在其中拖动角点:

这是一个演示,显示了外角,您可以在其中拖动角点:

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

function drawAngleSymbol(pt3,pt2,pt1){ ... }
如果要在外角上绘制角度符号,可以调用此函数并按顺时针顺序提供角点:点1、点2、点3:

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

好的,问题不在于路径中的点,而在于路径本身

问题 如果只绘制了一条圆弧,则使用上一条路径来检测该点是否位于多边形内部

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

解决方案

重新计算代码的因子,以便在每次检查之前可以重新创建多边形的原始路径。这是一个相对快速的过程,因为我们不必在画布上绘制任何东西来获得有效路径(代价高昂的部分是图形本身)

执行以下操作以修复-

首先创建一个泛型函数来创建路径。此方法只能用于渲染和检查路径:

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();
}
现在修改绘制方法:

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,你就可以开始了


前面的答案中提到的,这个值的理想解是在两个角度之间计算一个“平均值”,所以角度在圆弧的中间。

< P> OK,结果出问题与路径中的点无关,而是与路径本身有关。< /P> 问题 如果只绘制了一条圆弧,则使用上一条路径来检测该点是否位于多边形内部

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

解决方案

重新计算代码的因子,以便在每次检查之前可以重新创建多边形的原始路径。这是一个相对快速的过程,因为我们不必在画布上绘制任何东西来获得有效路径(代价高昂的部分是图形本身)

执行以下操作以修复-

首先创建一个泛型函数来创建路径。此方法只能用于渲染和检查路径:

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();
}
现在修改绘制方法:

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,你就可以开始了


前面的答案中提到的,这个值的理想解是在两个角度之间计算一个“平均值”,所以角度在圆弧的中间。

< P> OK,结果出问题与路径中的点无关,而是与路径本身有关。< /P> 问题