Skip to content

Commit

Permalink
Read a Polygonal domain from Ipe (#260)
Browse files Browse the repository at this point in the history
* read polygons with holes

* reading polygonal domains from ipe files

* make it compile

* disabled a buggy test

* fixed the tests
  • Loading branch information
noinia authored Dec 22, 2024
1 parent e3c363e commit b552e60
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 38 deletions.
2 changes: 1 addition & 1 deletion hgeometry/hgeometry.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ library
HGeometry.Polygon.Convex.MinkowskiSum
HGeometry.Polygon.Triangulation.Types

-- HGeometry.PlaneGraph.Type
HGeometry.PlaneGraph.Type
HGeometry.PlaneGraph.Connected.Type

HGeometry.LineSegment.Intersection.Types
Expand Down
3 changes: 2 additions & 1 deletion hgeometry/ipe/src/Ipe.hs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ module Ipe(
, _asPolyLine
, _asSimplePolygon
, _asConvexPolygon
-- , _asSomePolygon, _asSimplePolygon, _asMultiPolygon
, _asPolygonalDomain

-- *** Dealing with Attributes
, _withAttrs
-- ** Default readers
Expand Down
26 changes: 25 additions & 1 deletion hgeometry/ipe/src/Ipe/FromIpe.hs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ module Ipe.FromIpe(
, _asPolyLine
, _asSimplePolygon
, _asConvexPolygon
-- , _asSomePolygon, _asSimplePolygon, _asMultiPolygon
, _asPolygonalDomain

, toPolygonalDomain

-- * Dealing with Attributes
, _withAttrs
Expand All @@ -36,24 +38,29 @@ module Ipe.FromIpe(
import Control.Lens hiding (Simple)
import Data.Kind (Type)
import qualified Data.Sequence as Seq
import Data.Vector.NonEmpty (NonEmptyVector)
import HGeometry.Ball
import HGeometry.Box
import qualified HGeometry.Box as Box
import HGeometry.Cyclic
import HGeometry.Ellipse (Ellipse, _EllipseCircle)
import HGeometry.Ext
import HGeometry.Foldable.Util
import HGeometry.LineSegment
import HGeometry.Number.Radical
import HGeometry.Point
import qualified HGeometry.PolyLine as PolyLine
import HGeometry.Polygon.Class
import HGeometry.Polygon.Convex
import HGeometry.Polygon.Simple
import HGeometry.Polygon.WithHoles
import HGeometry.Properties
import HGeometry.Triangle
import Ipe.Path
import Ipe.Reader
import Ipe.Types
import System.OsPath
import Witherable

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

Expand Down Expand Up @@ -127,6 +134,23 @@ _asSimplePolygon = prism' polygonToPath pathToPolygon
_asConvexPolygon :: (Num r, Ord r) => Prism' (Path r) (ConvexPolygon (Point 2 r))
_asConvexPolygon = _asSimplePolygon._ConvexPolygon

-- | Convert to a polygonal domain
_asPolygonalDomain :: Prism' (Path r) (PolygonalDomain (Point 2 r))
_asPolygonalDomain = prism' toPath toDomain
where
toPath (PolygonalDomain outer' holes') =
Path $ (pathPiece outer' Seq.<| fromFoldable (fmap pathPiece holes'))
pathPiece = PolygonPath AsIs

toDomain path = over theHoles fromFoldable <$> toPolygonalDomain path

-- | Convert to a path to a Polygonal Domain
toPolygonalDomain :: Path r
-> Maybe (PolygonalDomainF Seq.Seq (Cyclic NonEmptyVector) (Point 2 r))
toPolygonalDomain path = case mapMaybe (preview (_PolygonPath._2)) (path^.pathSegments) of
outer' Seq.:<| holes' -> Just $ PolygonalDomain outer' holes'
_ -> Nothing

-- | Tries to convert a path into a rectangle.
_asRectangle :: forall r. (Num r, Ord r) => Prism' (Path r) (Rectangle (Point 2 r))
_asRectangle = prism' rectToPath pathToRect
Expand Down
35 changes: 11 additions & 24 deletions hgeometry/src/HGeometry/PlaneGraph/Type.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
--------------------------------------------------------------------------------
module HGeometry.PlaneGraph.Type
( PlaneGraph(..)
, fromAdjacencyRep
, fromConnectedSegments
-- , fromAdjacencyRep
-- , fromConnectedSegments
-- , VertexData(VertexData), location

, E(..)
-- , E(..)
) where

import Control.Lens hiding (holes, holesOf, (.=))
Expand Down Expand Up @@ -55,7 +55,7 @@ import qualified Hiraffe.PlanarGraph.Dart as Dart

-- | An Embedded, *connected*, planar graph
newtype PlaneGraph s v e f = PlaneGraph (PlanarGraph Primal s v e f)
deriving stock (Show,Eq,Generic)
-- deriving stock (Show,Eq,Generic)
-- deriving newtype (ToYAML,FromYAML)

type instance NumType (PlaneGraph s v e f) = NumType v
Expand Down Expand Up @@ -114,49 +114,34 @@ instance DiGraph_ (PlaneGraph s v e f) where
twinDartOf d = twinOf d . to Just
outgoingDartsOf v = _PlanarGraph.outgoingDartsOf v

{-
instance ConstructableDiGraph_ (PlaneGraph s v e f) where
type DiGraphFromAdjListExtraConstraints (PlaneGraph s v e f) h = (f ~ (), Foldable1 h)
-- | The vertices are expected to have their adjacencies in CCW order.
diGraphFromAdjacencyLists = PlaneGraph . diGraphFromAdjacencyLists
-- TODO: we should probably use some toEmbedding here as well I think

-}

instance BidirGraph_ (PlaneGraph s v e f) where
twinOf d = to $ const (PG.twin d)
getPositiveDart (PlaneGraph g) e = getPositiveDart g e


-- | Computes the cyclic order of adjacencies around each vertex.
--
-- \(O(n \log n)\)
toEmbedding :: ( Foldable1 g, Functor g, Foldable h, Functor h
, vi ~ VertexIx (PlaneGraph s v e f)
, v ~ Vertex (PlaneGraph s v e f)
, e ~ Edge (PlaneGraph s v e f)
, GraphFromAdjListExtraConstraints (PlaneGraph s v e f) h
, Point_ v 2 r, Ord r, Num r
) => g (vi, v, h (vi, e)) -> g (vi, v, Vector.NonEmptyVector (vi, e))
toEmbedding vs = fmap sortAround' vs
where
vertexLocs = foldMap (\(vi,v,_) -> Map.singleton vi v) vs
sortAround' (vi,v,adjs) = (vi,v, Vector.unsafeFromVector $ sortBy (ccwCmpAround' v) adjs)
ccwCmpAround' v (ui,_) (wi,_) = ccwCmpAround v (vertexLocs Map.! ui) (vertexLocs Map.! wi)



instance ( Point_ v 2 (NumType v)
, Ord (NumType v), Num (NumType v)
) => Graph_ (PlaneGraph s v e f) where
neighboursOf u = _PlanarGraph.neighboursOf u
incidentEdgesOf u = _PlanarGraph.incidentEdgesOf u

{-
instance ( Point_ v 2 (NumType v)
, Ord (NumType v), Num (NumType v)
) => ConstructableGraph_ (PlaneGraph s v e f) where
type GraphFromAdjListExtraConstraints (PlaneGraph s v e f) h = (f ~ (), Foldable1 h)
fromAdjacencyLists = fromEmbedding . toEmbedding
-}

{-
instance ( Point_ v 2 (NumType v)
, Ord (NumType v), Num (NumType v)
Expand Down Expand Up @@ -262,3 +247,5 @@ instance (Ord r, Num r) => Eq (E r) where
a == b = a `compare` b == EQ
instance (Ord r, Num r) => Ord (E r) where
(E v) `compare` (E u) = ccwCmpAroundWith (Vector2 0 1) (origin :: Point 2 r) (Point v) (Point u)
-}
7 changes: 4 additions & 3 deletions hgeometry/test/ConvexHull/R3Spec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ type R = RealNumber 5


spec = describe "3D convex hull through duality tests " $ do
fit "single triangle" $ do
let tri = Triangle origin (Point3 10 0 1) (Point3 0 10 2 :: Point 3 R)
Dual.facets (traceShowWith ("hull",) $ Dual.upperHull tri) `shouldBe` []
pure ()
-- fit "single triangle" $ do
-- let tri = Triangle origin (Point3 10 0 1) (Point3 0 10 2 :: Point 3 R)
-- Dual.facets (traceShowWith ("hull",) $ Dual.upperHull tri) `shouldBe` []
-- FIXME: This is actually incorrect. I think it should be the thing below:
-- Dual.facets (traceShowWith ("hull",) $ Dual.upperHull tri) `shouldBe` [toNonEmpty tri]
7 changes: 7 additions & 0 deletions hgeometry/test/Polygon/SeqSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Data.Maybe
import qualified Data.Sequence as Seq
import qualified Data.Vector.NonEmpty as NV
import HGeometry.Cyclic
import HGeometry.Number.Real.Rational
import HGeometry.Point
import HGeometry.Polygon
import HGeometry.Polygon.Instances ()
Expand Down Expand Up @@ -101,3 +102,9 @@ spec = describe "Polygon with Seq1 spec" $ do
prop "cw traversals consistent" $
\(pg :: SimplePolygon (Point 2 Rational)) (i :: Int) ->
itoListOf (cwOuterBoundaryFrom i) pg === itoListOf (cwOuterBoundaryFrom i) (toSeqPoly pg)

it "gets rid of duplicate points at the beginning and end" $
let myPoly :: SimplePolygon (Point 2 (RealNumber 5))
myPoly = fromJust . fromPoints $
read @[Point 2 (RealNumber 5)] "[Point2 0 0,Point2 26 37.1,Point2 7.1 45.2,Point2 (-6.6) 39,Point2 (-1.9) 15.1,Point2 (-1.4) 12.7,Point2 0 0]"
in myPoly^..vertices `shouldBe` [Point2 26 37.1,Point2 7.1 45.2,Point2 (-6.6) 39,Point2 (-1.9) 15.1,Point2 (-1.4) 12.7,Point2 0 0]
3 changes: 2 additions & 1 deletion hgeometry/test/Polygon/TriangulateSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ graphPolygons :: (Ord r, Num r, Point_ point 2 r)
graphPolygons gr = map (&vertices %~ view (core.asPoint)) $ gr^..interiorFacePolygons

buggyPolygon2 :: SimplePolygon (Point 2 R)
buggyPolygon2 = read "SimplePolygon [Point2 2589.22 470.87,Point2 2588.68 470.97,Point2 2587.88 471.15,Point2 2587.5 471.28,Point2 2586.96 471.57,Point2 2586.46 471.9,Point2 2586.4 472.02,Point2 2586.87 472.14,Point2 2587.24 472.17,Point2 2588.02 472.06,Point2 2588.79 471.9,Point2 2589.55 471.71,Point2 2590.7 471.38,Point2 2591.07 471.26,Point2 2591.17 471.12,Point2 2591.09 470.96,Point2 2590.87 470.84,Point2 2590.42 470.81,Point2 2589.98 470.8]"
buggyPolygon2 = fromJust . fromPoints $
read @[Point 2 R] "[Point2 2589.22 470.87,Point2 2588.68 470.97,Point2 2587.88 471.15,Point2 2587.5 471.28,Point2 2586.96 471.57,Point2 2586.46 471.9,Point2 2586.4 472.02,Point2 2586.87 472.14,Point2 2587.24 472.17,Point2 2588.02 472.06,Point2 2588.79 471.9,Point2 2589.55 471.71,Point2 2590.7 471.38,Point2 2591.07 471.26,Point2 2591.17 471.12,Point2 2591.09 470.96,Point2 2590.87 470.84,Point2 2590.42 470.81,Point2 2589.98 470.8]"

buggySimplified :: SimplePolygon (Point 2 R)
buggySimplified = fromJust . fromPoints $
Expand Down
2 changes: 1 addition & 1 deletion hgeometry/test/Polygon/Triangulation/MakeMonotoneSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import Control.Lens
import Data.Maybe (fromJust)
import qualified Data.Set as Set
import HGeometry.Ext
import HGeometry.Point
import HGeometry.LineSegment
import HGeometry.Point
import HGeometry.Polygon.Class
import HGeometry.Polygon.Simple
import HGeometry.Polygon.Triangulation.MakeMonotone
Expand Down
29 changes: 23 additions & 6 deletions todo.org
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,30 @@ initial run that actually triangulates the whole world:

cabal run hgeometry-examples:hgeometry-triangulateworld -- -i -o 130.82s user 0.50s system 99% cpu 2:12.23 total




** DONE verify fromPoints

i.e. add a test that makes sure that the cyclic zero's are correct,
i.e. that

myPoly :: SimplePolygon (Point 2 R)
myPoly = fromJust . fromPoints $
read @[Point 2 R] "[Point2 0 0,Point2 26 37.1,Point2 7.1 45.2,Point2 (-6.6) 39,Point2 (-1.9) 15.1,Point2 (-1.4) 12.7,Point2 0 0]"

sanitizes the two Point2 0 0's at the end and the start



** TODO polygons with holes
*** DONE represent polygons with holes
*** TODO inpolygon test
make sure we can report in which hole we are as well
*** TODO some tests
*** TODO render them to ipe
*** DONE render them to ipe
*** TODO intersect with a line or with a segment

* DONE avoid binary files in the tests ; replace them with json files or so
(in particular, the arbitrary instances for polygon)

Expand All @@ -148,7 +165,7 @@ make sure we can report in which hole we are as well
* TODO arrangement
** TODO line-segment-intersection sweep
** TODO planar subdivision
*** TODO plane graph
*** DONE plane graph

* TODO 3d-lower-envelope
** TODO naive
Expand Down Expand Up @@ -193,8 +210,8 @@ guaranteed to appear: )

** TODO 3d convex hull

** TODO render faces as polygons
** TODO 3d export of the lower envelope
** DONE render faces as polygons
** DONE 3d export of the lower envelope

* DONE Convex polygons
** DONE binary search extremal direction
Expand Down Expand Up @@ -226,8 +243,8 @@ guaranteed to appear: )
** TODO linear programming (RIC)

* TODO delaunay triangulation
* TODO voronoi diagram
** TODO all colinear points
* DONE voronoi diagram
** DONE all colinear points
* DONE closest pair
* DONE minkowski-sum
** DONE fix testcases
Expand Down

0 comments on commit b552e60

Please sign in to comment.