ALGO: fix algorithm to show collinear points as part of the hull
There was also a bug to be fixed when doing this. We missed an important pattern match case which casued wrong results.
This commit is contained in:
parent
bfcc9bfdf7
commit
37b38115ae
@ -66,7 +66,7 @@ ccw a b c =
|
|||||||
(bx - ax) *
|
(bx - ax) *
|
||||||
(cy - ay) -
|
(cy - ay) -
|
||||||
(by - ay) *
|
(by - ay) *
|
||||||
(cx - ax) > 0
|
(cx - ax) >= 0
|
||||||
where
|
where
|
||||||
(ax, ay) = unp2 a
|
(ax, ay) = unp2 a
|
||||||
(bx, by) = unp2 b
|
(bx, by) = unp2 b
|
||||||
|
@ -29,7 +29,7 @@ scanHalf (min 3 elem => lowerHull) (min 1 elem => rest)
|
|||||||
= scanHalf (lowerHull + head rest) (tail rest)
|
= scanHalf (lowerHull + head rest) (tail rest)
|
||||||
| otherwise
|
| otherwise
|
||||||
= scanHalf (deleteSndToLastElem lowerHull + head rest)
|
= scanHalf (deleteSndToLastElem lowerHull + head rest)
|
||||||
(tail rest)
|
(rest)
|
||||||
|
|
||||||
scanHalf (min 3 elem => lowerHull ) []
|
scanHalf (min 3 elem => lowerHull ) []
|
||||||
| isCounterClockWise (last3Elements lowerHull) == True
|
| isCounterClockWise (last3Elements lowerHull) == True
|
||||||
@ -37,6 +37,10 @@ scanHalf (min 3 elem => lowerHull ) []
|
|||||||
| otherwise
|
| otherwise
|
||||||
= scanHalf (deleteSndToLastElem lowerHull) []
|
= scanHalf (deleteSndToLastElem lowerHull) []
|
||||||
|
|
||||||
|
scanHalf lowerHull (min 1 elem => rest) = scanHalf (lowerHull + head rest)
|
||||||
|
(tail rest)
|
||||||
|
|
||||||
|
|
||||||
scanHalf lowerHull _ = lowerHull
|
scanHalf lowerHull _ = lowerHull
|
||||||
=== end scanHalf function ===
|
=== end scanHalf function ===
|
||||||
|
|
||||||
@ -87,12 +91,13 @@ grahamGetCH vs =
|
|||||||
-> [PT] -- ^ the rest of the points
|
-> [PT] -- ^ the rest of the points
|
||||||
-> [PT] -- ^ all convex hull points for the half
|
-> [PT] -- ^ all convex hull points for the half
|
||||||
scanH hs@(x:y:z:xs) (r':rs')
|
scanH hs@(x:y:z:xs) (r':rs')
|
||||||
| ccw z y x = scanH (r':hs) rs'
|
| ccw z y x = scanH (r':hs) rs'
|
||||||
| otherwise = scanH (r':x:z:xs) rs'
|
| otherwise = scanH (x:z:xs) (r':rs')
|
||||||
scanH hs@(x:y:z:xs) []
|
scanH hs@(x:y:z:xs) []
|
||||||
| ccw z y x = hs
|
| ccw z y x = hs
|
||||||
| otherwise = scanH (x:z:xs) []
|
| otherwise = scanH (x:z:xs) []
|
||||||
scanH xs _ = xs
|
scanH hs (r':rs') = scanH (r':hs) rs'
|
||||||
|
scanH hs _ = hs
|
||||||
|
|
||||||
|
|
||||||
-- |Compute all steps of the graham scan algorithm to allow
|
-- |Compute all steps of the graham scan algorithm to allow
|
||||||
@ -110,12 +115,15 @@ grahamGetCHSteps vs =
|
|||||||
| otherwise = []
|
| otherwise = []
|
||||||
where
|
where
|
||||||
scanH c' hs@(x:y:z:xs) (r':rs')
|
scanH c' hs@(x:y:z:xs) (r':rs')
|
||||||
| c' >= c = hs
|
| c' >= c = hs
|
||||||
| ccw z y x = scanH (c' + 1) (r':hs) rs'
|
| ccw z y x = scanH (c' + 1) (r':hs) rs'
|
||||||
| otherwise = scanH (c' + 1) (r':x:z:xs) rs'
|
| otherwise = scanH (c' + 1) (x:z:xs) (r':rs')
|
||||||
scanH _ [x,y] [] = [y,x]
|
scanH _ [x,y] [] = [y,x]
|
||||||
scanH c' hs@(x:y:z:xs) []
|
scanH c' hs@(x:y:z:xs) []
|
||||||
| c' >= c = hs
|
| c' >= c = hs
|
||||||
| ccw z y x = hs
|
| ccw z y x = hs
|
||||||
| otherwise = scanH (c' + 1) (x:z:xs) []
|
| otherwise = scanH (c' + 1) (x:z:xs) []
|
||||||
|
scanH c' hs (r':rs')
|
||||||
|
| c' >= c = hs
|
||||||
|
| otherwise = scanH (c' + 1) (r':hs) rs'
|
||||||
scanH _ xs _ = xs
|
scanH _ xs _ = xs
|
||||||
|
Loading…
Reference in New Issue
Block a user