三维线路交叉口代码无法正常工作 [英] 3d line-intersection code not working properly

查看:128
本文介绍了三维线路交叉口代码无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



这是我的代码:

   -  dir =方向
--p1,p2 =表示行
函数GetIntersection(dirStart,dirEnd,p1,p2)
本地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> (t)= 0且s≤1且t≥0且t≤1)和(向量(dirStart.x +(t * s1_x),0,dirStart.z +(t * s1_y))或零)then
local v = Vector(dirStart.x +(t * s1_x),0,dirStart.z +(t * s1_y))
return v
end
结束


解决方案

3D中的两条倾斜线之间。出于您的目的,如果足够小的值(交叉点确实存在)检查结果,检查s和t参数在范围0..1中,然后
使用参数s计算点



这种方法的数学描述在最短的一行...部分Paul Bourke页面

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

 函数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:=点(L0.Direction,L0.Direction);
b:=点(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;
如果det< eps然后
结果:= -1
else begin
invdet:= 1 / det;
s:= invdet *(b * e - c * d);
t:= invdet *(a * e - b * d);

结果:=距离(PointAtParam(L0,s),PointAtParam(L1,t));
end;
end;


I created this piece of code to get the intersection of two 3d line-segments.

Unfortunately the result of this code is inaccurate, the intersection-point is not always on both lines.

I am confused and unsure what I'm doing wrong.

Here is my code:

--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

解决方案

This is example of Delphi code to find a distance between two skew lines in 3D. For your purposes it is necessary to check that result if small enough value (intersection does exist), check that s and t parameters are in range 0..1, then calculate point using parameter s

Math of this approach is described in 'the shortest line...' section of Paul Bourke page

VecDiff if vector difference function, Dot id scalar product function

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;

这篇关于三维线路交叉口代码无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆