Ich implementiere den Gilbert-Johnson-Keerthi Algorithmus, der berechnet, ob zwei Objekte sich schneiden (dh kollidieren).Wie überprüfe ich, ob ein Simplex den Ursprung enthält?
Der Einstiegspunkt zu meinem Code ist die hasCollided
Funktion, die zwei Listen von Punkten nimmt und True
zurückgibt, wenn sie sich schneiden. Ich glaube, ich habe das Papier korrekt umgesetzt - allerdings muss ich noch die contains
Funktion implementieren.
Die contains
Funktion sollte bestimmen, ob ein Simplex den Ursprung enthält. Ich bin unsicher, wie ich das umsetzen soll.
Wie kann ich effizient feststellen, ob ein Simplex (Punktsammlung) den Ursprung enthält?
Das folgende ist meine Implementierung:
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
Die Helferfunktionen sind:
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]
Nun, wenn die konvexe Hülle der Simplex-Union der Singleton-Satz, der den Ursprung enthält, gleich dem ursprünglichen Simplex ist, dann muss der Ursprung innerhalb des Simplex liegen. Das ist ein (teurer) Weg, es zu tun. –
@ ThomasM.DuBuisson Ich verstehe nicht ganz, was Sie mit dem ursprünglichen Simplex meinen? – sdasdadas
Was ich meine ist: 'enthält simp pnt = nicht $ simp == convexHull (Union simp (Singleton pnt))'. Ich sehe, dass deine 'contains'-Funktion mehr Argumente benötigt, also beantworte ich vielleicht ein anderes Problem als das, was du fragst. –