【问题标题】:Formula to determine if an infinite line and a line segment intersect?确定无限线和线段是否相交的公式?
【发布时间】:2017-01-17 11:32:29
【问题描述】:

给定一条线上的一个点和该线的斜率,如何确定这条线在每个方向上无限延伸,是否与线段(x1,y1)(x2,y2) 相交,如果是,则确定相交的点发生了吗?

我找到了这个,但我不确定它在这里是否有用。
如果有人想帮助我理解“射线”,我可以。 http://www.realtimerendering.com/intersections.html

对不起,我是个白痴。

【问题讨论】:

  • 所以线不能垂直?

标签: javascript math glsl gpu


【解决方案1】:

第一行任意点有参数方程

dx = Cos(slope)
dy = Sin(Slope)
x = x0 + t * dx     (1)
y = y0 + t * dy

包含第二段的行

dxx = x2 - x1
dyy = y2 - y1
x = x1 + u * dxx    (2)
y = y1 + u * dyy

如果线性系统存在交点

x0 + t * dx = x1 + u * dxx   (3)    
y0 + t * dy = y1 + u * dyy

有未知数的解决方案tu
u 位于[0..1] 范围内

可以通过替换方程对 (2) 中的 u 来计算交点

【讨论】:

  • 将此答案与gamedev.stackexchange.com/a/44733/60691 结合起来,以全面解决我的问题。
  • 实际上,@Mbo 您能否为 dx 和 dy 提供任何其他文档,说明为什么坡度上的 cos 和 sin 会给我这些值。答案似乎大部分是正确的,但随着坡度接近完全垂直,我看到了奇怪。
  • 我假设 slope 是 OX 轴和线方向之间的角度。如果我们想为线定义单位长度方向向量,那么它的分量是余弦和正弦(dirx,diry) = (cos(slope), sin(slope)) 这种方法适用于任何斜率,包括垂直线。你看到了什么奇怪的东西?
【解决方案2】:

请不要让我解释它是如何工作的,我只是从我已经放置的一些古老代码中推断/重写它。 (动作脚本 1)

为这个例子构建对象的一些函数:

function point(x, y){ 
    return {x, y} 
}
function line(x0, y0, x1, y1){
  return {
    start: point(x0, y0), 
    end: point(x1, y1)
  } 
}
function ray(x, y, vx, vy){
  return {
    start: point(x, y), 
    vector: point(vx, vy)
  } 
}
function ray2(x, y, angle){
    var rad = angle * Math.PI / 180;
    return ray(x, y, Math.cos(rad), Math.sin(rad));
}

路口代码:

//returns the difference vector between two points (pointB - pointA)
function delta(a, b){ return point( b.x - a.x, b.y - a.y ) }
//kind of a 2D-version of the cross-product
function cp(a, b){ return a.y * b.x - a.x * b.y } 

function intersection(a, b){
    var d21 = a.vector || delta(a.start, a.end),
        d43 = b.vector || delta(b.start, b.end),
        d13 = delta(b.start, a.start),
        d = cp(d43, d21);

    //rays are paralell, no intersection possible
    if(!d) return null;
    //if(!d) return { a, b, position: null, hitsA: false, hitsB: false };

    var u = cp(d13, d21) / d,
        v = cp(d13, d43) / d;

    return {
        a, b,

        //position of the intersection
        position: point(
            a.start.x + d21.x * v,
            a.start.y + d21.y * v
        ),  
        //is position on lineA?
        hitsA: v >= 0 && v <= 1,
        //is position on lineB?
        hitsB: u >= 0 && u <= 1,

        timeTillIntersection: v,
    };
}

还有一个例子:

var a = line(0, 0, 50, 50);

var b = line(0, 50, 50, 0);             //lines are crossing
console.log(intersection(a, b));

var c = line(100, 50, 150, 0);          //lines are not crossing
console.log(intersection(a, c));

var d = line(100, -1000, 100, 1000);    //intersection is only on d, not on a
console.log(intersection(a, d));

var e = ray(100, 50, -1, -1);           //paralell to a
console.log(intersection(a, e));

返回有关交点的信息,以及它是否在通过的线/射线上。不管你是通过线还是射线。

关于timeTillIntersection:如果第一个参数/射线代表一个球/子弹/任何具有当前位置和运动矢量的东西,而第二个参数代表一堵墙左右,那么v,又名timeTillIntersection确定如何直到这个球以与球速度相同的单位相交/撞到墙壁(在当前条件下)需要很长时间。所以你基本上可以免费获得一些信息。

【讨论】:

    【解决方案3】:

    您搜索的是dot product。一条线可以表示为一个向量。

    当你有 2 条线时,它们会在某个点相交。除非它们平行。

    平行向量 a,b(均归一化)的点积为 1(dot(a,b) = 1)。

    如果你有线i的起点和终点,那么你也可以很容易地构造向量i

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-25
      • 2012-09-02
      相关资源
      最近更新 更多