Skip to content

Commit

Permalink
some work on the divide and conquer algorithm; or rather on dealing w…
Browse files Browse the repository at this point in the history
…ith degeneracies
  • Loading branch information
noinia committed Jun 30, 2024
1 parent bc1f20b commit a00c52d
Showing 1 changed file with 61 additions and 5 deletions.
66 changes: 61 additions & 5 deletions hgeometry/src/HGeometry/Plane/LowerEnvelope/DivideAndConquer.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ module HGeometry.LowerEnvelope.DivideAndConquer
) where

import Control.Lens
import qualified Data.List.NonEmpty as NonEmpty
import Data.List.NonEmpty (NonEmpty(..))
import qualified Data.List.NonEmpty as NonEmpty
import qualified Data.Map as Map
import Data.Word
import HGeometry.HyperPlane.Class
import HGeometry.HyperPlane.NonVertical
import HGeometry.Line.PointAndVector
import qualified HGeometry.Line.LowerEnvelope as LowerEnvelope
import HGeometry.LowerEnvelope.AdjListForm
import HGeometry.LowerEnvelope.EpsApproximation
import qualified HGeometry.LowerEnvelope.Naive as Naive
Expand All @@ -18,7 +20,6 @@ import HGeometry.LowerEnvelope.VertexForm
import HGeometry.Point
import HGeometry.Properties
import Witherable

--------------------------------------------------------------------------------

-- | below this value we use the naive algorithm.
Expand All @@ -34,12 +35,67 @@ eps = 1/8 -- TODO figure out what this had to be again.
--
-- running time: \(O(n \log n)\)
lowerEnvelope :: ( Plane_ plane r
, Ord r, Fractional r, Foldable f, Functor f, Ord plane
, Ord r, Fractional r, Foldable1 f, Functor f, Ord plane
, Show plane, Show r
) => f plane -> LowerEnvelope plane
lowerEnvelope = fromVertexForm . lowerEnvelopeVertexForm
lowerEnvelope hs = case verifyNotAllColinear hs of
JustOnePlane h -> ParallelStrips $ Set.singleton (ParallelPlane h)
AllColinear v -> let lines = fmap (toLine v) hs
env = LowerEnvelope.lowerEnvelope lines
in ParallelStrips $ fromEnv env
NonDegenerate _ -> fromVertexForm . lowerEnvelopeVertexForm $ hs


toLine :: Vector 2 r -> plane -> General r :+ plane
toLine undefined

fromEnv :: LowerEnvelopeF g (Point 2 r) (General r :+ plane) -> Set.Set (ParallelPlane plane)
fromEnv = undefined


-- | Helper type that describes whether the planes are degenerate or not
data VerifyDegenerate plane r = JustOnePlane plane
| AllColinear (Vector 2 r)
-- ^ All edges of the lower envelope are parallel to
-- this direction.
| NonDegenerate (Vector 3 plane)
-- ^ three non-degenrate planes prove that we will have a vertex
deriving (Show,Eq)

-- | Verifies that not all planes are colinear.
verifyNotAllColinear :: ( Plane_ plane r
, Ord r, Fractional r, Foldable1 f, Ord plane
, Show plane, Show r
) => f plane -> VerifyDegenrate plane (NumType plane)
verifyNotAllColinear hs = findOnParalellPlanes (toNonEmpty hs)
where
-- try to find two non-parallel planes h1 h2
findOnParalellPlanes (h1 :| rest) = case NonEmpty.nonEmpty rest of
Nothing -> JustOnePlane h1
Just (h2 :| rest') -> case direction h1 h2 of
Left h' -> findOnParalellPlanes (h' :| rest')
Right l -> findThirdPlane h1 h2 l rest -- find a third plane
where
-- | Tries to compute the vector of the line in which the two planes intersect,
-- returns this vector (if the intersection line exists), or the lowest plane if one
-- is always below the other.
direction h1 h2 = case intersectionLine h1 h2 of
Nothing | evalAt' origin h1 <= evalAt' origin h2 -> Left h1
| otherwise -> Left h2
Just l -> Right $ toPV (l^.direction)

findThirdPlane h1 h2 l = go
where
go = \case
[] -> AllColinear v
(h3 : rest)
| direction h1 h3 `isParallelTo2` l -> go rest
| otherwise -> NonDegnerate $ Vector3 h1 h2 h3

toPV = \case
VerticalLineThrough x -> verticalLine x
NonLinear (LineEQ a b) -> fromLinearFunction a b

-- FIXME: make sure not all planes are parallel first, otherwise the triangulatedEnvelope part is kind of weird.

-- | Compute the vertices of the lower envelope
--
Expand Down

0 comments on commit a00c52d

Please sign in to comment.