在tcl中找到平面和直线之间的交点?
以下代码有什么问题? 我得到了非常奇怪的结果。我错过了什么吗?
proc Dot {vec1 vec2} {
set ret [expr ([lindex $vec1 0]*[lindex $vec2 0])+([lindex $vec1 1]*[lindex $vec2 1])+([lindex $vec1 2]*[lindex $vec2 2])]
}
proc FindInterSectPoint_LineAndPlane {normalVectorPlane basePoint refPoint topoint} {
foreach {norm1 norm2 norm3} $normalVectorPlane {break}
foreach {xB yB zB} $basePoint {break}
foreach {xb yb zb} $refPoint {break}
foreach {xa ya za} $topoint {break}
set vecL1 [expr $xb-$xa]
set vecL2 [expr $yb-$ya]
set vecL3 [expr $zb-$za]
set direction [expr -($norm1*$xB)+($norm2*$yB)+($norm3*$zB)]
set d [expr -(($vecL1*$xb)+($vecL2*$yb)+($vecL3*$zb)+$direction)]
set n [Dot $normalVectorPlane [list $vecL1 $vecL2 $vecL3] ]
if {$n == 0} {
return "line on parallel to plane"; # line on plane
}
set s [expr $d/($n*1.000)]
if {$s > 0 && $s < 1} {
set ret "intersection occurs between the two end points"
} elseif {$s == 0} {
set ret "intersection falls on the first end point"
} elseif {$s == 1} {
set ret "intersection falls on the second end point"
} elseif {$s > 1} {
set ret "intersection occurs beyond second end Point"
} elseif {$s < 0} {
set ret "intersection happens before 1st end point"
} else {
set ret "error"
}
set x [expr [lindex $refPoint 0]+($s*$vecL1)]
set y [expr [lindex $refPoint 1]+($s*$vecL2)]
set z [expr [lindex $refPoint 2]+($s*$vecL3)]
lappend ret "$x $y $z n=$n d=$d s=$s"
}
输出:
%FindInterSectPoint_LineAndPlane {0 0 1} {0 0 0} {0 0 0} {1 2 3}
交点落在第一个端点 {0.0 0.0 0.0 n=-3 d=0 s=-0.0}
%FindInterSectPoint_LineAndPlane { 1 0 0} {0 0 0} {0 0 1} {0 0 0}
与平面平行的线
%FindInterSectPoint_LineAndPlane {1 0 0} {0 0 0} {0 0 1} {0 0 5}
与平面平行的线plane
%FindInterSectPoint_LineAndPlane {0 0 1} {0 0 0} {1 1 1} {2 2 2}
相交发生在第一个终点之前 {4.0 4.0 4.0 n=-1 d=3 s=-3.0}
%FindInterSectPoint_LineAndPlane {0 0 1} {0 0 0} {-1 -1 -1} {2 2 2}
相交发生在第二个端点 {-10.0 -10.0 -10.0 n=-3 d=-9 s=3.0} 之外
What is problem with follwoing code?
I am getting very strange results. Do I missing something?
proc Dot {vec1 vec2} {
set ret [expr ([lindex $vec1 0]*[lindex $vec2 0])+([lindex $vec1 1]*[lindex $vec2 1])+([lindex $vec1 2]*[lindex $vec2 2])]
}
proc FindInterSectPoint_LineAndPlane {normalVectorPlane basePoint refPoint topoint} {
foreach {norm1 norm2 norm3} $normalVectorPlane {break}
foreach {xB yB zB} $basePoint {break}
foreach {xb yb zb} $refPoint {break}
foreach {xa ya za} $topoint {break}
set vecL1 [expr $xb-$xa]
set vecL2 [expr $yb-$ya]
set vecL3 [expr $zb-$za]
set direction [expr -($norm1*$xB)+($norm2*$yB)+($norm3*$zB)]
set d [expr -(($vecL1*$xb)+($vecL2*$yb)+($vecL3*$zb)+$direction)]
set n [Dot $normalVectorPlane [list $vecL1 $vecL2 $vecL3] ]
if {$n == 0} {
return "line on parallel to plane"; # line on plane
}
set s [expr $d/($n*1.000)]
if {$s > 0 && $s < 1} {
set ret "intersection occurs between the two end points"
} elseif {$s == 0} {
set ret "intersection falls on the first end point"
} elseif {$s == 1} {
set ret "intersection falls on the second end point"
} elseif {$s > 1} {
set ret "intersection occurs beyond second end Point"
} elseif {$s < 0} {
set ret "intersection happens before 1st end point"
} else {
set ret "error"
}
set x [expr [lindex $refPoint 0]+($s*$vecL1)]
set y [expr [lindex $refPoint 1]+($s*$vecL2)]
set z [expr [lindex $refPoint 2]+($s*$vecL3)]
lappend ret "$x $y $z n=$n d=$d s=$s"
}
Output:
%FindInterSectPoint_LineAndPlane {0 0 1} {0 0 0} {0 0 0} {1 2 3}
intersection falls on the first end point {0.0 0.0 0.0 n=-3 d=0 s=-0.0}
%FindInterSectPoint_LineAndPlane {1 0 0} {0 0 0} {0 0 1} {0 0 0}
line on parallel to plane
%FindInterSectPoint_LineAndPlane {1 0 0} {0 0 0} {0 0 1} {0 0 5}
line on parallel to plane
%FindInterSectPoint_LineAndPlane {0 0 1} {0 0 0} {1 1 1} {2 2 2}
intersection happens before 1st end point {4.0 4.0 4.0 n=-1 d=3 s=-3.0}
%FindInterSectPoint_LineAndPlane {0 0 1} {0 0 0} {-1 -1 -1} {2 2 2}
intersection occurs beyond second end Point {-10.0 -10.0 -10.0 n=-3 d=-9 s=3.0}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是什么?
我猜应该是:(
注意“|”和“||”的区别)。
此外,关于上述代码的一些注释:
由于我们没有“Dot”和“UnitVector”的源代码,我想那里也可能存在问题。
What's this?
I'd guess that supposed to be:
(note the difference in "|" and "||).
In addition, a few comments about the above code:
Since we don't have the source for "Dot" and "UnitVector", I guess there could be problems there as well.
该线
看起来不正确,尽管这不可能是导致结果的原因,因为
basePoint
是原点。不应该编辑吗:
我又看了一遍,发现了一些问题。首先,您对 d 的定义不正确。您使用了直线方向而不是平面法线,并使用了直线的
topoint
而不是refPoint
。我想指出的是,前者可能会发生,因为您使用了奇怪的命名方案并将线方向组件称为norm11
、norm12
和norm13
>!该行代码应该是我看到的第二个问题是
s
应该是d
/n
而不是n
>/d
。Edit2:
好的,现在尝试删除
d
上的测试,因为我看不出它的意义。当然,您仍然需要对 n 进行测试,因为它现在是您的分母,如果它为零,则意味着直线与平面平行。这是唯一不会有交点的情况(假设该线被视为无限长)。The line
doesn't look right although that can't be what's causing your results since
basePoint
is the origin. Should it not beEdit:
I've had another look and I can see some problems. Firstly, your definition of
d
is incorrect. You've used the line direction instead of the plane normal and thetopoint
of the line instead of therefPoint
. I would point out that the former has probably happened because you've used a bizarre naming scheme and called the line direction componentsnorm11
,norm12
andnorm13
! That line of code should beThe second problem I can see is that
s
should bed
/n
and notn
/d
.Edit2:
Okay now try removing the test on
d
as I can't see the point of it. You still need the test onn
of course since that's now your denominator and if that's zero then that means the line is parallel to the plane. That is the only circumstance under which there will be no intersection (assuming the line is treated as infinitely long).