确定无限直线和线段是否相交的公式?

Formula to determine if an infinite line and a line segment intersect?

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

我找到了这个,但我不确定它在这里是否有用。
如果有人想帮助我理解 "rays",那我没问题。 http://www.realtimerendering.com/intersections.html

对不起,我是个白痴。

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

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

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

如果你有直线i的起点和终点,那么你也可以轻松构造向量i

第一行任意点有参数方程

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来计算交点

请不要让我解释它究竟是如何工作的,我只是 extrapolated/rewritten 它来自我手头的一些古老代码。 (动作脚本 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));
}

intersection-code:

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

returns 有关交叉点的信息,以及它是否在传递的 lines/rays 上。不关心你是通过线还是射线。

关于timeTillIntersection:如果第一个argument/ray表示一个ball/bullet/whatever当前位置和motion-vector,第二个参数表示一堵墙左右,那么v,又名 timeTillIntersection 决定了这个球 intersects/hits 墙壁(在当前条件下)所用的时间与用于球速度的单位相同。所以你基本上可以免费获得一些信息。