查找直线是否与球体相交

发布于 2024-09-24 05:54:30 字数 1462 浏览 2 评论 0原文

尝试创建一个非常简单的布尔函数来查找直线是否与球体相交。

尽管问题相似,但这似乎不是我想要的: 直线和球体的交点?

我也尝试过这些算法列出于:

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)

任何帮助将不胜感激。

Trying to make a very simple boolean function that will find whether a line intersects a sphere.

This did not seem to be what I want, even though the question was similar:
Intersection of a line and a Sphere?

Also I have tried the algorithms listed at:

http://www.docstoc.com/docs/7747820/Intersection-of-a-Line-and-a-Sphere

and

http://www.ccs.neu.edu/home/fell/CSU540/programs/RayTracingFormulas.htm

with no real luck.

My most recent code (in Haskell) looks like:

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)

Where it returns true if 2 points have a direct line-of-site.
This works for some simple cases, but fails for others that should work, such as:

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)

Any help would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

草莓味的萝莉 2024-10-01 05:54:30

您使用了错误的方程式。如果您的行表示如下:(

p1 + u (p2 - p1)

其中 u 是标量),则 top/bot 会找到使该表达式尽可能接近的 u可能到达球体的中心。

所以我会修改你的代码:

where u = top/bot
      nearestPoint = {- p1 + u (p2 - p1) -}
      result = {- distance between nearestPoint and p3 -}

填写该伪代码,你应该是黄金。您只是误解了结果的含义。

顺便说一句,您可以使用 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)

You are using the wrong equation. If your line is represented like:

p1 + u (p2 - p1)

(where u is a scalar), then top/bot finds the u that makes that expression as close as possible to the center of the sphere.

So I would amend your code:

where u = top/bot
      nearestPoint = {- p1 + u (p2 - p1) -}
      result = {- distance between nearestPoint and p3 -}

Fill in that pseudocode and you should be golden. You were just misinterpreting the meaning of result.

By the way, you could probably clean up your code a lot by using Data.VectorSpace. I can write out my amendment in full easily using it:

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)
凉栀 2024-10-01 05:54:30

我不知道这是否是最有效的做事方式,但需要考虑的一件事是:

如果从线到球体中心的垂直距离小于或等于半径,则线与球体相交球体。

那么你的问题就变成了:如何计算从点到线的距离?

I don't know if this is the most efficient way to do things, but one thing to consider is:

A line intersects a sphere if the perpendicular distance from the line to the center of the sphere is less than or equal to the radius of the sphere.

Your question then becomes: How do I calculate the distance from a point to a line?

流星番茄 2024-10-01 05:54:30

这是一个懒惰的答案,但以下页面应该包含您想要的信息: http://www .devmaster.net/wiki/Ray-sphere_intersection

更一般地说,谷歌搜索射线球体相交而不是线球体相交应该会产生大量直接的信息。

另外,我认为这本质上是这个问题的重复: 测试线段是否与球体相交< /a>

This is a lazy answer, but the following page should have the information you want: http://www.devmaster.net/wiki/Ray-sphere_intersection

More generally, googling for ray sphere intersection rather than line sphere intersection should yield a wealth of straightforward information.

Also, I think this is essentially a duplicate of this question: Testing whether a line segment intersects a sphere

汹涌人海 2024-10-01 05:54:30

在我看来你想改用

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

e:此处此处

It looks to me like you want instead to use

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. I don't know what Haskell's notation for square is, so I used ^2 above.

e: working here and here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文