diff --git a/hgeometry/data/test-with-ipe/VoronoiDiagram/foo.ipe b/hgeometry/data/test-with-ipe/VoronoiDiagram/foo.ipe new file mode 100644 index 000000000..652066b78 --- /dev/null +++ b/hgeometry/data/test-with-ipe/VoronoiDiagram/foo.ipe @@ -0,0 +1,332 @@ + + + + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +0.6 0 0 0.6 0 0 e +0.4 0 0 0.4 0 0 e + + + + +0.6 0 0 0.6 0 0 e + + + + + +0.5 0 0 0.5 0 0 e + + +0.6 0 0 0.6 0 0 e +0.4 0 0 0.4 0 0 e + + + + + +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h +-0.4 -0.4 m +0.4 -0.4 l +0.4 0.4 l +-0.4 0.4 l +h + + + + +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h + + + + + +-0.5 -0.5 m +0.5 -0.5 l +0.5 0.5 l +-0.5 0.5 l +h + + +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h +-0.4 -0.4 m +0.4 -0.4 l +0.4 0.4 l +-0.4 0.4 l +h + + + + + + +-0.43 -0.57 m +0.57 0.43 l +0.43 0.57 l +-0.57 -0.43 l +h + + +-0.43 0.57 m +0.57 -0.43 l +0.43 -0.57 l +-0.57 0.43 l +h + + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +-1 0.333 m +0 0 l +-1 -0.333 l + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h +-1 0 m +-2 0.333 l +-2 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h +-1 0 m +-2 0.333 l +-2 -0.333 l +h + + + + +0.5 0 m +-0.5 0.333 l +-0.5 -0.333 l +h + + + + +0.5 0 m +-0.5 0.333 l +-0.5 -0.333 l +h + + + + +0.5 0 m +-0.5 0.333 l +-0.3 0 l +-0.5 -0.333 l +h + + + + +0.5 0 m +-0.5 0.333 l +-0.3 0 l +-0.5 -0.333 l +h + + + + +1 0 m +0 0.333 l +0 -0.333 l +h +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +1 0 m +0 0.333 l +0 -0.333 l +h +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hgeometry/data/test-with-ipe/VoronoiDiagram/foo_out.ipe b/hgeometry/data/test-with-ipe/VoronoiDiagram/foo_out.ipe new file mode 100644 index 000000000..b0688f298 --- /dev/null +++ b/hgeometry/data/test-with-ipe/VoronoiDiagram/foo_out.ipe @@ -0,0 +1,204 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +0.6 0 0 0.6 0 0 e 0.4 0 0 0.4 0 0 e + + + +0.6 0 0 0.6 0 0 e + + + +0.5 0 0 0.5 0 0 e + +0.6 0 0 0.6 0 0 e 0.4 0 0 0.4 0 0 e + + + +-0.6 -0.6 m 0.6 -0.6 l 0.6 0.6 l -0.6 0.6 l h +-0.4 -0.4 m 0.4 -0.4 l 0.4 0.4 l -0.4 0.4 l h + + +-0.6 -0.6 m 0.6 -0.6 l 0.6 0.6 l -0.6 0.6 l h + + +-0.5 -0.5 m 0.5 -0.5 l 0.5 0.5 l -0.5 0.5 l h + +-0.6 -0.6 m 0.6 -0.6 l 0.6 0.6 l -0.6 0.6 l h +-0.4 -0.4 m 0.4 -0.4 l 0.4 0.4 l -0.4 0.4 l h + + +-0.43 -0.57 m 0.57 0.43 l 0.43 0.57 l -0.57 -0.43 l h + +-0.43 0.57 m 0.57 -0.43 l 0.43 -0.57 l -0.57 0.43 l h + + + +0 0 m -1.0 0.333 l -1.0 -0.333 l h + + +0 0 m -1.0 0.333 l -1.0 -0.333 l h + + +0 0 m -1.0 0.333 l -0.8 0 l -1.0 -0.333 l h + + +0 0 m -1.0 0.333 l -0.8 0 l -1.0 -0.333 l h + + +0 0 m -1.0 0.333 l -1.0 -0.333 l h + + +0 0 m -1.0 0.333 l -0.8 0 l -1.0 -0.333 l h + + +0 0 m -1.0 0.333 l -0.8 0 l -1.0 -0.333 l h + + +-1.0 0.333 m 0 0 l -1.0 -0.333 l + + +0 0 m -1.0 0.333 l -1.0 -0.333 l h +-1 0 m -2.0 0.333 l -2.0 -0.333 l h + + + +0 0 m -1.0 0.333 l -1.0 -0.333 l h +-1 0 m -2.0 0.333 l -2.0 -0.333 l h + + + + + + +464.975609756097 153.560975609756 m +1000.000000000000 -1184.000000000000 l +481.313432835820 179.701492537313 m +1000.000000000000 237.333333333333 l +427.534883720930 302.883720930232 m +1000.000000000000 446.000000000000 l +112.000000000000 -3312.000000000000 m +111.960000000000 -3313.000000000000 l +375.292035398230 370.053097345132 m +604.363636363636 1000.000000000000 l +241.333333333333 372.666666666666 m +-9.600000000000 1000.000000000000 l +107.555555555555 305.777777777777 m +-1000.000000000000 748.800000000000 l +111.000000000000 148.250000000000 m +-1000.000000000000 426.000000000000 l +107.555555555555 305.777777777777 m +154.285714285714 224.000000000000 l +107.555555555555 305.777777777777 m +241.333333333333 372.666666666666 l +111.000000000000 148.250000000000 m +154.285714285714 224.000000000000 l +111.000000000000 148.250000000000 m +112.000000000000 146.000000000000 l +112.000000000000 -3312.000000000000 m +112.000000000000 146.000000000000 l +112.000000000000 -3312.000000000000 m +248.000000000000 -1000.000000000000 l +112.000000000000 146.000000000000 m +248.000000000000 112.000000000000 l +154.285714285714 224.000000000000 m +220.000000000000 224.000000000000 l +220.000000000000 224.000000000000 m +272.500000000000 161.000000000000 l +220.000000000000 224.000000000000 m +268.571428571428 321.142857142857 l +241.333333333333 372.666666666666 m +271.917525773195 351.257731958762 l +248.000000000000 -1000.000000000000 m +388.075471698113 120.603773584905 l +248.000000000000 -1000.000000000000 m +248.000000000000 112.000000000000 l +248.000000000000 112.000000000000 m +272.500000000000 161.000000000000 l +268.571428571428 321.142857142857 m +341.913043478260 211.130434782608 l +268.571428571428 321.142857142857 m +271.917525773195 351.257731958762 l +271.917525773195 351.257731958762 m +375.292035398230 370.053097345132 l +272.500000000000 161.000000000000 m +325.473684210526 172.771929824561 l +325.473684210526 172.771929824561 m +341.913043478260 211.130434782608 l +325.473684210526 172.771929824561 m +388.075471698113 120.603773584905 l +341.913043478260 211.130434782608 m +425.254901960784 277.803921568627 l +375.292035398230 370.053097345132 m +427.534883720930 302.883720930232 l +388.075471698113 120.603773584905 m +464.975609756097 153.560975609756 l +425.254901960784 277.803921568627 m +427.534883720930 302.883720930232 l +425.254901960784 277.803921568627 m +481.313432835820 179.701492537313 l +464.975609756097 153.560975609756 m +481.313432835820 179.701492537313 l + \ No newline at end of file diff --git a/hgeometry/kernel/src/HGeometry/Box/Boxable.hs b/hgeometry/kernel/src/HGeometry/Box/Boxable.hs index 08c6157d5..a4b20d500 100644 --- a/hgeometry/kernel/src/HGeometry/Box/Boxable.hs +++ b/hgeometry/kernel/src/HGeometry/Box/Boxable.hs @@ -74,6 +74,9 @@ folding1 sfa agb = phantom . traverse1_ agb . sfa -------------------------------------------------------------------------------- -- Instances +instance IsBoxable (Point d r) where + boundingBox p = Box p p + instance ( Box_ (Box point) point , Point_ point d r ) => IsBoxable (Box point) where diff --git a/hgeometry/src/HGeometry/LowerEnvelope/AdjListForm.hs b/hgeometry/src/HGeometry/LowerEnvelope/AdjListForm.hs index 363d81c72..2e3bc1629 100644 --- a/hgeometry/src/HGeometry/LowerEnvelope/AdjListForm.hs +++ b/hgeometry/src/HGeometry/LowerEnvelope/AdjListForm.hs @@ -46,8 +46,9 @@ import qualified Data.Sequence as Seq import qualified Data.Set as Set import Data.Traversable (mapAccumL) import qualified Data.Vector as V -import qualified Data.Vector.NonEmpty as NonEmptyV import Data.Vector.NonEmpty (NonEmptyVector) +import qualified Data.Vector.NonEmpty as NonEmptyV +import HGeometry.Box import HGeometry.Combinatorial.Util import HGeometry.Ext import HGeometry.Foldable.Sort @@ -73,13 +74,23 @@ import Debug.Trace -------------------------------------------------------------------------------- -- * Data type defining a lower envelope --- | The lower envelope in adjacencylist form. +-- | A connected lower envelope in adjacencylist form. +-- +-- invariant: there is always at least one bounded vertex. data LowerEnvelope plane = LowerEnvelope !(UnboundedVertex plane) (Seq.Seq (BoundedVertex plane)) deriving instance (Show plane, Show (NumType plane)) => Show (LowerEnvelope plane) deriving instance (Eq plane, Eq (NumType plane)) => Eq (LowerEnvelope plane) +type instance NumType (LowerEnvelope plane) = NumType plane +type instance Dimension (LowerEnvelope plane) = 3 + +instance (Ord (NumType plane), Num (NumType plane)) => IsBoxable (LowerEnvelope plane) where + -- ^ the bounding box contains all bounded vertices + boundingBox env = boundingBox . NonEmpty.fromList $ env^..boundedVertices.traverse.location + -- the fromList is safe since there is alwasy at least one vertex + -- instance Functor LowerEnvelope where -- instance Foldable LowerEnvelope where -- instance Traversable LowerEnvelope where diff --git a/hgeometry/src/HGeometry/VoronoiDiagram/ViaLowerEnvelope.hs b/hgeometry/src/HGeometry/VoronoiDiagram/ViaLowerEnvelope.hs index ee91f2e05..9ea7f72af 100644 --- a/hgeometry/src/HGeometry/VoronoiDiagram/ViaLowerEnvelope.hs +++ b/hgeometry/src/HGeometry/VoronoiDiagram/ViaLowerEnvelope.hs @@ -20,6 +20,7 @@ module HGeometry.VoronoiDiagram.ViaLowerEnvelope import Control.Lens import Data.Default.Class import qualified Data.Map as Map +import HGeometry.Box import HGeometry.Duality import HGeometry.Ext import HGeometry.HyperPlane.Class @@ -41,7 +42,7 @@ deriving instance (Show point, Show (NumType point)) => Show (VoronoiDiagram poi deriving instance (Eq point, Eq (NumType point)) => Eq (VoronoiDiagram point) type instance NumType (VoronoiDiagram point) = NumType point -type instance Dimension (VoronoiDiagram point) = Dimension point +type instance Dimension (VoronoiDiagram point) = 2 -- Dimension point -- | Iso to Access the underlying LowerEnvelope _VoronoiDiagramLowerEnvelope :: Iso (VoronoiDiagram point) (VoronoiDiagram point') @@ -51,9 +52,8 @@ _VoronoiDiagramLowerEnvelope = coerced -------------------------------------------------------------------------------- - - - +instance (Ord (NumType point), Num (NumType point)) => IsBoxable (VoronoiDiagram point) where + boundingBox vd = projectPoint <$> boundingBox (vd^._VoronoiDiagramLowerEnvelope) -------------------------------------------------------------------------------- diff --git a/hgeometry/test-with-ipe/test/VoronoiDiagram/VoronoiSpec.hs b/hgeometry/test-with-ipe/test/VoronoiDiagram/VoronoiSpec.hs index b1cf1bde3..0c8697eac 100644 --- a/hgeometry/test-with-ipe/test/VoronoiDiagram/VoronoiSpec.hs +++ b/hgeometry/test-with-ipe/test/VoronoiDiagram/VoronoiSpec.hs @@ -18,8 +18,10 @@ import HGeometry.LowerEnvelope.AdjListForm import qualified Data.Set as Set import qualified Data.Sequence as Seq import HGeometry.Number.Real.Rational +import Data.List.NonEmpty (NonEmpty(..)) import HGeometry.Point import HGeometry.Vector +import HGeometry.Box import HGeometry.HalfLine import HGeometry.VoronoiDiagram import Ipe @@ -65,6 +67,8 @@ spec = describe "Voronoi diagram tests" $ do [osp|simple_out|] testIpe [osp|simple1.ipe|] [osp|simple1_out|] + testIpe [osp|foo.ipe|] + [osp|foo_out|] @@ -76,14 +80,21 @@ spec = describe "Voronoi diagram tests" $ do +grow :: (Num r, Point_ point d r) => r -> Box point -> Box point +grow d (Box p q) = Box (p&coordinates %~ subtract d) + (q&coordinates %~ (+d)) + instance (HasDefaultIpeOut point, Point_ point 2 r, Fractional r, Ord r, Default point , Show r, Show point ) => HasDefaultIpeOut (VoronoiDiagram point) where type DefaultIpeOut (VoronoiDiagram point) = Group - defIO vd = ipeGroup $ vd^..edgeGeometries.to iO' - - + defIO vd = ipeGroup $ vd^..edgeGeometries.to render + where + bRect = boundingBox $ defaultBox :| [grow 1 $ boundingBox vd] + render = \case + Left hl -> iO $ ipeHalfLineIn bRect hl + Right seg -> iO' seg instance Default (Point 2 R) where