javascript - 旋转多边形检测并使直线遵循边界

标签 javascript html math collision trigonometry

这是我长期以来一直在努力解决的一个问题。

enter image description here

正如您所看到的,这是实际有效的问题的当前状态。我使用工具在 2 个 div 之间拖动一条线,如果移动源 div 或目标 div,箭头就会跟随矩形边界。 为此,我计算直线(由代表每个 div 中心的 2 个点定义)与矩形边界之间的交点。然后,通过获取目标 div 中心与其位置之间的距离来减少直线边界。到目前为止,一切都很好。

这是棘手的部分: 我最近实现了像这样旋转这些矩形的功能

enter image description here

还有两个问题:

  • 当您将一条线从矩形(未旋转)拖动到旋转的矩形时,它仍然遵循边界,就像未旋转一样
  • 当您将一条线从旋转的矩形拖动到另一个矩形时,它不会粘在另一个矩形的边界上

所以我的问题是:如何使这些箭头跟随旋转的矩形。更棘手的是,如何将一个旋转矩形的箭头绘制到另一个旋转矩形。 我可以使用的技术受到限制:HTML5、CSS3、JQuery(Javascript) 无法使用 HTML5 Canvas 。

我有矩形的旋转 Angular ,因为我自己设置了它。

这是我计算线的交点、斜边(箭头宽度)和旋转 Angular 代码:

     var link = $(target).find(".arrow");
    if ($(link).length) {
        $.each(link, function (index, value) {
/* zoomLevel is just a scaling of the container, it corrects position but here, you can just ignore it */
            var x1 = $(target).offset().left + ($(target).width() / 2) * zoomLevel;
            var y1 = $(target).offset().top + ($(target).height() / 2) * zoomLevel;
            var to = $(value).attr("data-bind");
            var destinationStuff = $("body").find("#" + to);
            var destinationW = ($(destinationStuff).width() / 2) * zoomLevel;
            var destinationH = ($(destinationStuff).height() / 2) * zoomLevel;
            var x2 = $(destinationStuff).offset().left + destinationW;
            var y2 = $(destinationStuff).offset().top + destinationH;
            var hypotenuse = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
            var angle = Math.atan2((y1 - y2), (x1 - x2)) * (180 / Math.PI);
            angle += 180;
            var a = (y2 - y1) / (x2 - x1);
            var minushyp = 0;
            if (-destinationH <= a * destinationW && a * destinationW <= destinationH) {
                if (x1 > x2) {
                    //intersect with left side target

                        interX = Math.abs(a * destinationW);
                        minushyp = Math.sqrt((destinationW) * (destinationW) + (interX) * (interX));


                } else {
                    //intersect with right side target
                    interX = Math.abs(a * destinationW);
                    minushyp = Math.sqrt((destinationW) * (destinationW) + (interX) * (interX));
                }
            } else if (-destinationW <= destinationH / a && destinationH / a <= destinationW) {
                if (y1 > y2) {
                    //intersect with bottom side target
                    interX = Math.abs(destinationH / a);
                    minushyp = Math.sqrt((destinationH) * (destinationH) + (interX) * (interX));

                } else {
                    //intersect with top side target
                    interX = Math.abs(destinationH / a);

                    minushyp = Math.sqrt((destinationH) * (destinationH) + (interX) * (interX));

                }
            }

            animateBind(value, target, hypotenuse, minushyp, angle, false);

        });
    }

我有一个函数可以做同样的事情,但是当您拖动目标矩形时(因此绑定(bind)到它的每个箭头也会移动)

和一些 HTML

<div class="board">
            <div class="stuffSet object" id="box5" data-rotation="20"
             style="top: somepx; left: somepx; -webkit-transform-origin:0% 0%; -webkit-transform:rotate(some degrees)">
<div class="stuffSet object" id="box4" style="top: 220px; left: 702px;">
            <div class="subStuff arrow object" data-bind="box5">
                <div class="line top left" style="border-width: 1px; right: 0px;"></div>
                <div class="line top right" style="border-width: 1px; right: 0px;"></div>
                <div class="line center" style="border-width: 1px;"></div>
            </div>
        </div>
</div>

每个想法都绝对定位在板上 谢谢!

最佳答案

在 div 边界处剪切线条的一种方法是将线条转换为 div 的本地坐标系。

假设直线由x1, y1, x2, y2定义,并且x2,y2需要被剪裁。

首先,将场景移动(-divcenterx, -divcentery)。之后,div 的中心将位于原点:

x1 -= divcenterx
y1 -= divcentery
x2 -= divcenterx
y1 -= divcentery

然后我们需要用矩阵R恢复旋转:

R11 = cos(angle)
R12 = sin(angle)
R21 = -sin(angle)
R22 = cos(angle)

x1Unrotated = R11 * x1 + R12 * y1
y1Unrotated = R21 * x1 + R22 * y1
x2Unrotated = R11 * x2 + R12 * y2
y2Unrotated = R21 * x2 + R22 * y2

现在我们可以像您一样执行剪辑。要剪辑的矩形以原点为中心,并具有原始宽度和高度。

之后,我们必须撤消转换。

x1 = R11 * x1Unrotated + R21 * y1Unrotated + divcenterx
y1 = R12 * x1Unrotated + R22 * y1Unrotated + divcentery
x2 = R11 * x2Unrotated + R21 * y2Unrotated + divcenterx
y2 = R12 * x2Unrotated + R22 * y2Unrotated + divcentery

这是线的最终坐标。

关于javascript - 旋转多边形检测并使直线遵循边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17295444/

相关文章:

algorithm - 在游戏中计算卡车载货量

javascript - 将一个变量替换为另一个变量

javascript - 在 Node 服务器中部署 ext js 应用程序时出现错误

javascript - jQuery - 将 html 放入数组中以进行 ajax 查询

jquery - 文本淡入效果

c - 为 Goldschmidt 部门选择良好的初步估计

javascript - 在 JavaScript 中计算对数数组的平均值

javascript - $ 未定义 - 将 jQuery 与 electron.js 一起使用

jquery - 第一次删除后无法第二次上传相同的图片

ruby-on-rails - 如何使用 RSpec 测试 WebSockets(使用 Pusher)?