【发布时间】:2014-03-16 03:53:01
【问题描述】:
我正在实现Gilbert-Johnson-Keerthi 算法,该算法计算两个对象是否相交(即碰撞)。
我的代码的入口点是hasCollided 函数,它接受两个点列表,如果它们相交则返回True。我相信我已经正确地实现了这篇论文 - 但是,我仍然需要实现 contains 函数。
contains 函数应确定单纯形是否包含原点。我不确定如何实现这一点。
如何有效地确定单纯形(点的集合)是否包含原点?
以下是我的实现:
type Simplex = Set (Vector Double)
hasCollided :: [Vector Double] -> [Vector Double] -> Bool
hasCollided points1 points2 = gjk points1 points2 simplex (scale (-1) direction) p
where simplex = insert p empty
p = support points1 points2 direction
direction = fromList [1, 0, 0]
gjk :: [Vector Double] -> [Vector Double] -> Simplex -> Vector Double -> Vector Double -> Bool
gjk points1 points2 simplex direction lastAdded =
if p <.> direction < 0 then False
else
if contains simplex' (fromList [0, 0, 0]) direction p then True
else gjk points1 points2 simplex' direction' p
where p = support points1 points2 direction
simplex' = insert p simplex
direction' = cross ab $ cross ao ab
ab = sub p lastAdded
ao = sub origin3D lastAdded
辅助函数是:
contains :: Simplex -> Vector Double -> Vector Double -> Vector Double -> Bool
contains simplex point direction lastAdded = undefined
support :: [Vector Double] -> [Vector Double] -> Vector Double -> Vector Double
support points1 points2 direction = sub p1 p2
where p1 = getFarthestPoint points1 direction
p2 = getFarthestPoint points2 direction
getFarthestPoint :: [Vector Double] -> Vector Double -> Vector Double
getFarthestPoint points direction = points !! index
where index = fromJust $ elemIndex (maximum dotproducts) dotproducts
dotproducts = map (direction <.>) points
origin3D :: Vector Double
origin3D = fromList [0, 0, 0]
【问题讨论】:
-
如果单纯形联合的凸包包含原点的单例集等于原始单纯形,那么原点必须在单纯形内。这是一种(昂贵的)方法。
-
@ThomasM.DuBuisson 我不太明白你所说的原始单纯形是什么意思?
-
我的意思是:
contains simp pnt = not $ simp == convexHull (union simp (singleton pnt))。我看到你的contains函数需要更多参数,所以也许我回答的问题与你的问题不同。 -
@ThomasM.DuBuisson 我认为是这样,但这可能是我的术语。通过包含,我的意思是原点
(0, 0, 0)位于四面体单纯形的体积内,如果这有意义吗? -
这真的不是关于编程的问题,是吗?更多a mathematics question。无论如何,这是检查单纯形是否包含任何给定点的方法:考虑通过用给定点替换其中一个顶点获得的单纯形。 Compute its volume 并记住结果的符号。对每个顶点执行此操作。如果所有符号都一致,则该点位于单纯形内。延伸阅读:barycentric coordinates
标签: math haskell physics linear-algebra collision