gpt4 book ai didi

javascript - 在形状内部绘制 Angular 圆弧[陡 Angular ]

转载 作者:行者123 更新时间:2023-12-02 17:47:39 27 4
gpt4 key购买 nike

我有四点。它是可拖动的。在任何时候我点击“绘制”按钮我想显示 Angular 。我尝试过,但它会在外面画出陡峭 Angular 弧线。但我想在形状内的任意点绘制圆弧。

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

});
});

请注意 fiddle :http://jsfiddle.net/AbdiasSoftware/BKK5z/6/

提前致谢。

在 Chrome 中我得到这样的结果

enter image description here

在 Firefox 中我得到这样的结果

enter image description here

最佳答案

好吧,事实证明问题与路径中的点没有太大关系,而是与路径本身有关。

问题

当仅绘制单个圆弧时,使用先前的路径来检测该点是否在多边形内部。

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

解决方案

<强> Updated fiddle here

重构代码,以便在每次检查之前可以重新创建多边形的原始路径。这是一个相对快速的过程,因为我们不必在 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();
}

现在修改绘制方法:

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

});

第二个小问题是臭名昭著的增量值的“敏感性”。再次将其向上调整到约 0.20 左右,您应该可以开始了。

正如我在之前的答案中提到的,该值的理想解决方案是计算两个 Angular 之间的“平均值”,以便该 Angular 位于圆弧的中间。

关于javascript - 在形状内部绘制 Angular 圆弧[陡 Angular ],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21619907/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com