尝试创建一个非常简单的布尔函数,该函数将查找线是否与球体相交。
这似乎不是我想要的,即使问题类似: Intersection of a line and a Sphere?
我也尝试过列出的算法:
http://www.docstoc.com/docs/7747820/Intersection-of-a-Line-and-a-Sphere
和
http://www.ccs.neu.edu/home/fell/CSU540/programs/RayTracingFormulas.htm
没有真正的运气。
我最近的代码(在Haskell中)看起来像:
data Point = Point { x :: Float, y :: Float, z :: Float} deriving (Eq, Show, Read)
data Sphere = Sphere { center :: Point, radius :: Float } deriving (Eq, Show, Read)
inView :: Point -> Point -> Sphere -> Bool
inView (Point x1 y1 z1) (Point x2 y2 z2) (Sphere (Point x3 y3 z3) r)
| result > 0 && result < r = False
| otherwise = True
where result = top/bot
top = (x3 - x1) * (x2 - x1) + (y3 - y1) * (y2 - y1) + (z3 - z1) * (z2 - z1)
bot = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) + (z2 - z1) * (z2 - z1)
如果2个点具有直接的站点行,则返回true。 这适用于一些简单的情况,但对于应该工作的其他情况则无效,例如:
inView (Point {x = 43.64, y = -183.20, z = 187.37}) (Point {x = 42.04, y = -183.58, z = 187.37}) (Sphere (Point 0 0 0) 5)
任何帮助都将不胜感激。
答案 0 :(得分:2)
您使用的是错误的等式。如果您的行代表如下:
p1 + u (p2 - p1)
(其中u
是标量),然后top/bot
找到u
,使该表达式尽可能接近球体的中心。
所以我会修改你的代码:
where u = top/bot
nearestPoint = {- p1 + u (p2 - p1) -}
result = {- distance between nearestPoint and p3 -}
填写那个伪代码,你应该是金色的。你只是误解了result
的含义。
顺便说一句,您可以使用Data.VectorSpace
大量清理代码。我可以很容易地用它来写出我的修正案:
import Data.VectorSpace
type Point = (Double, Double, Double)
inView :: Point -> Point -> Sphere -> Bool
inView p1 p2 (Sphere p3 r) = result < r
where u = top/bot
top = ...
bot = ...
nearestPoint = p1 ^+^ u *^ (p2 ^-^ p1)
result = magnitude (p3 ^-^ nearestPoint)
答案 1 :(得分:1)
我不知道这是否是最有效的做事方式,但有一点需要考虑:
如果从直线到球体中心的垂直距离小于或等于球体的半径,则直线与球体相交。
然后你的问题变成:我如何计算从一个点到一条线的距离?
答案 2 :(得分:0)
这是一个懒惰的答案,但以下页面应该包含您想要的信息:http://www.devmaster.net/wiki/Ray-sphere_intersection
更一般地说,谷歌搜索光线球体交叉而不是线球交叉应该产生大量简单的信息。
另外,我认为这基本上是这个问题的重复:Testing whether a line segment intersects a sphere
答案 3 :(得分:0)
在我看来,你想要改为使用
inView :: Point -> Point -> Sphere -> Bool
inView (Point x1 y1 z1) (Point x2 y2 z2) (Sphere (Point x3 y3 z3) r)
| result > 0 && result < r^2 = False // is this correct? I know nothing about Haskell, but seems like this should be True
| otherwise = True
where result = -t1^2/t2 + t3
t1 = (x3 - x1) * (x2 - x1) + (y3 - y1) * (y2 - y1) + (z3 - z1) * (z2 - z1)
t2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) + (z2 - z1) * (z2 - z1)
t3 = (x3 - x1) * (x3 - x1) + (y3 - y1) * (y3 - y1) + (z3 - z1) * (z3 - z1)
NB。我不知道Haskell的方格符号是什么,所以我使用了上面的^2
。