【问题标题】:Find intersection of two lines given a constant slope and changing coordinates在给定恒定斜率和变化坐标的情况下找到两条线的交点
【发布时间】:2023-03-07 14:28:01
【问题描述】:

我之前问过这个问题,但没有清楚地表达出来,所以请原谅我的重复。这应该会更好。

在给定三个其他坐标和 2 个斜率的情况下,我需要计算一个坐标的位置。基本上是两条线的交点。但是,我没有通常可用的所有信息来解决这个问题。

我有一个由一堆顶点定义的任意形状。用户可以在这些顶点之间拖动一条线,形状应如下图所示做出反应。

所以在第一个示例中,用户将线 EF 从左侧位置拖动到右侧位置(线 E2F2)。需要发生的是线 EF 增长/缩小,使其斜率保持不变,并且它的开始和结束坐标分别保持在线 DE 和 AF 上。这显示为 E2F2 行。

这需要足够通用,才能处理我扔给它的任何奇怪或规则的角度。第二组形状显示了一种更简单的方法。用户将线 CD 拖到 C2D2 的位置。注意斜坡是如何保持不变的,D2 基本上沿着对角线滑动,B2C2 和 C2D2 都在长度上延伸。结果是所有 3 个斜率都保持不变,但 B2C2 和 C2D2 线的长度会增加以保持连接,而 D2E2 线会缩小。

您需要了解,当拖动线 EF 时,您实际上是在移动坐标“E”。因此,计算第一个坐标很容易。前一个和下一个永远不会改变。所以我基本上有 3 条相关线的斜率和 4 个必要坐标中的 3 个。我需要第四个,所以在我的例子中,F2 或 D2。

每次坐标移动时,都会在一个事件上调用此代码。假设我们正在拖动线 EF - 那么坐标是 E。

            var next = this.model.get("next"),  // coordinate F
            nextNext = next.get("next"),   // coordinate A
            nextDx = nextNext.get("x") - next.get("x"),    // delta X of AF
            nextDy = nextNext.get("y") - next.get("y"),   // delta Y of AF

            prev = this.model.get("prev"),    // coordinate D
            prevDx = prev.get("x") - this.model.get("x"),   // delta X of DF
            prevDy = prev.get("y") - this.model.get("y"), // delta Y of DF

            selfDx = next.get("x") - this.model.get("x"),   // delta X of EF
            selfDy = next.get("y") - this.model.get("y"),   // delta Y of EF

            selfX = this.initialCoords.x + this.shape.getX(),   // the new position of E
            selfY = this.initialCoords.y + this.shape.getY(),

            selfM, selfB, prevM, prevB, nextM, nextB, m, x, y, b;


        // check for would-be infinities
        if (selfDx == 0) {



            // **** THIS WHOLE BLOCK IS CORRECT ****





            // i'm vertical
            // we can safely assume prev/next aren't also vertical.  i think?  right?

            prevM = prev.get("slope");
            prevB = prev.get("y") - prevM * prev.get("x");



            var myX = selfX,
                myY = prevM * myX + prevB;

            this.model.set({
                x: myX,
                y: myY
            });



            nextM = next.get("slope");
            nextB = next.get("y") - nextM * next.get("x");



            var nextX = selfX,
                nextY = nextM * nextX + nextB;

            next.set({
                x: nextX,
                y: nextY
            });

        } else if (selfDy == 0) {



            //***** THIS WHOLE BLOCK IS CORRECT **** //



            // i'm horizontal

            if (prevDx == 0) {
                // prev is a vertical line
                this.model.set({
                    y: selfY
                });
            } else {

                prevM = prev.get("slope");
                prevB = prev.get("y") - prevM * prev.get("x");

                var myY = selfY,
                    myX = (selfY - prevB) / prevM;

                this.model.set({
                    x: myX,
                    y: myY
                });
            }



            if (nextDx == 0) {
                // next is a vertical line
                next.set({
                    y: selfY
                });
            } else {
                nextM = next.get("slope");
                nextB = next.get("y") - nextM * next.get("x");

                var nextY = selfY,
                    nextX = (selfY - nextB) / nextM;

                next.set({
                    x: nextX,
                    y: nextY
                });
            }
        } else {

            // HELP HERE - you've chosen to drag an arbitrarily angled line.  Figure out the "next" coordinate given the "current" one.

            selfM = this.model.get("slope");
            selfB = this.model.get("y") - this.model.get("slope") * this.model.get("x");

            if (selfM < 0) {

                prevM = prev.get("slope");
                prevB = prev.get("y") - prevM * prev.get("x");

                var myY = selfY,
                    myX = (selfY - prevB) / prevM;


                // CORRECT, but need "next" position based on this
                this.model.set({
                    x: myX,
                    y: myY
                });



            } else {

                // CORRECT but need "next" position based on this.
                var myX = selfX;
                this.model.set({
                    x: myX
                });
            }
        }

【问题讨论】:

    标签: javascript geometry html5-canvas line-intersection


    【解决方案1】:

    我有类似的情况,并使用此页面作为参考取得了一些成功: http://en.wikipedia.org/wiki/Line-line_intersection

    您应该能够枚举所有线测试,以检查它们与移动线相交的任何点。这些将是新坐标。

    wiki 文章中的方程式假定行数无限长,您应该注意这一点,但实际上应该是您想要的(我认为 - 可能存在边缘情况)。

    【讨论】:

    • 我使用该公式让它工作(最终 - 这需要永远),但来自不同的站点并使用一些帮助代码来完成繁重的工作。但是,我会把你的标记为答案。只需要摆弄一下 JS 就可以让它工作。
    • 谢谢!只是认为它可能会为您指明正确的方向 - 很高兴听到您将其分类。
    • @oooyaya 你能分享你的 JS,省得我重新发明轮子吗?谢谢!
    • @Tiago 抱歉,对于我不再合作的雇主来说,这是很久以前的事了,所以我没有也不拥有代码。我确实使用了 wiki 中列出的方程式……
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-09
    • 2022-06-28
    • 2012-10-24
    • 1970-01-01
    • 1970-01-01
    • 2019-10-13
    • 1970-01-01
    相关资源
    最近更新 更多