packages feed

hgeometry-0.7.0.0: test/Algorithms/Geometry/PolygonTriangulation/TriangulateMonotoneSpec.hs

module Algorithms.Geometry.PolygonTriangulation.TriangulateMonotoneSpec where

import           Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone
import           Control.Lens
import           Data.Ext
import           Data.Geometry
import           Data.Geometry.Ipe
import           Data.Geometry.Polygon
import qualified Data.List.NonEmpty as NonEmpty
import           Data.Maybe
import qualified Data.Set as Set
import           Data.Vinyl
import           Test.Hspec
import           Util


spec :: Spec
spec = do testCases "test/Algorithms/Geometry/PolygonTriangulation/monotone.ipe"
          testCases "test/Algorithms/Geometry/PolygonTriangulation/simplepolygon6.ipe"

testCases    :: FilePath -> Spec
testCases fp = (runIO $ readInput fp) >>= \case
    Left e    -> it "reading TriangulateMonotone file" $
                   expectationFailure $ "Failed to read ipe file " ++ show e
    Right tcs -> mapM_ toSpec tcs


data TestCase r = TestCase { _polygon  :: MonotonePolygon () r :+ IpeColor r
                           , _solution :: [LineSegment 2 () r]
                           }
                  deriving (Show,Eq)


toSpec                            :: (Num r, Ord r, Show r) => TestCase r -> Spec
toSpec (TestCase (poly :+ c) sol) =
    describe ("testing polygions of color " ++ show c) $ do
      it "comparing with manual solution" $
        (naiveSet $ computeDiagonals poly) `shouldBe` naiveSet sol
  where
    naiveSet = NaiveSet . map S

newtype S p r = S (LineSegment 2 p r) deriving (Show)

instance (Eq p, Eq r) => Eq (S p r) where
  (S s) == (S y) =  (s^.start == y^.start && s^.end == y^.end)
                 || (s^.start == y^.end   && s^.end == y^.start)



-- | Point sets per color, Crosses form the solution
readInput    :: FilePath -> IO (Either ConversionError [TestCase Rational])
readInput fp = fmap f <$> readSinglePageFile fp
  where
    f page = [ TestCase pg (solutionOf pg segs)
             | pg <- map g polies
             ]
      where
        g x@(pg :+ _) = toCounterClockWiseOrder pg :+ lookupColor x

        polies = page^..content.traverse._withAttrs _IpePath _asSimplePolygon
        segs   = page^..content.traverse._withAttrs _IpePath _asLineSegment

        solutionOf (_ :+ c) = map (^.core) . filter ((== c) . lookupColor)


        -- -- | Crosses form a solution
        -- isInSolution s = s^.core.symbolName == "mark/cross(sx)"

        -- right = either (const Nothing) Just
        -- solutionOf = right . fromList . map (^.core.symbolPoint) . filter isInSolution

lookupColor           :: i :+ IpeAttributes Path r -> IpeColor r
lookupColor (_ :+ ats) = fromMaybe (IpeColor $ Named "black") $ lookupAttr SStroke ats