3d线交叉代码无法正常工作

时间:2016-10-25 07:35:26

标签: math lua geometry line intersection

我创建了这段代码来获得两个3d线段的交集。

不幸的是,这段代码的结果是不准确的,交叉点并不总是在两条线上。

我很困惑,不确定我做错了什么。

这是我的代码:

--dir = direction
--p1,p2 = represents the line
function GetIntersection(dirStart, dirEnd, p1, p2)
   local s1_x, s1_y, s2_x, s2_y =  dirEnd.x - dirStart.x, dirEnd.z - dirStart.z, p2.x - p1.x, p2.z - p1.z
   local div = (-s2_x * s1_y) + (s1_x * s2_y)

   if div == 0 then return nil end
   local s = (-s1_y * (dirStart.x - p1.x) + s1_x * (dirStart.z - p1.z)) / div
   local t = ( s2_x * (dirStart.z - p1.z) - s2_y * (dirStart.x - p1.x)) / div

   if (s >= 0 and s <= 1 and t >= 0 and t <= 1) and (Vector(dirStart.x + (t * s1_x), 0, dirStart.z + (t * s1_y)) or nil) then
      local v = Vector(dirStart.x + (t * s1_x),0,dirStart.z + (t * s1_y))
      return v
   end
end

2 个答案:

答案 0 :(得分:1)

这是Delphi代码的示例,用于在3D中查找两条倾斜线之间的距离。为了您的目的,如果足够小的值(交叉确实存在),有必要检查结果,检查s和t参数是否在0..1范围内,然后 使用参数s计算点

此方法的数学在Paul Bourke page

的“最短行...”部分中描述

VecDiff如果向量差函数,Dot id标量乘积函数

function LineLineDistance(const L0, L1: TLine3D; var s, t: Double): Double;
var
  u: TPoint3D;
  a, b, c, d, e, det, invdet:Double;
begin
  u := VecDiff(L1.Base, L0.Base);
  a := Dot(L0.Direction, L0.Direction);
  b := Dot(L0.Direction, L1.Direction);
  c := Dot(L1.Direction, L1.Direction);
  d := Dot(L0.Direction, u);
  e := Dot(L1.Direction, u);
  det := a * c - b * b;
  if det < eps then   
    Result := -1
  else begin
    invdet := 1 / det;
    s := invdet * (b * e - c * d);
    t := invdet * (a * e - b * d);

    Result := Distance(PointAtParam(L0, s), PointAtParam(L1, t));
  end;
end;

答案 1 :(得分:0)

据我所知,你的代码很好。我已在https://jsfiddle.net/SalixAlba/kkrc9kcf/

的javascript中实现此功能

它似乎适用于我能想到的所有情况。 我所做的唯一改变就是改变javascript中的工作而不是lua。最终条件已被注释掉

entity1

从数学上讲,这是有道理的。如果A,B和C,D是你的两行。设s1 = B-A,s2 = C-D。线AB的点由A + t s1给出,线CD上的点由C + s s2给出。对于我们需要的交叉点

A + t s1 = C + s s2

(A-C)+ t s1 = s s2

通过对每个向量s1和s2采用2D交叉积来找到s,t的两个公式

(A-C)^ s1 + t s1 ^ s1 = s s2 ^ s1 (A-C)^ s2 + t s1 ^ s2 = s s2 ^ s2

回忆s1 ^ s1 = s2 ^ s2 = 0和s2 ^ s1 = - s1 ^ s2我们得到

(A-C)^ s1 = s s2 ^ s1 (A-C)^ s2 + t s1 ^ s2 = 0

可以解决得到s和t。这符合你的方程式。