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

时间:2017-01-17 00:13:54

标签: javascript math glsl gpu

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

我发现了这一点,但我不确定它是否有用。
如果有人想帮我理解“光线”,那对我来说没问题。 http://www.realtimerendering.com/intersections.html

我很抱歉我是个白痴。

3 个答案:

答案 0 :(得分: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替换来计算交叉点

答案 1 :(得分:1)

请不要让我解释这是如何运作的,我只是从我已经存在的一些古老代码中推断/重写它。 (Actionscript 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:如果第一个参数/ ray代表一个球/子弹/任何具有当前位置和运动矢量的东西,而第二个参数代表一个墙左右,那么v,又名{ {1}}确定该球在与球的速度相同的单位中与墙壁(在当前条件下)相交/撞击所花费的时间。所以你基本上可以免费获得一些信息。

答案 2 :(得分:0)

您搜索的是dot product。线可以表示为矢量。

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

平行向量 a,b (均标准化)的点积为1(点(a,b)= 1 )。

如果你有 i 行的起点和终点,那么你也可以轻松地构建向量 i