wumpus-basic 0.9.0 → 0.10.0
raw patch · 38 files changed
+1644/−1023 lines, 38 filesdep ~wumpus-corePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: wumpus-core
API changes (from Hackage documentation)
- Wumpus.Basic.Anchors: baselineSW :: (TextAnchor t, (DUnit t) ~ u) => t -> Point2 u
- Wumpus.Basic.Anchors: class TextAnchor t
- Wumpus.Basic.Arrows: line :: (Num u) => ConnPath u -> ConnImage u (Path u)
- Wumpus.Basic.Graphic.BaseClasses: askCtx :: (DrawingCtxM m) => m DrawingContext
- Wumpus.Basic.Graphic.BaseClasses: asksCtx :: (DrawingCtxM m) => (DrawingContext -> a) -> m a
- Wumpus.Basic.Graphic.BaseClasses: class (Monad m) => DrawingCtxM m :: (* -> *)
- Wumpus.Basic.Graphic.BaseClasses: class (Monad m) => PointSupplyM m :: (* -> *)
- Wumpus.Basic.Graphic.BaseClasses: class ScalingM m where { type family XDim m :: *; type family YDim m :: *; }
- Wumpus.Basic.Graphic.BaseClasses: class (Monad m) => TraceM m :: (* -> *)
- Wumpus.Basic.Graphic.BaseClasses: localCtx :: (DrawingCtxM m) => (DrawingContext -> DrawingContext) -> m a -> m a
- Wumpus.Basic.Graphic.BaseClasses: position :: (PointSupplyM m, u ~ (MonUnit m)) => m (Point2 u)
- Wumpus.Basic.Graphic.BaseClasses: scalePt :: (ScalingM m, u ~ (MonUnit m), ux ~ (XDim m), uy ~ (YDim m)) => ux -> uy -> m (Point2 u)
- Wumpus.Basic.Graphic.BaseClasses: scaleVec :: (ScalingM m, u ~ (MonUnit m), ux ~ (XDim m), uy ~ (YDim m)) => ux -> uy -> m (Vec2 u)
- Wumpus.Basic.Graphic.BaseClasses: scaleX :: (ScalingM m, u ~ (MonUnit m), ux ~ (XDim m)) => ux -> m u
- Wumpus.Basic.Graphic.BaseClasses: scaleY :: (ScalingM m, u ~ (MonUnit m), uy ~ (YDim m)) => uy -> m u
- Wumpus.Basic.Graphic.BaseClasses: trace :: (TraceM m) => HPrim (MonUnit m) -> m ()
- Wumpus.Basic.Graphic.BaseTypes: askDF :: DrawingF DrawingContext
- Wumpus.Basic.Graphic.BaseTypes: asksDF :: (DrawingContext -> a) -> DrawingF a
- Wumpus.Basic.Graphic.BaseTypes: data DrawingF a
- Wumpus.Basic.Graphic.BaseTypes: data HPrim u
- Wumpus.Basic.Graphic.BaseTypes: hprimToList :: HPrim u -> [PrimElement u]
- Wumpus.Basic.Graphic.BaseTypes: instance (Monoid a) => Monoid (DrawingF a)
- Wumpus.Basic.Graphic.BaseTypes: instance Applicative DrawingF
- Wumpus.Basic.Graphic.BaseTypes: instance Functor DrawingF
- Wumpus.Basic.Graphic.BaseTypes: instance Monad DrawingF
- Wumpus.Basic.Graphic.BaseTypes: instance Monoid (HPrim u)
- Wumpus.Basic.Graphic.BaseTypes: intoConnImage :: ConnDrawingF u a -> ConnGraphic u -> ConnImage u a
- Wumpus.Basic.Graphic.BaseTypes: intoImage :: DrawingF a -> Graphic u -> Image u a
- Wumpus.Basic.Graphic.BaseTypes: intoLocImage :: LocDrawingF u a -> LocGraphic u -> LocImage u a
- Wumpus.Basic.Graphic.BaseTypes: lgappend :: LocGraphic u -> LocGraphic u -> LocGraphic u
- Wumpus.Basic.Graphic.BaseTypes: localDF :: (DrawingContext -> DrawingContext) -> DrawingF a -> DrawingF a
- Wumpus.Basic.Graphic.BaseTypes: localLG :: (DrawingContext -> DrawingContext) -> LocGraphic u -> LocGraphic u
- Wumpus.Basic.Graphic.BaseTypes: pureDF :: a -> DrawingF a
- Wumpus.Basic.Graphic.BaseTypes: runDF :: DrawingContext -> DrawingF a -> a
- Wumpus.Basic.Graphic.BaseTypes: runGraphic :: DrawingContext -> Graphic u -> HPrim u
- Wumpus.Basic.Graphic.BaseTypes: runImage :: DrawingContext -> Image u a -> (a, HPrim u)
- Wumpus.Basic.Graphic.BaseTypes: singleH :: PrimElement u -> HPrim u
- Wumpus.Basic.Graphic.BaseTypes: type ConnDrawingF u a = Point2 u -> Point2 u -> DrawingF a
- Wumpus.Basic.Graphic.BaseTypes: type ConnGraphic u = Point2 u -> Point2 u -> Graphic u
- Wumpus.Basic.Graphic.BaseTypes: type ConnImage u a = Point2 u -> Point2 u -> Image u a
- Wumpus.Basic.Graphic.BaseTypes: type DConnDrawingF a = ConnDrawingF Double a
- Wumpus.Basic.Graphic.BaseTypes: type DConnGraphic = ConnGraphic Double
- Wumpus.Basic.Graphic.BaseTypes: type DConnImage a = ConnImage Double a
- Wumpus.Basic.Graphic.BaseTypes: type DGraphic = Graphic Double
- Wumpus.Basic.Graphic.BaseTypes: type DImage a = Image Double a
- Wumpus.Basic.Graphic.BaseTypes: type DLocDrawingF a = LocDrawingF Double a
- Wumpus.Basic.Graphic.BaseTypes: type DLocGraphic = LocGraphic Double
- Wumpus.Basic.Graphic.BaseTypes: type DLocImage a = LocImage Double a
- Wumpus.Basic.Graphic.BaseTypes: type DPoint2F = Point2F Double
- Wumpus.Basic.Graphic.BaseTypes: type Graphic u = DrawingF (HPrim u)
- Wumpus.Basic.Graphic.BaseTypes: type Image u a = DrawingF (a, HPrim u)
- Wumpus.Basic.Graphic.BaseTypes: type LocDrawingF u a = Point2 u -> DrawingF a
- Wumpus.Basic.Graphic.BaseTypes: type LocGraphic u = Point2 u -> Graphic u
- Wumpus.Basic.Graphic.BaseTypes: type LocImage u a = Point2 u -> Image u a
- Wumpus.Basic.Graphic.BaseTypes: type Point2F u = Point2 u -> Point2 u
- Wumpus.Basic.Graphic.BaseTypes: xlinkGraphic :: XLink -> Graphic u -> Graphic u
- Wumpus.Basic.Graphic.BaseTypes: xlinkImage :: XLink -> Image u a -> Image u a
- Wumpus.Basic.Graphic.DrawingContext: bothPrimary :: DrawingContext -> DrawingContext
- Wumpus.Basic.Graphic.DrawingContext: bothSecondary :: DrawingContext -> DrawingContext
- Wumpus.Basic.Graphic.DrawingContext: primaryColour :: RGBi -> DrawingContext -> DrawingContext
- Wumpus.Basic.Graphic.DrawingContext: primary_colour :: DrawingContext -> RGBi
- Wumpus.Basic.Graphic.DrawingContext: secondaryColour :: RGBi -> DrawingContext -> DrawingContext
- Wumpus.Basic.Graphic.DrawingContext: secondary_colour :: DrawingContext -> RGBi
- Wumpus.Basic.Paths.Base: Curve :: Point2 u -> Point2 u -> Point2 u -> Point2 u -> Curve u
- Wumpus.Basic.Paths.Base: CurveSeg :: u -> (Curve u) -> PathSeg u
- Wumpus.Basic.Paths.Base: Line :: Point2 u -> Point2 u -> Line u
- Wumpus.Basic.Paths.Base: LineSeg :: u -> (Line u) -> PathSeg u
- Wumpus.Basic.Paths.Base: Path :: u -> Seq (PathSeg u) -> Path u
- Wumpus.Basic.Paths.Base: addSegment :: (Num u) => Path u -> PathSeg u -> Path u
- Wumpus.Basic.Paths.Base: ctrl_point1 :: Curve u -> Point2 u
- Wumpus.Basic.Paths.Base: ctrl_point2 :: Curve u -> Point2 u
- Wumpus.Basic.Paths.Base: curve_end :: Curve u -> Point2 u
- Wumpus.Basic.Paths.Base: curve_start :: Curve u -> Point2 u
- Wumpus.Basic.Paths.Base: data Curve u
- Wumpus.Basic.Paths.Base: data Line u
- Wumpus.Basic.Paths.Base: data PathSeg u
- Wumpus.Basic.Paths.Base: emptyPath :: (Num u) => Path u
- Wumpus.Basic.Paths.Base: instance (Eq u) => Eq (Curve u)
- Wumpus.Basic.Paths.Base: instance (Eq u) => Eq (Line u)
- Wumpus.Basic.Paths.Base: instance (Ord u) => Ord (Curve u)
- Wumpus.Basic.Paths.Base: instance (Ord u) => Ord (Line u)
- Wumpus.Basic.Paths.Base: instance (Show u) => Show (Curve u)
- Wumpus.Basic.Paths.Base: instance (Show u) => Show (Line u)
- Wumpus.Basic.Paths.Base: line_end :: Line u -> Point2 u
- Wumpus.Basic.Paths.Base: line_start :: Line u -> Point2 u
- Wumpus.Basic.Paths.Base: path_elements :: Path u -> Seq (PathSeg u)
- Wumpus.Basic.Paths.Base: path_length :: Path u -> u
- Wumpus.Basic.Paths.Base: pcurve :: (Floating u, Ord u) => Point2 u -> Point2 u -> Point2 u -> Point2 u -> PathSeg u
- Wumpus.Basic.Paths.Base: pline :: (Floating u) => Point2 u -> Point2 u -> PathSeg u
- Wumpus.Basic.Paths.Base: segmentEnd :: PathSeg u -> Point2 u
- Wumpus.Basic.Paths.Base: segmentLength :: PathSeg u -> u
- Wumpus.Basic.Paths.Base: segmentStart :: PathSeg u -> Point2 u
- Wumpus.Basic.Paths.Base: subdivide :: (Fractional u) => Curve u -> (Curve u, Curve u)
- Wumpus.Basic.Paths.Base: subdividet :: (Real u) => u -> Curve u -> (Curve u, Curve u)
- Wumpus.Basic.Paths.Connectors: arbh :: (Floating u) => u -> ConnPath u
- Wumpus.Basic.Paths.Connectors: arbv :: (Floating u) => u -> ConnPath u
- Wumpus.Basic.Paths.Connectors: connectS :: (Floating u) => ConnPath u
- Wumpus.Basic.Paths.Connectors: directionL :: (Real u, Floating u) => Path u -> Radian
- Wumpus.Basic.Paths.Connectors: directionR :: (Real u, Floating u) => Path u -> Radian
- Wumpus.Basic.Paths.Connectors: fillPath :: (Num u) => Path u -> Graphic u
- Wumpus.Basic.Paths.Connectors: midpoint :: (Real u, Floating u) => Path u -> Point2 u
- Wumpus.Basic.Paths.Connectors: pathGraphic :: (Num u) => ConnPath u -> ConnGraphic u
- Wumpus.Basic.Paths.Connectors: shorten :: (Real u, Floating u, Ord u) => u -> Path u -> Path u
- Wumpus.Basic.Paths.Connectors: shortenL :: (Real u, Floating u, Ord u) => u -> Path u -> Path u
- Wumpus.Basic.Paths.Connectors: shortenR :: (Real u, Floating u, Ord u) => u -> Path u -> Path u
- Wumpus.Basic.Paths.Connectors: type ConnPath u = Point2 u -> Point2 u -> Path u
+ Wumpus.Basic.Arrows: arrowRBracket :: (Real u, Floating u, FromPtSize u) => Connector u -> ConnImage u (Path u)
+ Wumpus.Basic.Arrows: cline :: (Num u) => Connector u -> ConnImage u (Path u)
+ Wumpus.Basic.Arrows.Tips: rbracket :: (Floating u, FromPtSize u) => Radian -> LocGraphic u
+ Wumpus.Basic.Graphic.Base: askDC :: (DrawingCtxM m) => m DrawingContext
+ Wumpus.Basic.Graphic.Base: asksDC :: (DrawingCtxM m) => (DrawingContext -> a) -> m a
+ Wumpus.Basic.Graphic.Base: class (Monad m) => DrawingCtxM m :: (* -> *)
+ Wumpus.Basic.Graphic.Base: class (Monad m) => PointSupplyM m :: (* -> *)
+ Wumpus.Basic.Graphic.Base: class (Monad m) => TraceM m :: (* -> *)
+ Wumpus.Basic.Graphic.Base: data DrawingR a
+ Wumpus.Basic.Graphic.Base: data HPrim u
+ Wumpus.Basic.Graphic.Base: hprimToList :: HPrim u -> [PrimElement u]
+ Wumpus.Basic.Graphic.Base: instance (Monoid a) => Monoid (DrawingR a)
+ Wumpus.Basic.Graphic.Base: instance Applicative DrawingR
+ Wumpus.Basic.Graphic.Base: instance DrawingCtxM DrawingR
+ Wumpus.Basic.Graphic.Base: instance Functor DrawingR
+ Wumpus.Basic.Graphic.Base: instance Monad DrawingR
+ Wumpus.Basic.Graphic.Base: instance Monoid (HPrim u)
+ Wumpus.Basic.Graphic.Base: intoConnImage :: ConnDrawingR u a -> ConnGraphic u -> ConnImage u a
+ Wumpus.Basic.Graphic.Base: intoImage :: DrawingR a -> Graphic u -> Image u a
+ Wumpus.Basic.Graphic.Base: intoLocImage :: LocDrawingR u a -> LocGraphic u -> LocImage u a
+ Wumpus.Basic.Graphic.Base: localize :: (DrawingCtxM m) => (DrawingContext -> DrawingContext) -> m a -> m a
+ Wumpus.Basic.Graphic.Base: position :: (PointSupplyM m, u ~ (MonUnit m)) => m (Point2 u)
+ Wumpus.Basic.Graphic.Base: runDrawingR :: DrawingContext -> DrawingR a -> a
+ Wumpus.Basic.Graphic.Base: runGraphic :: DrawingContext -> Graphic u -> HPrim u
+ Wumpus.Basic.Graphic.Base: runImage :: DrawingContext -> Image u a -> (a, HPrim u)
+ Wumpus.Basic.Graphic.Base: singleH :: PrimElement u -> HPrim u
+ Wumpus.Basic.Graphic.Base: trace :: (TraceM m) => HPrim (MonUnit m) -> m ()
+ Wumpus.Basic.Graphic.Base: type ConnDrawingR u a = Point2 u -> Point2 u -> DrawingR a
+ Wumpus.Basic.Graphic.Base: type ConnGraphic u = Point2 u -> Point2 u -> Graphic u
+ Wumpus.Basic.Graphic.Base: type ConnImage u a = Point2 u -> Point2 u -> Image u a
+ Wumpus.Basic.Graphic.Base: type DConnDrawingR a = ConnDrawingR Double a
+ Wumpus.Basic.Graphic.Base: type DConnGraphic = ConnGraphic Double
+ Wumpus.Basic.Graphic.Base: type DConnImage a = ConnImage Double a
+ Wumpus.Basic.Graphic.Base: type DGraphic = Graphic Double
+ Wumpus.Basic.Graphic.Base: type DImage a = Image Double a
+ Wumpus.Basic.Graphic.Base: type DLocDrawingR a = LocDrawingR Double a
+ Wumpus.Basic.Graphic.Base: type DLocGraphic = LocGraphic Double
+ Wumpus.Basic.Graphic.Base: type DLocImage a = LocImage Double a
+ Wumpus.Basic.Graphic.Base: type DPoint2F = Point2F Double
+ Wumpus.Basic.Graphic.Base: type Graphic u = DrawingR (HPrim u)
+ Wumpus.Basic.Graphic.Base: type Image u a = DrawingR (a, HPrim u)
+ Wumpus.Basic.Graphic.Base: type LocDrawingR u a = Point2 u -> DrawingR a
+ Wumpus.Basic.Graphic.Base: type LocGraphic u = Point2 u -> Graphic u
+ Wumpus.Basic.Graphic.Base: type LocImage u a = Point2 u -> Image u a
+ Wumpus.Basic.Graphic.Base: type Point2F u = Point2 u -> Point2 u
+ Wumpus.Basic.Graphic.Base: xlinkGraphic :: XLink -> Graphic u -> Graphic u
+ Wumpus.Basic.Graphic.Base: xlinkImage :: XLink -> Image u a -> Image u a
+ Wumpus.Basic.Graphic.DirectionContext: asksTheta :: (DirectionM m) => (Radian -> a) -> m a
+ Wumpus.Basic.Graphic.DirectionContext: class (Monad m) => DirectionM m
+ Wumpus.Basic.Graphic.DirectionContext: data Direction a
+ Wumpus.Basic.Graphic.DirectionContext: data DirectionT m a
+ Wumpus.Basic.Graphic.DirectionContext: displacePara :: (DirectionM m, Floating u) => u -> Point2 u -> m (Point2 u)
+ Wumpus.Basic.Graphic.DirectionContext: displacePerp :: (DirectionM m, Floating u) => u -> Point2 u -> m (Point2 u)
+ Wumpus.Basic.Graphic.DirectionContext: instance (DrawingCtxM m) => DrawingCtxM (DirectionT m)
+ Wumpus.Basic.Graphic.DirectionContext: instance (Monad m) => Applicative (DirectionT m)
+ Wumpus.Basic.Graphic.DirectionContext: instance (Monad m) => DirectionM (DirectionT m)
+ Wumpus.Basic.Graphic.DirectionContext: instance (Monad m) => Functor (DirectionT m)
+ Wumpus.Basic.Graphic.DirectionContext: instance (Monad m) => Monad (DirectionT m)
+ Wumpus.Basic.Graphic.DirectionContext: instance (Monad m, TraceM m) => TraceM (DirectionT m)
+ Wumpus.Basic.Graphic.DirectionContext: instance Applicative Direction
+ Wumpus.Basic.Graphic.DirectionContext: instance DirectionM Direction
+ Wumpus.Basic.Graphic.DirectionContext: instance Functor Direction
+ Wumpus.Basic.Graphic.DirectionContext: instance Monad Direction
+ Wumpus.Basic.Graphic.DirectionContext: localTheta :: (DirectionM m) => Radian -> m a -> m a
+ Wumpus.Basic.Graphic.DirectionContext: parallel :: (DirectionM m, Floating u) => u -> m (Vec2 u)
+ Wumpus.Basic.Graphic.DirectionContext: perpendicular :: (DirectionM m, Floating u) => u -> m (Vec2 u)
+ Wumpus.Basic.Graphic.DirectionContext: runDirection :: Radian -> Direction a -> a
+ Wumpus.Basic.Graphic.DirectionContext: runDirectionT :: Radian -> DirectionT m a -> m a
+ Wumpus.Basic.Graphic.DrawingContext: bothFillColour :: DrawingContextF
+ Wumpus.Basic.Graphic.DrawingContext: bothStrokeColour :: DrawingContextF
+ Wumpus.Basic.Graphic.DrawingContext: capButt :: DrawingContextF
+ Wumpus.Basic.Graphic.DrawingContext: capRound :: DrawingContextF
+ Wumpus.Basic.Graphic.DrawingContext: capSquare :: DrawingContextF
+ Wumpus.Basic.Graphic.DrawingContext: default_drawing_context :: DrawingContext
+ Wumpus.Basic.Graphic.DrawingContext: fillColour :: RGBi -> DrawingContextF
+ Wumpus.Basic.Graphic.DrawingContext: fill_colour :: DrawingContext -> RGBi
+ Wumpus.Basic.Graphic.DrawingContext: joinBevel :: DrawingContextF
+ Wumpus.Basic.Graphic.DrawingContext: joinMiter :: DrawingContextF
+ Wumpus.Basic.Graphic.DrawingContext: joinRound :: DrawingContextF
+ Wumpus.Basic.Graphic.DrawingContext: strokeColour :: RGBi -> DrawingContextF
+ Wumpus.Basic.Graphic.DrawingContext: stroke_colour :: DrawingContext -> RGBi
+ Wumpus.Basic.Graphic.DrawingContext: type DrawingContextF = DrawingContext -> DrawingContext
+ Wumpus.Basic.Graphic.PrimGraphic: curveBetween :: (Fractional u) => Point2 u -> Point2 u -> Point2 u -> Point2 u -> Graphic u
+ Wumpus.Basic.Graphic.Query: markHalfHeight :: (Applicative m, DrawingCtxM m, Fractional u, FromPtSize u) => m u
+ Wumpus.Basic.Graphic.ScalingContext: class (Monad m) => ScalingM m where { type family XDim m :: *; type family YDim m :: *; }
+ Wumpus.Basic.Graphic.ScalingContext: scalePt :: (ScalingM m, u ~ (MonUnit m), ux ~ (XDim m), uy ~ (YDim m)) => ux -> uy -> m (Point2 u)
+ Wumpus.Basic.Graphic.ScalingContext: scaleVec :: (ScalingM m, u ~ (MonUnit m), ux ~ (XDim m), uy ~ (YDim m)) => ux -> uy -> m (Vec2 u)
+ Wumpus.Basic.Graphic.ScalingContext: scaleX :: (ScalingM m, u ~ (MonUnit m), ux ~ (XDim m)) => ux -> m u
+ Wumpus.Basic.Graphic.ScalingContext: scaleY :: (ScalingM m, u ~ (MonUnit m), uy ~ (YDim m)) => uy -> m u
+ Wumpus.Basic.Paths.Base: (:<<) :: PathSegment u -> Path u -> PathViewL u
+ Wumpus.Basic.Paths.Base: (:>>) :: Path u -> PathSegment u -> PathViewR u
+ Wumpus.Basic.Paths.Base: Curve1 :: (Point2 u) -> (Point2 u) -> (Point2 u) -> (Point2 u) -> PathSegment u
+ Wumpus.Basic.Paths.Base: EmptyPathL :: PathViewL u
+ Wumpus.Basic.Paths.Base: EmptyPathR :: PathViewR u
+ Wumpus.Basic.Paths.Base: Line1 :: (Point2 u) -> (Point2 u) -> PathSegment u
+ Wumpus.Basic.Paths.Base: curve :: (Floating u, Ord u) => Point2 u -> Point2 u -> Point2 u -> Point2 u -> Path u
+ Wumpus.Basic.Paths.Base: curveByAngles :: (Floating u, Ord u) => Point2 u -> Radian -> Radian -> Point2 u -> Path u
+ Wumpus.Basic.Paths.Base: data PathSegment u
+ Wumpus.Basic.Paths.Base: data PathViewL u
+ Wumpus.Basic.Paths.Base: data PathViewR u
+ Wumpus.Basic.Paths.Base: directionL :: (Real u, Floating u) => Path u -> Radian
+ Wumpus.Basic.Paths.Base: directionR :: (Real u, Floating u) => Path u -> Radian
+ Wumpus.Basic.Paths.Base: instance (Eq u) => Eq (PathSegment u)
+ Wumpus.Basic.Paths.Base: instance (Eq u) => Eq (PathViewL u)
+ Wumpus.Basic.Paths.Base: instance (Eq u) => Eq (PathViewR u)
+ Wumpus.Basic.Paths.Base: instance (Floating u) => Monoid (Path u)
+ Wumpus.Basic.Paths.Base: instance (Ord u) => Ord (PathSegment u)
+ Wumpus.Basic.Paths.Base: instance (Ord u) => Ord (PathViewL u)
+ Wumpus.Basic.Paths.Base: instance (Ord u) => Ord (PathViewR u)
+ Wumpus.Basic.Paths.Base: instance (Show u) => Show (PathSegment u)
+ Wumpus.Basic.Paths.Base: instance (Show u) => Show (PathViewL u)
+ Wumpus.Basic.Paths.Base: instance (Show u) => Show (PathViewR u)
+ Wumpus.Basic.Paths.Base: length :: (Num u) => Path u -> u
+ Wumpus.Basic.Paths.Base: line :: (Floating u) => Point2 u -> Point2 u -> Path u
+ Wumpus.Basic.Paths.Base: midpoint :: (Real u, Floating u) => Path u -> Maybe (Point2 u, Radian)
+ Wumpus.Basic.Paths.Base: pathViewL :: (Num u) => Path u -> PathViewL u
+ Wumpus.Basic.Paths.Base: pathViewR :: (Num u) => Path u -> PathViewR u
+ Wumpus.Basic.Paths.Base: shortenBoth :: (Real u, Floating u) => u -> Path u -> Path u
+ Wumpus.Basic.Paths.Base: shortenL :: (Real u, Floating u) => u -> Path u -> Path u
+ Wumpus.Basic.Paths.Base: shortenR :: (Real u, Floating u) => u -> Path u -> Path u
+ Wumpus.Basic.Paths.Base: tipL :: Path u -> Maybe (Point2 u)
+ Wumpus.Basic.Paths.Base: tipR :: Path u -> Maybe (Point2 u)
+ Wumpus.Basic.Paths.Base: tracePoints :: (Floating u) => [Point2 u] -> Path u
+ Wumpus.Basic.Paths.Base: type DPath = Path Double
+ Wumpus.Basic.Paths.Base: type DPathSegment = PathSegment Double
+ Wumpus.Basic.Paths.Base: type DPathViewL = PathViewL Double
+ Wumpus.Basic.Paths.Base: type DPathViewR = PathViewR Double
+ Wumpus.Basic.Paths.Connectors: connect :: (Floating u) => Connector u
+ Wumpus.Basic.Paths.Connectors: hvhconn :: (Floating u) => u -> Connector u
+ Wumpus.Basic.Paths.Connectors: type Connector u = Point2 u -> Point2 u -> Path u
+ Wumpus.Basic.Paths.Connectors: vhvconn :: (Floating u) => u -> Connector u
+ Wumpus.Basic.Paths.Construction: tip :: PathM u (Point2 u)
+ Wumpus.Basic.Paths.RoundCorners: cornerCurve :: (Real u, Floating u) => Point2 u -> Point2 u -> Point2 u -> Path u
+ Wumpus.Basic.Paths.RoundCorners: illustratePath :: (Fractional u) => Path u -> Graphic u
+ Wumpus.Basic.Paths.RoundCorners: roundEvery :: (Real u, Floating u) => u -> [Point2 u] -> Path u
- Wumpus.Basic.Arrows: arrowBarb45 :: (Real u, Floating u, FromPtSize u) => ConnPath u -> ConnImage u (Path u)
+ Wumpus.Basic.Arrows: arrowBarb45 :: (Real u, Floating u, FromPtSize u) => Connector u -> ConnImage u (Path u)
- Wumpus.Basic.Arrows: arrowBarb60 :: (Real u, Floating u, FromPtSize u) => ConnPath u -> ConnImage u (Path u)
+ Wumpus.Basic.Arrows: arrowBarb60 :: (Real u, Floating u, FromPtSize u) => Connector u -> ConnImage u (Path u)
- Wumpus.Basic.Arrows: arrowBarb90 :: (Real u, Floating u, FromPtSize u) => ConnPath u -> ConnImage u (Path u)
+ Wumpus.Basic.Arrows: arrowBarb90 :: (Real u, Floating u, FromPtSize u) => Connector u -> ConnImage u (Path u)
- Wumpus.Basic.Arrows: arrowOTri45 :: (Real u, Floating u, FromPtSize u) => ConnPath u -> ConnImage u (Path u)
+ Wumpus.Basic.Arrows: arrowOTri45 :: (Real u, Floating u, FromPtSize u) => Connector u -> ConnImage u (Path u)
- Wumpus.Basic.Arrows: arrowOTri60 :: (Real u, Floating u, FromPtSize u) => ConnPath u -> ConnImage u (Path u)
+ Wumpus.Basic.Arrows: arrowOTri60 :: (Real u, Floating u, FromPtSize u) => Connector u -> ConnImage u (Path u)
- Wumpus.Basic.Arrows: arrowOTri90 :: (Real u, Floating u, FromPtSize u) => ConnPath u -> ConnImage u (Path u)
+ Wumpus.Basic.Arrows: arrowOTri90 :: (Real u, Floating u, FromPtSize u) => Connector u -> ConnImage u (Path u)
- Wumpus.Basic.Arrows: arrowPerp :: (Real u, Floating u, FromPtSize u) => ConnPath u -> ConnImage u (Path u)
+ Wumpus.Basic.Arrows: arrowPerp :: (Real u, Floating u, FromPtSize u) => Connector u -> ConnImage u (Path u)
- Wumpus.Basic.Arrows: arrowTri45 :: (Real u, Floating u, FromPtSize u) => ConnPath u -> ConnImage u (Path u)
+ Wumpus.Basic.Arrows: arrowTri45 :: (Real u, Floating u, FromPtSize u) => Connector u -> ConnImage u (Path u)
- Wumpus.Basic.Arrows: arrowTri60 :: (Real u, Floating u, FromPtSize u) => ConnPath u -> ConnImage u (Path u)
+ Wumpus.Basic.Arrows: arrowTri60 :: (Real u, Floating u, FromPtSize u) => Connector u -> ConnImage u (Path u)
- Wumpus.Basic.Arrows: arrowTri90 :: (Real u, Floating u, FromPtSize u) => ConnPath u -> ConnImage u (Path u)
+ Wumpus.Basic.Arrows: arrowTri90 :: (Real u, Floating u, FromPtSize u) => Connector u -> ConnImage u (Path u)
- Wumpus.Basic.Graphic.DrawingContext: dashPattern :: DashPattern -> DrawingContext -> DrawingContext
+ Wumpus.Basic.Graphic.DrawingContext: dashPattern :: DashPattern -> DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: doublesize :: DrawingContext -> DrawingContext
+ Wumpus.Basic.Graphic.DrawingContext: doublesize :: DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: fontface :: FontFace -> DrawingContext -> DrawingContext
+ Wumpus.Basic.Graphic.DrawingContext: fontface :: FontFace -> DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: fontsize :: Int -> DrawingContext -> DrawingContext
+ Wumpus.Basic.Graphic.DrawingContext: fontsize :: Int -> DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: halfsize :: DrawingContext -> DrawingContext
+ Wumpus.Basic.Graphic.DrawingContext: halfsize :: DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: swapColours :: DrawingContext -> DrawingContext
+ Wumpus.Basic.Graphic.DrawingContext: swapColours :: DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: thick :: DrawingContext -> DrawingContext
+ Wumpus.Basic.Graphic.DrawingContext: thick :: DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: thin :: DrawingContext -> DrawingContext
+ Wumpus.Basic.Graphic.DrawingContext: thin :: DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: ultrathick :: DrawingContext -> DrawingContext
+ Wumpus.Basic.Graphic.DrawingContext: ultrathick :: DrawingContextF
- Wumpus.Basic.Graphic.Query: borderedAttr :: DrawingF (RGBi, StrokeAttr, RGBi)
+ Wumpus.Basic.Graphic.Query: borderedAttr :: (Applicative m, DrawingCtxM m) => m (RGBi, StrokeAttr, RGBi)
- Wumpus.Basic.Graphic.Query: fillAttr :: DrawingF RGBi
+ Wumpus.Basic.Graphic.Query: fillAttr :: (Applicative m, DrawingCtxM m) => m RGBi
- Wumpus.Basic.Graphic.Query: fontSize :: DrawingF Int
+ Wumpus.Basic.Graphic.Query: fontSize :: (Applicative m, DrawingCtxM m) => m Int
- Wumpus.Basic.Graphic.Query: lineSpacing :: (Fractional u) => DrawingF u
+ Wumpus.Basic.Graphic.Query: lineSpacing :: (Applicative m, DrawingCtxM m, Fractional u) => m u
- Wumpus.Basic.Graphic.Query: lineWidth :: DrawingF Double
+ Wumpus.Basic.Graphic.Query: lineWidth :: (Applicative m, DrawingCtxM m) => m Double
- Wumpus.Basic.Graphic.Query: markHeight :: (FromPtSize u) => DrawingF u
+ Wumpus.Basic.Graphic.Query: markHeight :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u
- Wumpus.Basic.Graphic.Query: monoCharWidth :: (FromPtSize u) => DrawingF u
+ Wumpus.Basic.Graphic.Query: monoCharWidth :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u
- Wumpus.Basic.Graphic.Query: monoDescenderDepth :: (FromPtSize u) => DrawingF u
+ Wumpus.Basic.Graphic.Query: monoDescenderDepth :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u
- Wumpus.Basic.Graphic.Query: monoLowerxHeight :: (FromPtSize u) => DrawingF u
+ Wumpus.Basic.Graphic.Query: monoLowerxHeight :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u
- Wumpus.Basic.Graphic.Query: monoNumeralHeight :: (FromPtSize u) => DrawingF u
+ Wumpus.Basic.Graphic.Query: monoNumeralHeight :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u
- Wumpus.Basic.Graphic.Query: monoSpacerWidth :: (FromPtSize u) => DrawingF u
+ Wumpus.Basic.Graphic.Query: monoSpacerWidth :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u
- Wumpus.Basic.Graphic.Query: monoTextDimensions :: (Num u, Ord u, FromPtSize u) => String -> DrawingF (u, u)
+ Wumpus.Basic.Graphic.Query: monoTextDimensions :: (Applicative m, DrawingCtxM m, Num u, Ord u, FromPtSize u) => String -> m (u, u)
- Wumpus.Basic.Graphic.Query: monoTextHeight :: (FromPtSize u) => DrawingF u
+ Wumpus.Basic.Graphic.Query: monoTextHeight :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u
- Wumpus.Basic.Graphic.Query: monoTextLength :: (FromPtSize u) => String -> DrawingF u
+ Wumpus.Basic.Graphic.Query: monoTextLength :: (Applicative m, DrawingCtxM m, FromPtSize u) => String -> m u
- Wumpus.Basic.Graphic.Query: monoTextWidth :: (FromPtSize u) => Int -> DrawingF u
+ Wumpus.Basic.Graphic.Query: monoTextWidth :: (Applicative m, DrawingCtxM m, FromPtSize u) => Int -> m u
- Wumpus.Basic.Graphic.Query: monoVecToCenter :: (Fractional u, Ord u, FromPtSize u) => String -> DrawingF (Vec2 u)
+ Wumpus.Basic.Graphic.Query: monoVecToCenter :: (Applicative m, DrawingCtxM m, Fractional u, Ord u, FromPtSize u) => String -> m (Vec2 u)
- Wumpus.Basic.Graphic.Query: strokeAttr :: DrawingF (RGBi, StrokeAttr)
+ Wumpus.Basic.Graphic.Query: strokeAttr :: (Applicative m, DrawingCtxM m) => m (RGBi, StrokeAttr)
- Wumpus.Basic.Graphic.Query: textAttr :: DrawingF (RGBi, FontAttr)
+ Wumpus.Basic.Graphic.Query: textAttr :: (Applicative m, DrawingCtxM m) => m (RGBi, FontAttr)
- Wumpus.Basic.Graphic.Query: withBorderedAttr :: (RGBi -> StrokeAttr -> RGBi -> a) -> DrawingF a
+ Wumpus.Basic.Graphic.Query: withBorderedAttr :: (Applicative m, DrawingCtxM m) => (RGBi -> StrokeAttr -> RGBi -> a) -> m a
- Wumpus.Basic.Graphic.Query: withFillAttr :: (RGBi -> a) -> DrawingF a
+ Wumpus.Basic.Graphic.Query: withFillAttr :: (Applicative m, DrawingCtxM m) => (RGBi -> a) -> m a
- Wumpus.Basic.Graphic.Query: withStrokeAttr :: (RGBi -> StrokeAttr -> a) -> DrawingF a
+ Wumpus.Basic.Graphic.Query: withStrokeAttr :: (Applicative m, DrawingCtxM m) => (RGBi -> StrokeAttr -> a) -> m a
- Wumpus.Basic.Graphic.Query: withTextAttr :: (RGBi -> FontAttr -> a) -> DrawingF a
+ Wumpus.Basic.Graphic.Query: withTextAttr :: (Applicative m, DrawingCtxM m) => (RGBi -> FontAttr -> a) -> m a
- Wumpus.Basic.Paths.Connectors: curveconn :: (Floating u, Ord u) => Radian -> Radian -> ConnPath u
+ Wumpus.Basic.Paths.Connectors: curveconn :: (Floating u, Ord u) => Radian -> Radian -> Connector u
- Wumpus.Basic.Paths.Connectors: hvconn :: (Floating u) => ConnPath u
+ Wumpus.Basic.Paths.Connectors: hvconn :: (Floating u) => Connector u
- Wumpus.Basic.Paths.Connectors: joint :: (Real u, Floating u) => u -> ConnPath u
+ Wumpus.Basic.Paths.Connectors: joint :: (Real u, Floating u) => u -> Connector u
- Wumpus.Basic.Paths.Connectors: vhconn :: (Floating u) => ConnPath u
+ Wumpus.Basic.Paths.Connectors: vhconn :: (Floating u) => Connector u
- Wumpus.Basic.Paths.Construction: execPath :: (Num u) => Point2 u -> PathM u a -> Path u
+ Wumpus.Basic.Paths.Construction: execPath :: (Floating u) => Point2 u -> PathM u a -> Path u
- Wumpus.Basic.Paths.Construction: runPath :: (Num u) => Point2 u -> PathM u a -> (a, Path u)
+ Wumpus.Basic.Paths.Construction: runPath :: (Floating u) => Point2 u -> PathM u a -> (a, Path u)
Files
- CHANGES +74/−0
- demo/ClipPic.hs +5/−3
- demo/ColourCharts.hs +1/−1
- demo/ColourDefns.hs +1/−1
- demo/DotPic.hs +3/−3
- demo/FontPic.hs +3/−3
- demo/PetriNet.hs +125/−0
- demo/Picture.hs +3/−3
- demo/Shapes.hs +1/−105
- demo/Symbols.hs +1/−1
- src/Wumpus/Basic/Anchors.hs +1/−8
- src/Wumpus/Basic/Arrows.hs +39/−23
- src/Wumpus/Basic/Arrows/Tips.hs +94/−14
- src/Wumpus/Basic/Colour/SVGColours.hs +2/−2
- src/Wumpus/Basic/Colour/X11Colours.hs +2/−2
- src/Wumpus/Basic/Dots.hs +4/−4
- src/Wumpus/Basic/Dots/Primitive.hs +15/−13
- src/Wumpus/Basic/Graphic.hs +4/−4
- src/Wumpus/Basic/Graphic/Base.hs +334/−0
- src/Wumpus/Basic/Graphic/BaseClasses.hs +0/−87
- src/Wumpus/Basic/Graphic/BaseTypes.hs +0/−301
- src/Wumpus/Basic/Graphic/DirectionContext.hs +140/−0
- src/Wumpus/Basic/Graphic/Drawing.hs +9/−10
- src/Wumpus/Basic/Graphic/DrawingContext.hs +83/−40
- src/Wumpus/Basic/Graphic/PrimGraphic.hs +6/−1
- src/Wumpus/Basic/Graphic/Query.hs +61/−48
- src/Wumpus/Basic/Graphic/ScalingContext.hs +22/−4
- src/Wumpus/Basic/Monads/TurtleMonad.hs +2/−2
- src/Wumpus/Basic/Paths/Base.hs +339/−74
- src/Wumpus/Basic/Paths/Connectors.hs +28/−153
- src/Wumpus/Basic/Paths/Construction.hs +55/−48
- src/Wumpus/Basic/Paths/RoundCorners.hs +114/−0
- src/Wumpus/Basic/Shapes/Base.hs +15/−0
- src/Wumpus/Basic/Shapes/Derived.hs +6/−6
- src/Wumpus/Basic/Text/LRText.hs +5/−5
- src/Wumpus/Basic/Utils/Intersection.hs +1/−1
- src/Wumpus/Basic/VersionNumber.hs +2/−2
- wumpus-basic.cabal +44/−51
CHANGES view
@@ -1,4 +1,78 @@ ++0.9.0 to 0.10.0:++ * @Basic.Graphic.BaseClasses@ and @Basic.Graphic.BaseTypes@ + merged into same module so they can depend on each other + without orphans instances.++ * @DrawingF@ renamed to @DrawingR@, the related type synonyms+ have also been changed, e.g. @LocDrawingF@ is now + @LocDrawingR@.++ * Method names in the @DrawingCtxM@ class changed - @askCtx@ is+ now @askDC@, @localCtx@ is now @localize@. Removed the + functions @askDF@, @asksDF@, @pureDF@ that worked for + @DrawingF@ (now @DrawingR@), @DrawingR@ now uses the + Applicative\'s @pure@ and the @DrawingCtxM@ class for these + functionalities.++ * @Basic.Graphic.DrawingContext@ - renamed @primary_colour@ to+ @stroke_colour@ and @secondary_colour@ to @fill_colour@. The + setter functions has been similarly renamed.++ * Added the type synonym @DrawingContextF@ to + @Basic.Graphic.DrawingContext@. Changed relevant function+ signatures to use it.++ * Re-worked the Path modules - base types entirely different,+ connectors entirely different, monadic path construction + largely the same.++ * Initial work on round cornered paths.+ + * Removed the type class @TextAnchor@ from @Basic.Anchors@. + This was a left-over from a previous implementation of + Shapes and is not relevant to the current implementation.+ + * Added @DirectionContext@ to @Basic.Graphic@.++ * @localLG@ removed it can be acheived with composition -+ @localize upd . loc_graphic_function@. @lgappend@ is also + removed - it can be recreated applicatively.++0.8.0 to 0.9.0:++ * Re-worked @Basic.Text.LRSymbol@ changed the type name and the+ types of the run functions. Added more symbols and a new demo + @Symbols.hs@.++ * @ScalingContext@ added to @Basic.Graphic@. Changed + @monoTextWidth@ to take a character count, the old behaviour + is recreated by the new function @monoTextLength@. ++ * @Basic.Graphic.Chain@ removed. It is now superseded by+ @Basic.Chains@.++ * Added new property to @DrawingContext@ for line spacing + scaling factor, and added a new drawing primitive + @textlineMulti@ for multi-line, left justified labels.++ * Synthezied attribute /getters/ such as @textDimensions@ moved+ from @Basic.Graphic.DrawingContext@ to the new module+ @Basic.Graphic.Query@. The type of all the functions has + changed to DrawingF. @lowerxHeight@ is renamed + @monoLowerxHeight@ emphasizing that the metrics pertain to+ monospaced Courier font.++ * Added Shapes modules.+ + * TurtleMonad module - the TurtleDrawing type and run functions+ have been removed and the internals have been reworked. + Turtle is now run solely as a /local effect/ within the + Drawing monad. ++ 0.7.0 to 0.8.0: * Re-introduced LRText and LRSymbol - they now work with
demo/ClipPic.hs view
@@ -39,12 +39,14 @@ pic :: DPicture pic = pic1 `nextToV` (stackOver [cpic1, cpic2, cpic3] cpic4) +fillPath :: Num u => Path u -> Graphic u+fillPath = filledPath . toPrimPathU pic1 :: DPicture pic1 = liftToPictureU $ execDrawing pic_drawing_ctx $ - localCtx (secondaryColour medium_slate_blue) $ do+ localize (fillColour medium_slate_blue) $ do draw $ fillPath path01- localCtx (secondaryColour powder_blue) $ + localize (fillColour powder_blue) $ draw $ fillPath path02 draw $ fillPath path03 draw $ fillPath path04@@ -52,7 +54,7 @@ background :: RGBi -> DPicture background rgb = liftToPictureU $ execDrawing pic_drawing_ctx $ - localCtx (primaryColour rgb) $ do + localize (strokeColour rgb) $ do mapM_ iheartHaskell ps where
demo/ColourCharts.hs view
@@ -43,7 +43,7 @@ colourSample :: String -> RGBi -> DPoint2 -> Drawing Double ()-colourSample name rgb pt = localCtx (secondaryColour rgb) $ do +colourSample name rgb pt = localize (fillColour rgb) $ do draw $ borderedRectangle 15 10 `at` pt draw $ textline name `at` displace 20 2 pt
demo/ColourDefns.hs view
@@ -8,7 +8,7 @@ -- -- Maintainer : Stephen Tetley <stephen.tetley@gmail.com> -- Stability : highly unstable--- Portability : GHC with TypeFamilies and more+-- Portability : GHC -- -- All the SVG / X11 \"named colours\" listed in tables. --
demo/DotPic.hs view
@@ -51,7 +51,7 @@ p17 = makeDotPic (dotText "AA") points std_ctx :: DrawingContext-std_ctx = secondaryColour peru $ standardContext 12+std_ctx = fillColour peru $ standardContext 12 points :: [Point2 Double] points = [P2 0 0, P2 32 10, P2 64 0, P2 96 10]@@ -66,10 +66,10 @@ dashline mapM_ (\pt -> drawi $ dotImg `ati` pt) xs where- dashline = localCtx attrUpd (draw $ openStroke $ vertexPath xs)+ dashline = localize attrUpd (draw $ openStroke $ vertexPath xs) attrUpd :: DrawingContext -> DrawingContext- attrUpd = dashPattern (evenDashes 1) . primaryColour cadet_blue+ attrUpd = dashPattern (evenDashes 1) . strokeColour cadet_blue
demo/FontPic.hs view
@@ -34,9 +34,9 @@ makeLabel :: RGBi -> FontFace -> Int -> DLocGraphic-makeLabel rgb ff sz = - localLG (primaryColour rgb . fontsize sz . fontface ff) - (textline $ fontMsg ff sz)+makeLabel rgb ff sz = localize upd . (textline $ fontMsg ff sz)+ where+ upd = fillColour rgb . fontsize sz . fontface ff -- indian_red1 -- steel_blue
+ demo/PetriNet.hs view
@@ -0,0 +1,125 @@+{-# LANGUAGE TypeFamilies #-}+{-# OPTIONS -Wall #-}++-- Acknowledgment - the petri net is taken from Claus Reinke\'s+-- paper /Haskell-Coloured Petri Nets/.+++module PetriNet where++import Wumpus.Basic.Anchors+import Wumpus.Basic.Arrows+import Wumpus.Basic.Colour.SVGColours+import Wumpus.Basic.Graphic -- package: wumpus-basic+import Wumpus.Basic.Paths+import Wumpus.Basic.Shapes.Base+import Wumpus.Basic.Shapes.Derived+import Wumpus.Basic.SafeFonts++import Wumpus.Core -- package: wumpus-core+++import System.Directory++++main :: IO ()+main = do + createDirectoryIfMissing True "./out/"+ writeEPS_latin1 "./out/petri_net.eps" petri_net+ writeSVG_latin1 "./out/petri_net.svg" petri_net+ +++petri_net :: DPicture+petri_net = liftToPictureU $ execDrawing (standardContext 14) $ do+ pw <- place 0 140+ tu1 <- transition 70 140+ rtw <- place 140 140+ tu2 <- transition 210 140+ w <- place 280 140+ tu3 <- transition 350 140+ res <- place 280 70+ pr <- place 0 0+ tl1 <- transition 70 0+ rtr <- place 140 0+ tl2 <- transition 210 0+ r <- place 280 0+ tl3 <- transition 350 0+ connector (east pw) (west tu1) + connector (east tu1) (west rtw)+ connector (east rtw) (west tu2)+ connector (east tu2) (west w)+ connector (east w) (west tu3)+ connectorC 32 (north tu3) (north pw)+ connector (east pr) (west tl1) + connector (east tl1) (west rtr)+ connector (east rtr) (west tl2)+ connector (east tl2) (west r)+ connector (east r) (west tl3)+ connectorC (-32) (south tl3) (south pr)+ connector (southwest res) (northeast tl2)+ connector (northwest tl3) (southeast res)+ connectorD 6 (southwest tu3) (northeast res)+ connectorD (-6) (southwest tu3) (northeast res) + connectorD 6 (northwest res) (southeast tu2)+ connectorD (-6) (northwest res) (southeast tu2) + draw $ lblParensParens `at` (P2 (-36) 150)+ draw $ lblParensParens `at` (P2 300 60)+ draw $ lblParensParensParens `at` (P2 (-52) (-14))+ draw $ lblBold "processing_w" `at` (southwards 12 pw)+ draw $ lblBold "ready_to_write" `at` (southwards 12 rtw)+ draw $ lblBold "writing" `at` (southwards 12 w)+ draw $ lblBold' "resource" `at` (P2 300 72)+ draw $ lblBold "processing_r" `at` (northwards 12 pr)+ draw $ lblBold "ready_to_read" `at` (northwards 12 rtr)+ draw $ lblBold "reading" `at` (northwards 12 r)+ return ()++greenFill :: DrawingCtxM m => m a -> m a+greenFill = localize (fillColour lime_green)++place :: (Real u, Floating u, DrawingCtxM m, TraceM m, u ~ MonUnit m) + => u -> u -> m (Circle u)+place x y = greenFill $ drawi $ drawShape $ translate x y $ circle 14++transition :: (Real u, Floating u, DrawingCtxM m, TraceM m, u ~ MonUnit m) + => u -> u -> m (Rectangle u)+transition x y = greenFill $ drawi $ drawShape $ translate x y $ rectangle 32 22++connector :: ( Real u, Floating u, FromPtSize u+ , DrawingCtxM m, TraceM m, u ~ MonUnit m )+ => Point2 u -> Point2 u -> m ()+connector p1 p2 = do+ _ <- drawi $ arrowTri60 connect `conn` p1 $ p2+ return ()+++connectorC :: ( Real u, Floating u, FromPtSize u+ , DrawingCtxM m, TraceM m, u ~ MonUnit m )+ => u -> Point2 u -> Point2 u -> m ()+connectorC v p1 p2 = do+ _ <- drawi $ arrowTri60 (vhvconn v) `conn` p1 $ p2+ return ()++connectorD :: ( Real u, Floating u, FromPtSize u+ , DrawingCtxM m, TraceM m, u ~ MonUnit m )+ => u -> Point2 u -> Point2 u -> m ()+connectorD u p1 p2 = do+ _ <- drawi $ arrowTri60 (joint u) `conn` p1 $ p2+ return ()+++lblParensParens :: Num u => LocGraphic u+lblParensParens = localize (fontface helvetica) . textline "(),()"++lblParensParensParens :: Num u => LocGraphic u+lblParensParensParens = localize (fontface helvetica) . textline "(),(),()"+++lblBold' :: Num u => String -> LocGraphic u+lblBold' ss = localize (fontface helveticaBold) . textline ss+++lblBold :: (Fractional u, Ord u, FromPtSize u) => String -> LocGraphic u+lblBold ss = localize (fontface helveticaBold) . centermonoTextline ss
demo/Picture.hs view
@@ -135,17 +135,17 @@ rect_red :: DPicture rect_red = liftToPictureU $ execDrawing pic_drawing_ctx $ - localCtx (secondaryColour indian_red)+ localize (fillColour indian_red) (draw $ borderedRectangle 30 10 `at` (P2 0 10)) rect_green :: DPicture rect_green = liftToPictureU $ execDrawing pic_drawing_ctx $ - localCtx (secondaryColour olive_drab)+ localize (fillColour olive_drab) (draw $ borderedRectangle 15 15 `at` (P2 10 10)) rect_blue :: DPicture rect_blue = liftToPictureU $ execDrawing pic_drawing_ctx $ - localCtx (secondaryColour powder_blue)+ localize (fillColour powder_blue) (draw $ borderedRectangle 20 30 `at` (P2 10 0))
demo/Shapes.hs view
@@ -1,20 +1,12 @@-{-# LANGUAGE TypeFamilies #-} {-# OPTIONS -Wall #-} --- Acknowledgment - the petri net is taken from Claus Reinke\'s--- paper /Haskell-Coloured Petri Nets/. - module Shapes where -import Wumpus.Basic.Anchors-import Wumpus.Basic.Arrows import Wumpus.Basic.Colour.SVGColours import Wumpus.Basic.Graphic -- package: wumpus-basic-import Wumpus.Basic.Paths import Wumpus.Basic.Shapes.Base import Wumpus.Basic.Shapes.Derived-import Wumpus.Basic.SafeFonts import Wumpus.Core -- package: wumpus-core @@ -28,8 +20,6 @@ createDirectoryIfMissing True "./out/" writeEPS_latin1 "./out/shapes01.eps" pic1 writeSVG_latin1 "./out/shapes01.svg" pic1- writeEPS_latin1 "./out/petri_net.eps" petri_net- writeSVG_latin1 "./out/petri.svg" petri_net pic1 :: DPicture@@ -38,104 +28,10 @@ $ lrectangle 90 30 "Rectangle" _ <- drawi $ drawShape $ translate 100 0 $ lcircle 10 "C0" - _ <- localCtx (primaryColour red) $ + _ <- localize (strokeColour red) $ drawi $ drawShape $ translate 220 10 $ rotate30 $ coordinate _ <- drawi $ drawShape $ translate 0 40 $ ldiamond 10 10 "d1" _ <- drawi $ drawShape $ translate 400 50 $ lrectangle 20 100 "R2" return () ---petri_net :: DPicture-petri_net = liftToPictureU $ execDrawing (standardContext 14) $ do- pw <- place 0 140- tu1 <- transition 70 140- rtw <- place 140 140- tu2 <- transition 210 140- w <- place 280 140- tu3 <- transition 350 140- res <- place 280 70- pr <- place 0 0- tl1 <- transition 70 0- rtr <- place 140 0- tl2 <- transition 210 0- r <- place 280 0- tl3 <- transition 350 0- connector (east pw) (west tu1) - connector (east tu1) (west rtw)- connector (east rtw) (west tu2)- connector (east tu2) (west w)- connector (east w) (west tu3)- connectorC 32 (north tu3) (north pw)- connector (east pr) (west tl1) - connector (east tl1) (west rtr)- connector (east rtr) (west tl2)- connector (east tl2) (west r)- connector (east r) (west tl3)- connectorC (-32) (south tl3) (south pr)- connector (southwest res) (northeast tl2)- connector (northwest tl3) (southeast res)- connectorD 6 (southwest tu3) (northeast res)- connectorD (-6) (southwest tu3) (northeast res) - connectorD 6 (northwest res) (southeast tu2)- connectorD (-6) (northwest res) (southeast tu2) - draw $ lblParensParens `at` (P2 (-36) 150)- draw $ lblParensParens `at` (P2 300 60)- draw $ lblParensParensParens `at` (P2 (-52) (-14))- draw $ lblBold "processing_w" `at` (southwards 12 pw)- draw $ lblBold "ready_to_write" `at` (southwards 12 rtw)- draw $ lblBold "writing" `at` (southwards 12 w)- draw $ lblBold' "resource" `at` (P2 300 72)- draw $ lblBold "processing_r" `at` (northwards 12 pr)- draw $ lblBold "ready_to_read" `at` (northwards 12 rtr)- draw $ lblBold "reading" `at` (northwards 12 r)- return ()--greenFill :: DrawingCtxM m => m a -> m a-greenFill = localCtx (secondaryColour lime_green)--place :: (Real u, Floating u, DrawingCtxM m, TraceM m, u ~ MonUnit m) - => u -> u -> m (Circle u)-place x y = greenFill $ drawi $ drawShape $ translate x y $ circle 14--transition :: (Real u, Floating u, DrawingCtxM m, TraceM m, u ~ MonUnit m) - => u -> u -> m (Rectangle u)-transition x y = greenFill $ drawi $ drawShape $ translate x y $ rectangle 32 22--connector :: ( Real u, Floating u, FromPtSize u- , DrawingCtxM m, TraceM m, u ~ MonUnit m )- => Point2 u -> Point2 u -> m ()-connector p1 p2 = do- _ <- drawi $ arrowTri60 connectS `conn` p1 $ p2- return ()---connectorC :: ( Real u, Floating u, FromPtSize u- , DrawingCtxM m, TraceM m, u ~ MonUnit m )- => u -> Point2 u -> Point2 u -> m ()-connectorC v p1 p2 = do- _ <- drawi $ arrowTri60 (arbv v) `conn` p1 $ p2- return ()--connectorD :: ( Real u, Floating u, FromPtSize u- , DrawingCtxM m, TraceM m, u ~ MonUnit m )- => u -> Point2 u -> Point2 u -> m ()-connectorD u p1 p2 = do- _ <- drawi $ arrowTri60 (joint u) `conn` p1 $ p2- return ()---lblParensParens :: Num u => LocGraphic u-lblParensParens = localLG (fontface helvetica) $ textline "(),()"--lblParensParensParens :: Num u => LocGraphic u-lblParensParensParens = localLG (fontface helvetica) $ textline "(),(),()"---lblBold' :: Num u => String -> LocGraphic u-lblBold' ss = localLG (fontface helveticaBold) $ textline ss---lblBold :: (Fractional u, Ord u, FromPtSize u) => String -> LocGraphic u-lblBold ss = localLG (fontface helveticaBold) $ centermonoTextline ss
demo/Symbols.hs view
@@ -2,7 +2,7 @@ module Symbols where -import Wumpus.Basic.Graphic+import Wumpus.Basic.Graphic hiding ( perpendicular ) import Wumpus.Basic.SafeFonts import Wumpus.Basic.Text.LRSymbol import Wumpus.Basic.Text.LRText
src/Wumpus/Basic/Anchors.hs view
@@ -9,7 +9,7 @@ -- -- Maintainer : Stephen Tetley <stephen.tetley@gmail.com> -- Stability : highly unstable--- Portability : GHC with TypeFamilies and more+-- Portability : GHC -- -- Anchor points on shapes. --@@ -25,7 +25,6 @@ CenterAnchor(..) , CardinalAnchor(..) , CardinalAnchor2(..)- , TextAnchor(..) , RadialAnchor(..) -- * extended anchor points@@ -66,12 +65,6 @@ southeast :: DUnit t ~ u => t -> Point2 u southwest :: DUnit t ~ u => t -> Point2 u northwest :: DUnit t ~ u => t -> Point2 u---- | 'textAnchor' is the Bottom left corner --- on the baseline.----class TextAnchor t where- baselineSW :: DUnit t ~ u => t -> Point2 u -- | Anchor on a border that can be identified with and angle.
src/Wumpus/Basic/Arrows.hs view
@@ -8,18 +8,18 @@ -- -- Maintainer : Stephen Tetley <stephen.tetley@gmail.com> -- Stability : highly unstable--- Portability : GHC with TypeFamilies and more+-- Portability : GHC ----- Anchor points on shapes.+-- Draw arrows. ----- \*\* WARNING \*\* this module is an experiment, and may --- change significantly or even be dropped from future revisions.+-- \*\* WARNING \*\* - the types are /wrong/ here and need more +-- thought. -- -------------------------------------------------------------------------------- module Wumpus.Basic.Arrows ( - line+ cline , arrowTri90@@ -34,6 +34,7 @@ , arrowBarb45 , arrowPerp+ , arrowRBracket ) where @@ -47,17 +48,22 @@ import Control.Applicative import Data.Monoid -liftConnPath :: ConnPath u -> ConnDrawingF u (Path u)-liftConnPath pF p1 p2 = pureDF $ pF p1 p2+liftConnector :: Connector u -> ConnDrawingR u (Path u)+liftConnector pF p1 p2 = pure $ pF p1 p2 -line :: Num u => ConnPath u -> ConnImage u (Path u)-line pathF = intoConnImage (liftConnPath pathF) (pathGraphic pathF)+cline :: Num u => Connector u -> ConnImage u (Path u)+cline pathF = intoConnImage (liftConnector pathF) (pathGraphic pathF) +-- ... No - can\'t a add tips to this one.+--+pathGraphic :: Num u => Connector u -> ConnGraphic u+pathGraphic bpath = \p1 p2 -> openStroke $ toPrimPathU $ bpath p1 p2 + -- Here the path is already shortened - we have accounted for the -- points already, so it is just a graphic. lineTipR :: Num u => Path u -> Graphic u -> Graphic u-lineTipR bpath tip = openStroke (toPrimPathU bpath) `mappend` tip+lineTipR bpath arrtip = openStroke (toPrimPathU bpath) `mappend` arrtip @@ -73,7 +79,7 @@ -- path segments. -- rightPathProps :: (Real u, Floating u, FromPtSize u) - => ConnPath u -> ConnDrawingF u (Path u,Radian)+ => Connector u -> ConnDrawingR u (Path u,Radian) rightPathProps pathF p1 p2 = (\h sw -> (shortenPath h sw, calcTheta h)) <$> markHeight <*> lineWidth@@ -86,7 +92,7 @@ triTipRight :: (Real u, Floating u, FromPtSize u) - => ConnPath u -> (Radian -> LocGraphic u) -> ConnImage u (Path u) + => Connector u -> (Radian -> LocGraphic u) -> ConnImage u (Path u) triTipRight pathF tipF p1 p2 = rightPathProps pathF p1 p2 >>= \(shortF,theta) -> lineTipR shortF (tipF theta p2) >>= \arrow_pic ->@@ -98,7 +104,7 @@ -- This version does not /retract/ the path... -- barbTipRight :: (Real u, Floating u, FromPtSize u) - => ConnPath u -> (Radian -> LocGraphic u) -> ConnImage u (Path u) + => Connector u -> (Radian -> LocGraphic u) -> ConnImage u (Path u) barbTipRight pathF tipF p1 p2 = rightPathProps pathF p1 p2 >>= \(_,theta) -> lineTipR path_zero (tipF theta p2) >>= \arrow_pic ->@@ -109,58 +115,68 @@ arrowTri90 :: (Real u, Floating u, FromPtSize u) - => ConnPath u -> ConnImage u (Path u)+ => Connector u -> ConnImage u (Path u) arrowTri90 pathF = triTipRight pathF tri90 arrowTri60 :: (Real u, Floating u, FromPtSize u) - => ConnPath u -> ConnImage u (Path u)+ => Connector u -> ConnImage u (Path u) arrowTri60 pathF = triTipRight pathF tri60 arrowTri45 :: (Real u, Floating u, FromPtSize u) - => ConnPath u -> ConnImage u (Path u)+ => Connector u -> ConnImage u (Path u) arrowTri45 pathF = triTipRight pathF tri45 arrowOTri90 :: (Real u, Floating u, FromPtSize u) - => ConnPath u -> ConnImage u (Path u)+ => Connector u -> ConnImage u (Path u) arrowOTri90 pathF = triTipRight pathF otri90 arrowOTri60 :: (Real u, Floating u, FromPtSize u) - => ConnPath u -> ConnImage u (Path u)+ => Connector u -> ConnImage u (Path u) arrowOTri60 pathF = triTipRight pathF otri60 arrowOTri45 :: (Real u, Floating u, FromPtSize u) - => ConnPath u -> ConnImage u (Path u)+ => Connector u -> ConnImage u (Path u) arrowOTri45 pathF = triTipRight pathF otri45 arrowBarb90 :: (Real u, Floating u, FromPtSize u) - => ConnPath u -> ConnImage u (Path u)+ => Connector u -> ConnImage u (Path u) arrowBarb90 pathF = barbTipRight pathF barb90 arrowBarb60 :: (Real u, Floating u, FromPtSize u) - => ConnPath u -> ConnImage u (Path u)+ => Connector u -> ConnImage u (Path u) arrowBarb60 pathF = barbTipRight pathF barb60 arrowBarb45 :: (Real u, Floating u, FromPtSize u) - => ConnPath u -> ConnImage u (Path u)+ => Connector u -> ConnImage u (Path u) arrowBarb45 pathF = barbTipRight pathF barb45 arrowPerp :: (Real u, Floating u, FromPtSize u) - => ConnPath u -> ConnImage u (Path u)+ => Connector u -> ConnImage u (Path u) arrowPerp pathF p1 p2 = lineTipR path_zero perp_tip >>= \arrow_pic -> return (path_zero, arrow_pic) where path_zero = pathF p1 p2 theta = langle p1 p2 perp_tip = perp theta p2+++arrowRBracket :: (Real u, Floating u, FromPtSize u) + => Connector u -> ConnImage u (Path u)+arrowRBracket pathF p1 p2 = + lineTipR path_zero perp_tip >>= \arrow_pic -> return (path_zero, arrow_pic)+ where+ path_zero = pathF p1 p2+ theta = langle p1 p2+ perp_tip = rbracket theta p2
src/Wumpus/Basic/Arrows/Tips.hs view
@@ -8,7 +8,7 @@ -- -- Maintainer : Stephen Tetley <stephen.tetley@gmail.com> -- Stability : highly unstable--- Portability : GHC with TypeFamilies and more+-- Portability : GHC -- -- Anchor points on shapes. --@@ -34,6 +34,8 @@ , perp + , rbracket+ ) where import Wumpus.Basic.Graphic@@ -44,21 +46,87 @@ import Control.Applicative --- | tripoints takes dimensions from the xlowerHeight.+++-- | Tiplen is length of the tip \*along the line it follows\*. ---tripoints :: (Floating u, FromPtSize u)- => Radian -> Radian -> LocDrawingF u (Point2 u, Point2 u)-tripoints triang theta tip = - (\h -> let d = h / (fromRadian $ cos halfang) - in (tip .-^ v1 d, tip .-^ v2 d))- <$> markHeight+-- > |\+-- > | \+-- > | /+-- > |/+-- > +-- > | | -- tip len+--++-- | Tip width is the distance between upper and lower +-- arrow points.+--+-- > __+-- > |\ +-- > | \ tip+-- > | / width+-- > |/ __+-- > ++++-- | This one is for triangular tips defined by their tip angle+-- e.g. 90deg, 60deg, 45deg.+--+-- The tip width will be variable (tip length should be the +-- markHeight).+-- +triVecsByAngle :: Floating u => u -> Radian -> Radian -> (Vec2 u, Vec2 u)+triVecsByAngle tiplen halfang theta = (vec_to_upper, vec_to_lower) where- halfang = 0.5 * triang- v1 d = avec (theta + halfang) d- v2 d = avec (theta - halfang) d+ hypo_len = tiplen / (fromRadian $ cos halfang)+ rtheta = pi + theta -- theta in the opposite direction+ vec_to_upper = avec (circularModulo $ rtheta - halfang) hypo_len+ vec_to_lower = avec (circularModulo $ rtheta + halfang) hypo_len +-- | This one is for triangles when the tip height and tip width+-- are known.+--+triVecsByDist :: (Real u, Floating u) + => u -> u -> Radian -> (Vec2 u, Vec2 u)+triVecsByDist tiplen half_tipwidth theta = (vec_to_upper, vec_to_lower)+ where+ hypo_len = sqrt $ (tiplen*tiplen) + (half_tipwidth*half_tipwidth)+ halfang = toRadian $ atan (half_tipwidth / tiplen) + rtheta = pi + theta -- theta in the opposite direction+ vec_to_upper = avec (circularModulo $ rtheta - halfang) hypo_len+ vec_to_lower = avec (circularModulo $ rtheta + halfang) hypo_len ++--------------------------------------------------------------------------------++-- | Tripoints takes the \*tip length\* is the mark height.+--+-- This means that the 90deg tip has a tip width greater-than the+-- mark height (but that is okay - seemingly this is how TikZ +-- does it!).+--+tripointsByAngle :: (Floating u, FromPtSize u)+ => Radian -> Radian -> LocDrawingR u (Point2 u, Point2 u)+tripointsByAngle triang theta tip = + (\h -> let (vupper,vlower) = triVecsByAngle h (0.5*triang) theta+ in (tip .+^ vupper, tip .+^ vlower))+ <$> markHeight++++tripointsByDist :: (Real u, Floating u, FromPtSize u)+ => (u -> u) -> (u -> u) -> Radian + -> LocDrawingR u (Point2 u, Point2 u)+tripointsByDist lenF halfwidthF theta tip = + (\h -> let (vup,vlo) = triVecsByDist (lenF h) (halfwidthF $ 0.5*h) theta+ in (tip .+^ vup, tip .+^ vlo))+ <$> markHeight++++ -- width = xchar_height -- filled with stroke colour! @@ -68,8 +136,8 @@ -> (PrimPath u -> Graphic u) -> LocGraphic u triAng triang theta gf pt = - tripoints triang theta pt >>= \(u,v) -> - localDF bothPrimary (gf $ vertexPath [pt,u,v])+ tripointsByAngle triang theta pt >>= \(u,v) -> + localize bothStrokeColour (gf $ vertexPath [pt,u,v]) @@ -106,7 +174,8 @@ barbAng :: (Floating u, Real u, FromPtSize u) => Radian -> Radian -> LocGraphic u barbAng ang theta pt = - tripoints ang theta pt >>= \(u,v) -> openStroke (vertexPath [u,pt,v])+ tripointsByAngle ang theta pt >>= \(u,v) -> + openStroke (vertexPath [u,pt,v]) barb90 :: (Floating u, Real u, FromPtSize u) @@ -129,3 +198,14 @@ let v = makeV h in openStroke $ vertexPath [ pt .+^ v, pt .-^ v] where makeV h = avec (theta + pi/2) (0.5 * h)+++rbracket :: (Floating u, FromPtSize u) => Radian -> LocGraphic u+rbracket theta pt = markHalfHeight >>= \hh -> + runDirection theta $ + displacePerp hh pt >>= \p1 ->+ displacePara (-hh) p1 >>= \p0 ->+ displacePerp (-hh) pt >>= \p2 ->+ displacePara (-hh) p2 >>= \p3 ->+ return (openStroke $ vertexPath [p0,p1,p2,p3]) +
src/Wumpus/Basic/Colour/SVGColours.hs view
@@ -7,8 +7,8 @@ -- License : BSD3 -- -- Maintainer : Stephen Tetley <stephen.tetley@gmail.com>--- Stability : highly unstable--- Portability : GHC with TypeFamilies and more+-- Stability : unstable+-- Portability : GHC -- -- The SVG \'named colours\', as rgb [0,1] values --
src/Wumpus/Basic/Colour/X11Colours.hs view
@@ -7,8 +7,8 @@ -- License : BSD3 -- -- Maintainer : Stephen Tetley <stephen.tetley@gmail.com>--- Stability : highly unstable--- Portability : GHC with TypeFamilies and more+-- Stability : unstable+-- Portability : GHC -- -- The X11 \'named colours\', as rgb [0,1] values --
src/Wumpus/Basic/Dots.hs view
@@ -11,7 +11,7 @@ -- -- Maintainer : Stephen Tetley <stephen.tetley@gmail.com> -- Stability : highly unstable--- Portability : GHC with TypeFamilies, GADTs and more+-- Portability : GHC -- -- Dots with anchors. --@@ -139,8 +139,8 @@ $ rectangleLines ctr hw hh rectangleLDO :: (Real u, Floating u) - => u -> u -> LocDrawingF u (DotAnchor u)-rectangleLDO w h pt = pureDF $ rectangleAnchor (w*0.5) (h*0.5) pt+ => u -> u -> LocDrawingR u (DotAnchor u)+rectangleLDO w h pt = pure $ rectangleAnchor (w*0.5) (h*0.5) pt circleAnchor :: Floating u => u -> Point2 u -> DotAnchor u@@ -148,7 +148,7 @@ (\theta -> ctr .+^ (avec theta rad)) (radialCardinal rad ctr) -circleLDO :: (Floating u, FromPtSize u) => LocDrawingF u (DotAnchor u)+circleLDO :: (Floating u, FromPtSize u) => LocDrawingR u (DotAnchor u) circleLDO pt = (\diam -> circleAnchor (diam * 0.5) pt) <$> markHeight
src/Wumpus/Basic/Dots/Primitive.hs view
@@ -8,7 +8,7 @@ -- -- Maintainer : Stephen Tetley <stephen.tetley@gmail.com> -- Stability : highly unstable--- Portability : GHC with TypeFamilies and more+-- Portability : GHC -- -- Marks - dots without anchor handles. --@@ -116,26 +116,27 @@ markHLine :: (Fractional u, FromPtSize u) => LocGraphic u -markHLine = standardSize (\h -> axialLine (hvec h))+markHLine = standardSize $ \h -> axialLine (hvec h) markVLine :: (Fractional u, FromPtSize u) => LocGraphic u -markVLine = standardSize (\h -> axialLine (vvec h)) +markVLine = standardSize $ \h -> axialLine (vvec h) markX :: (Fractional u, FromPtSize u) => LocGraphic u-markX = standardSize (\h -> let w = 0.75 * h in- axialLine (vec w h) `lgappend` axialLine (vec (-w) h))+markX = standardSize $ \h -> + let w = 0.75 * h + in mappend <$> axialLine (vec w h) <*> axialLine (vec (-w) h) markPlus :: (Fractional u, FromPtSize u) => LocGraphic u-markPlus = markVLine `lgappend` markHLine+markPlus = mappend <$> markVLine <*> markHLine markCross :: (Floating u, FromPtSize u) => LocGraphic u-markCross = standardSize - (\h -> axialLine (avec ang h) `lgappend` axialLine (avec (-ang) h))+markCross = standardSize $ \h -> + mappend <$> axialLine (avec ang h) <*> axialLine (avec (-ang) h) where ang = pi*0.25 @@ -144,7 +145,7 @@ -- needs horizontal pinch... pathDiamond :: (Fractional u, FromPtSize u) - => Point2 u -> DrawingF (PrimPath u)+ => Point2 u -> DrawingR (PrimPath u) pathDiamond pt = (\h -> let hh = 0.66 * h; hw = 0.5 * h in vertexPath [dvs hh, dve hw,dvn hh, dvw hw]) <$> markHeight@@ -205,7 +206,8 @@ markAsterisk :: (Floating u, FromPtSize u) => LocGraphic u-markAsterisk = standardSize (\h -> lineF1 h `lgappend` lineF2 h `lgappend` lineF3 h)+markAsterisk = standardSize $ \h -> + (\a b c -> a `mappend` b `mappend` c) <$> lineF1 h <*> lineF2 h <*> lineF3 h where ang = (pi*2) / 6 lineF1 z = axialLine (vvec z)@@ -215,15 +217,15 @@ markOPlus :: (Fractional u, FromPtSize u) => LocGraphic u-markOPlus = markCircle `lgappend` markPlus+markOPlus = mappend <$> markCircle <*> markPlus markOCross :: (Floating u, FromPtSize u) => LocGraphic u-markOCross = markCircle `lgappend` markCross+markOCross = mappend <$> markCircle <*> markCross markFOCross :: (Floating u, FromPtSize u) => LocGraphic u-markFOCross = markCross `lgappend` markBCircle +markFOCross = liftA2 mappend markCross markBCircle -- bkCircle :: (Fractional u, FromPtSize u) => LocGraphic u
src/Wumpus/Basic/Graphic.hs view
@@ -17,8 +17,8 @@ module Wumpus.Basic.Graphic (- module Wumpus.Basic.Graphic.BaseClasses- , module Wumpus.Basic.Graphic.BaseTypes+ module Wumpus.Basic.Graphic.Base+ , module Wumpus.Basic.Graphic.DirectionContext , module Wumpus.Basic.Graphic.Drawing , module Wumpus.Basic.Graphic.DrawingContext , module Wumpus.Basic.Graphic.PrimGraphic@@ -26,8 +26,8 @@ , module Wumpus.Basic.Graphic.ScalingContext ) where -import Wumpus.Basic.Graphic.BaseClasses-import Wumpus.Basic.Graphic.BaseTypes+import Wumpus.Basic.Graphic.Base+import Wumpus.Basic.Graphic.DirectionContext import Wumpus.Basic.Graphic.Drawing import Wumpus.Basic.Graphic.DrawingContext import Wumpus.Basic.Graphic.PrimGraphic
+ src/Wumpus/Basic/Graphic/Base.hs view
@@ -0,0 +1,334 @@+{-# LANGUAGE TypeFamilies #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module : Wumpus.Basic.Graphic.Base+-- Copyright : (c) Stephen Tetley 2010+-- License : BSD3+--+-- Maintainer : stephen.tetley@gmail.com+-- Stability : highly unstable+-- Portability : GHC +--+-- Base types for Drawing Objects, Graphics / Images (a Graphic +-- that also returns an answer), etc.+-- +-- Base classes for monadic drawing.+--+-- Note on suffix names. Function types suffixed @F@ are functions +-- from same-to-same, e.g.:+--+-- > type Point2F u = Point2 u -> Point2 u+--+-- Functional types subfixed @R@ are functions from some static +-- context to the answer type (c.f the ReaderMonad), e.g.:+--+-- > newtype DrawingR a = DrawingR { getDrawingR :: DrawingContext -> a }+--+-- The suffix @M@ is used for classes defining monadic actions.+--+-- \*\* WARNING \*\* - some names are expected to change.+--+--------------------------------------------------------------------------------++module Wumpus.Basic.Graphic.Base+ (+ + -- * Drawing monads.+ MonUnit+ , TraceM(..)+ , DrawingCtxM(..)+ , asksDC+ + , PointSupplyM(..)++ -- * Base types+ , HPrim+ , hprimToList+ , singleH++ , Point2F+ , DPoint2F++ , DrawingR+ , LocDrawingR+ , DLocDrawingR++ , runDrawingR++ , Graphic+ , DGraphic+ ++ , runGraphic+ , xlinkGraphic++ , LocGraphic+ , DLocGraphic++ , Image+ , DImage+ , LocImage+ , DLocImage++ , runImage+ , intoImage+ , intoLocImage+ , xlinkImage++ , ConnDrawingR+ , DConnDrawingR+ , ConnGraphic+ , DConnGraphic+ , ConnImage+ , DConnImage++ , intoConnImage++ ) where++import Wumpus.Basic.Graphic.DrawingContext+import Wumpus.Basic.Utils.HList++import Wumpus.Core -- package: wumpus-core+++import Control.Applicative+import Data.Monoid+++--------------------------------------------------------------------------------+-- Monadic drawing++-- | DUnit is always for fully saturated type constructors, so +-- (seemingly) an equivalent type family is needed for monads.++type family MonUnit m :: * +++-- | Collect elementary graphics as part of a larger drawing.+--+-- TraceM works much like a writer monad.+--+class Monad m => TraceM (m :: * -> *) where+ trace :: HPrim (MonUnit m) -> m ()++class Monad m => DrawingCtxM (m :: * -> *) where+ askDC :: m DrawingContext+ localize :: (DrawingContext -> DrawingContext) -> m a -> m a+++-- | Project a value out of a context.+--+asksDC :: DrawingCtxM m => (DrawingContext -> a) -> m a+asksDC f = askDC >>= (return . f)+++++++-- | A monad that supplies points, e.g. a turtle monad. +--+class Monad m => PointSupplyM (m :: * -> *) where+ position :: u ~ MonUnit m => m (Point2 u)+ ++--------------------------------------------------------------------------------+-- Base types++-- | Graphics objects, even simple ones (line, arrow, dot) might +-- need more than one primitive (path or text label) for their+-- construction. Hence, the primary representation that all the +-- others are built upon must support /concatenation/ of +-- primitives. +--+-- Wumpus-Core has a type Picture - made from one or more +-- Primitives - but Pictures include support for affine frames. +-- For drawing many simple graphics (dots, connector lines...) +-- that do not need individual affine transformations this is a +-- penalty. A list of Primitives is therefore more suitable +-- representation, and a Hughes list which supports+-- efficient concatenation is wise.+--+newtype HPrim u = HPrim { getHPrim :: H (PrimElement u) }++-- Note - only a Monoid instance for HPrim - they cannot be +-- shown, fmapped etc.++instance Monoid (HPrim u) where+ mempty = HPrim emptyH+ ha `mappend` hb = HPrim $ getHPrim ha `appendH` getHPrim hb+++hprimToList :: HPrim u -> [PrimElement u]+hprimToList = toListH . getHPrim+++singleH :: PrimElement u -> HPrim u+singleH = HPrim . wrapH ++-- | Point transformation function.+--+type Point2F u = Point2 u -> Point2 u++type DPoint2F = Point2F Double++--------------------------------------------------------------------------------+--++-- | Drawings in Wumpus-Basic have an implicit /graphics state/ +-- the @DrawingContext@, the most primitive building block is +-- a function from the DrawingContext to some polymorphic answer.+-- +-- This functional type is represented concretely as @DrawingR@.+-- +-- > DrawingR :: DrawingContext -> a +--+newtype DrawingR a = DrawingR { getDrawingR :: DrawingContext -> a }+++instance Functor DrawingR where+ fmap f ma = DrawingR $ \ctx -> f $ getDrawingR ma ctx ++-- The monoid instance seems sensible...+--+instance Monoid a => Monoid (DrawingR a) where + mempty = DrawingR $ \_ -> mempty+ fa `mappend` fb = DrawingR $ \ctx -> + getDrawingR fa ctx `mappend` getDrawingR fb ctx++-- Applicative++instance Applicative DrawingR where+ pure a = DrawingR $ \_ -> a+ mf <*> ma = DrawingR $ \ctx -> let f = getDrawingR mf ctx+ a = getDrawingR ma ctx+ in f a++-- Monad ++instance Monad DrawingR where+ return a = DrawingR $ \_ -> a+ ma >>= k = DrawingR $ \ctx -> let a = getDrawingR ma ctx+ in (getDrawingR . k) a ctx +++instance DrawingCtxM DrawingR where+ askDC = DrawingR $ \ctx -> ctx+ localize upd df = DrawingR $ \ctx -> getDrawingR df (upd ctx)+ ++-- | Run a /Drawing Function/ with the supplied /Drawing Context/.+--+runDrawingR :: DrawingContext -> DrawingR a -> a+runDrawingR ctx df = getDrawingR df ctx+++++type LocDrawingR u a = Point2 u -> DrawingR a ++type DLocDrawingR a = LocDrawingR Double a+++--------------------------------------------------------------------------------+++-- Simple drawing - representing one or more prims++type Graphic u = DrawingR (HPrim u)++type DGraphic = Graphic Double+++runGraphic :: DrawingContext -> Graphic u -> HPrim u+runGraphic ctx gf = (getDrawingR gf) ctx+++xlinkGraphic :: XLink -> Graphic u -> Graphic u+xlinkGraphic xlink gf = DrawingR $ \ctx -> + let xs = hprimToList $ runGraphic ctx gf + in (singleH $ xlinkGroup xlink xs)+++--------------------------------------------------------------------------------+++-- | Commonly graphics take a start point as well as a drawing +-- context.+-- +-- Here they are called a LocGraphic - graphic with a (starting) +-- location.+--+type LocGraphic u = Point2 u -> Graphic u++type DLocGraphic = LocGraphic Double+++++--------------------------------------------------------------------------------+++-- | Images return a value as well as drawing. A /node/ is a +-- typical example - nodes are drawing but the also support +-- taking anchor points.+--+type Image u a = DrawingR (a, HPrim u)++type DImage a = Image Double a++type LocImage u a = Point2 u -> Image u a++type DLocImage a = LocImage Double a++runImage :: DrawingContext -> Image u a -> (a,HPrim u)+runImage ctx img = (getDrawingR img) ctx+++intoImage :: DrawingR a -> Graphic u -> Image u a+intoImage f g = DrawingR $ \ctx -> + let a = getDrawingR f ctx; o = getDrawingR g ctx in (a,o)+++intoLocImage :: LocDrawingR u a -> LocGraphic u -> LocImage u a+intoLocImage f g pt = DrawingR $ \ctx -> + let a = getDrawingR (f pt) ctx; o = getDrawingR (g pt) ctx in (a,o)+++xlinkImage :: XLink -> Image u a -> Image u a+xlinkImage xlink img = DrawingR $ \ctx -> + let (a,hp) = runImage ctx img + in (a, singleH $ xlinkGroup xlink $ hprimToList hp)++--------------------------------------------------------------------------------+--++type ConnDrawingR u a = Point2 u -> Point2 u -> DrawingR a++type DConnDrawingR a = ConnDrawingR Double a++-- | ConnGraphic is a connector drawn between two points +-- contructing a Graphic.+--+type ConnGraphic u = Point2 u -> Point2 u -> Graphic u++type DConnGraphic = ConnGraphic Double++-- | ConImage is a connector drawn between two points +-- constructing an Image.+--+type ConnImage u a = Point2 u -> Point2 u -> Image u a++type DConnImage a = ConnImage Double a+++intoConnImage :: ConnDrawingR u a -> ConnGraphic u -> ConnImage u a+intoConnImage f g p1 p2 = DrawingR $ \ctx -> + let a = getDrawingR (f p1 p2) ctx; o = getDrawingR (g p1 p2) ctx in (a,o)++++
− src/Wumpus/Basic/Graphic/BaseClasses.hs
@@ -1,87 +0,0 @@-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module : Wumpus.Basic.Graphic.BaseClasses--- Copyright : (c) Stephen Tetley 2010--- License : BSD3------ Maintainer : stephen.tetley@gmail.com--- Stability : unstable--- Portability : GHC ------ Base classes and type families.------ Drawing is always built on TraceM and DrawingCtxM, it may use--- PointSupplyM for chains or turtle drawing.--------------------------------------------------------------------------------------module Wumpus.Basic.Graphic.BaseClasses- (- MonUnit- , TraceM(..)- , DrawingCtxM(..)- , asksCtx -- , ScalingM(..)- - , PointSupplyM(..)-- ) where--import Wumpus.Basic.Graphic.BaseTypes ( HPrim )-import Wumpus.Basic.Graphic.DrawingContext- --import Wumpus.Core -- package: wumpus-core------- DUnit is always for fully saturated type constructors, so --- (seemingly) an equivalent type family is needed for monads.--type family MonUnit m :: * ----- | Collect elementary graphics as part of a larger drawing.------ TraceM works much like a writer monad.----class Monad m => TraceM (m :: * -> *) where- trace :: HPrim (MonUnit m) -> m ()--class Monad m => DrawingCtxM (m :: * -> *) where- askCtx :: m DrawingContext- localCtx :: (DrawingContext -> DrawingContext) -> m a -> m a----- | Project a value out of a context.----asksCtx :: DrawingCtxM m => (DrawingContext -> a) -> m a-asksCtx f = askCtx >>= (return . f)----- | Scaling...----class ScalingM m where- type XDim m :: *- type YDim m :: *- scaleX :: (u ~ MonUnit m, ux ~ XDim m) => ux -> m u- scaleY :: (u ~ MonUnit m, uy ~ YDim m) => uy -> m u- scalePt :: (u ~ MonUnit m, ux ~ XDim m, uy ~ YDim m) - => ux -> uy -> m (Point2 u)- scaleVec :: (u ~ MonUnit m, ux ~ XDim m, uy ~ YDim m) - => ux -> uy -> m (Vec2 u)----- | A monad that supplies points, e.g. a turtle monad. ----class Monad m => PointSupplyM (m :: * -> *) where- position :: u ~ MonUnit m => m (Point2 u)-
− src/Wumpus/Basic/Graphic/BaseTypes.hs
@@ -1,301 +0,0 @@-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module : Wumpus.Basic.Graphic.Image--- Copyright : (c) Stephen Tetley 2010--- License : BSD3------ Maintainer : stephen.tetley@gmail.com--- Stability : highly unstable--- Portability : GHC ------ Base types for Drawing Objects, Graphics / Images (a Graphic --- that also returns an answer), etc.------ \*\* WARNING \*\* - some names are expected to change --- particularly the naming of the /append/ and /concat/ functions.--------------------------------------------------------------------------------------module Wumpus.Basic.Graphic.BaseTypes- (- -- HPrim- , hprimToList- , singleH-- , Point2F- , DPoint2F-- , DrawingF- , LocDrawingF- , DLocDrawingF-- , runDF- , pureDF - , askDF- , asksDF- , localDF-- , Graphic- , DGraphic- -- , runGraphic- , xlinkGraphic-- , LocGraphic- , DLocGraphic- , localLG- , lgappend-- , Image- , DImage- , LocImage- , DLocImage-- , runImage- , intoImage- , intoLocImage- , xlinkImage-- , ConnDrawingF- , DConnDrawingF- , ConnGraphic- , DConnGraphic- , ConnImage- , DConnImage-- , intoConnImage-- ) where--import Wumpus.Basic.Graphic.DrawingContext-import Wumpus.Basic.Utils.HList--import Wumpus.Core -- package: wumpus-core---import Control.Applicative-import Data.Monoid------ | Graphics objects, even simple ones (line, arrow, dot) might --- need more than one primitive (path or text label) for their--- construction. Hence, the primary representation that all the --- others are built upon must support /concatenation/ of --- primitives. ------ Wumpus-Core has a type Picture - made from one or more --- Primitives - but Pictures include support for affine frames. --- For drawing many simple graphics (dots, connector lines...) --- that do not need individual affine transformations this is a --- penalty. A list of Primitives is therefore more suitable --- representation, and a Hughes list which supports--- efficient concatenation is wise.----newtype HPrim u = HPrim { getHPrim :: H (PrimElement u) }---- Note - only a Monoid instance for HPrim - they cannot be --- shown, fmapped etc.--instance Monoid (HPrim u) where- mempty = HPrim emptyH- ha `mappend` hb = HPrim $ getHPrim ha `appendH` getHPrim hb---hprimToList :: HPrim u -> [PrimElement u]-hprimToList = toListH . getHPrim---singleH :: PrimElement u -> HPrim u-singleH = HPrim . wrapH ---- | Point transformation function.----type Point2F u = Point2 u -> Point2 u--type DPoint2F = Point2F Double----------------------------------------------------------------------------------------- | Drawings in Wumpus-Basic have an implicit /graphics state/ --- the @DrawingContext@, the most primitive building block is --- a function from the DrawingContext to some polymorphic answer.--- --- This functional type is represented concretely as @DrawingF@.--- --- > DrawingF :: DrawingContext -> a ----newtype DrawingF a = DrawingF { getDrawingF :: DrawingContext -> a }---instance Functor DrawingF where- fmap f ma = DrawingF $ \ctx -> f $ getDrawingF ma ctx ---- The monoid instance seems sensible...----instance Monoid a => Monoid (DrawingF a) where - mempty = DrawingF $ \_ -> mempty- fa `mappend` fb = DrawingF $ \ctx -> - getDrawingF fa ctx `mappend` getDrawingF fb ctx---- Applicative--instance Applicative DrawingF where- pure a = DrawingF $ \_ -> a- mf <*> ma = DrawingF $ \ctx -> let f = getDrawingF mf ctx- a = getDrawingF ma ctx- in f a---- Monad --instance Monad DrawingF where- return a = DrawingF $ \_ -> a- ma >>= k = DrawingF $ \ctx -> let a = getDrawingF ma ctx- in (getDrawingF . k) a ctx ---- | Run a /Drawing Function/ with the supplied /Drawing Context/.----runDF :: DrawingContext -> DrawingF a -> a-runDF ctx df = getDrawingF df ctx----- | Wrap a value into a DrawingF.------ Note the value is /pure/ it does depend on the DrawingContext--- (it is /context free/).----pureDF :: a -> DrawingF a-pureDF a = DrawingF $ \ _ctx -> a --askDF :: DrawingF DrawingContext-askDF = DrawingF id--asksDF :: (DrawingContext -> a) -> DrawingF a-asksDF fn = DrawingF $ \ctx -> fn ctx--localDF :: (DrawingContext -> DrawingContext) - -> DrawingF a -> DrawingF a-localDF upd gf = DrawingF $ \ctx -> getDrawingF gf (upd ctx)----type LocDrawingF u a = Point2 u -> DrawingF a --type DLocDrawingF a = LocDrawingF Double a---------------------------------------------------------------------------------------- Simple drawing - representing one or more prims--type Graphic u = DrawingF (HPrim u)--type DGraphic = Graphic Double---runGraphic :: DrawingContext -> Graphic u -> HPrim u-runGraphic ctx gf = (getDrawingF gf) ctx---xlinkGraphic :: XLink -> Graphic u -> Graphic u-xlinkGraphic xlink gf = askDF >>= \ctx -> - let xs = hprimToList $ runGraphic ctx gf in pureDF (singleH $ xlinkGroup xlink xs)---------------------------------------------------------------------------------------- | Commonly graphics take a start point as well as a drawing --- context.--- --- Here they are called a LocGraphic - graphic with a (starting) --- location.----type LocGraphic u = Point2 u -> Graphic u--type DLocGraphic = LocGraphic Double---localLG :: - (DrawingContext -> DrawingContext) -> LocGraphic u -> LocGraphic u-localLG upd img = \pt -> localDF upd (img pt) ----- | Composition operator for LocGraphic - both LocGraphics--- are drawn at the same origin and the results concatenated.-------lgappend :: LocGraphic u -> LocGraphic u -> LocGraphic u-lgappend f g = \pt -> f pt `mappend` g pt---------------------------------------------------------------------------------------- | Images return a value as well as drawing. A /node/ is a --- typical example - nodes are drawing but the also support --- taking anchor points.----type Image u a = DrawingF (a, HPrim u)--type DImage a = Image Double a--type LocImage u a = Point2 u -> Image u a--type DLocImage a = LocImage Double a--runImage :: DrawingContext -> Image u a -> (a,HPrim u)-runImage ctx img = (getDrawingF img) ctx---intoImage :: DrawingF a -> Graphic u -> Image u a-intoImage f g = DrawingF $ \ctx -> - let a = getDrawingF f ctx; o = getDrawingF g ctx in (a,o)---intoLocImage :: LocDrawingF u a -> LocGraphic u -> LocImage u a-intoLocImage f g pt = DrawingF $ \ctx -> - let a = getDrawingF (f pt) ctx; o = getDrawingF (g pt) ctx in (a,o)---xlinkImage :: XLink -> Image u a -> Image u a-xlinkImage xlink img = askDF >>= \ctx -> - let (a,hp) = runImage ctx img - in pureDF (a, singleH $ xlinkGroup xlink $ hprimToList hp)---------------------------------------------------------------------------------------type ConnDrawingF u a = Point2 u -> Point2 u -> DrawingF a--type DConnDrawingF a = ConnDrawingF Double a---- | ConnGraphic is a connector drawn between two points --- contructing a Graphic.----type ConnGraphic u = Point2 u -> Point2 u -> Graphic u--type DConnGraphic = ConnGraphic Double---- | ConImage is a connector drawn between two points --- constructing an Image.----type ConnImage u a = Point2 u -> Point2 u -> Image u a--type DConnImage a = ConnImage Double a---intoConnImage :: ConnDrawingF u a -> ConnGraphic u -> ConnImage u a-intoConnImage f g p1 p2 = DrawingF $ \ctx -> - let a = getDrawingF (f p1 p2) ctx; o = getDrawingF (g p1 p2) ctx in (a,o)----
+ src/Wumpus/Basic/Graphic/DirectionContext.hs view
@@ -0,0 +1,140 @@+{-# LANGUAGE TypeFamilies #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module : Wumpus.Basic.Graphic.DirectionContext+-- Copyright : (c) Stephen Tetley 2010+-- License : BSD3+--+-- Maintainer : stephen.tetley@gmail.com+-- Stability : unstable+-- Portability : GHC+--+-- Reader monad over (angular) direction.+--+--+--------------------------------------------------------------------------------++module Wumpus.Basic.Graphic.DirectionContext+ (++ DirectionM(..)+ , Direction+ , runDirection+ , DirectionT+ , runDirectionT++ , displacePerp+ , displacePara++ ) where++import Wumpus.Basic.Graphic.Base++import Wumpus.Core -- package: wumpus-core++import Data.AffineSpace -- package: vector-space++import Control.Applicative+++-- Should this use MonUnit for consistency ??++class Monad m => DirectionM m where+ localTheta :: Radian -> m a -> m a+ asksTheta :: (Radian -> a) -> m a + parallel :: Floating u => u -> m (Vec2 u)+ perpendicular :: Floating u => u -> m (Vec2 u)+++--+newtype Direction a = Direction { getDirection :: Radian -> a }++++instance Functor Direction where+ fmap f ma = Direction $ \r -> let a = getDirection ma r in f a++instance Applicative Direction where+ pure a = Direction $ \_ -> a+ mf <*> ma = Direction $ \r -> let f = getDirection mf r+ a = getDirection ma r+ in (f a)++instance Monad Direction where+ return a = Direction $ \_ -> a+ m >>= k = Direction $ \r -> let a = getDirection m r+ in (getDirection . k) a r++++runDirection :: Radian -> Direction a -> a+runDirection theta sf = (getDirection sf) theta+++instance DirectionM Direction where+ localTheta theta ma = Direction $ \_ -> getDirection ma theta+ asksTheta fn = Direction $ \r -> fn r+ parallel d = Direction $ \r -> avec (circularModulo r) d+ perpendicular d = Direction $ \r -> + avec (circularModulo $ (0.5*pi) + r) d +++--------------------------------------------------------------------------------+-- Transformer++newtype DirectionT m a = DirectionT { getDirectionT :: Radian -> m a }++type instance MonUnit (DirectionT m) = MonUnit m++instance Monad m => Functor (DirectionT m) where+ fmap f ma = DirectionT $ \r -> getDirectionT ma r >>= \a -> return (f a)++instance Monad m => Applicative (DirectionT m) where+ pure a = DirectionT $ \_ -> return a+ mf <*> ma = DirectionT $ \r -> getDirectionT mf r >>= \f -> + getDirectionT ma r >>= \a ->+ return (f a)++instance Monad m => Monad (DirectionT m) where+ return a = DirectionT $ \_ -> return a+ m >>= k = DirectionT $ \r -> getDirectionT m r >>= \a -> + (getDirectionT . k) a r++++instance Monad m => DirectionM (DirectionT m) where+ localTheta theta ma = DirectionT $ \_ -> getDirectionT ma theta+ asksTheta fn = DirectionT $ \r -> return (fn r)+ parallel d = DirectionT $ \r -> return (avec (circularModulo r) d)+ perpendicular d = DirectionT $ \r -> + return (avec (circularModulo $ (0.5*pi) + r) d)+++-- Cross instances - needed to run SalingT /locally/ in Drawing.++instance DrawingCtxM m => DrawingCtxM (DirectionT m) where+ askDC = DirectionT $ \_ -> askDC >>= \dctx -> return dctx+ localize ctx mf = DirectionT $ \r -> localize ctx (getDirectionT mf r)+++instance (Monad m, TraceM m) => TraceM (DirectionT m) where+ trace a = DirectionT $ \_ -> trace a ++++++runDirectionT :: Radian -> DirectionT m a -> m a+runDirectionT theta sf = (getDirectionT sf) theta+++--------------------------------------------------------------------------------++displacePerp :: (DirectionM m, Floating u) => u -> Point2 u -> m (Point2 u)+displacePerp u pt = perpendicular u >>= \v -> return (pt .+^ v)+++displacePara :: (DirectionM m, Floating u) => u -> Point2 u -> m (Point2 u)+displacePara u pt = parallel u >>= \v -> return (pt .+^ v)
src/Wumpus/Basic/Graphic/Drawing.hs view
@@ -54,8 +54,7 @@ ) where -import Wumpus.Basic.Graphic.BaseClasses-import Wumpus.Basic.Graphic.BaseTypes+import Wumpus.Basic.Graphic.Base import Wumpus.Basic.Graphic.DrawingContext @@ -157,14 +156,14 @@ -- DrawingCtxM instance DrawingCtxM (Drawing u) where- askCtx = Drawing $ \ctx s -> (ctx, s)- localCtx cF ma = Drawing $ \ctx s -> getDrawing ma (cF ctx) s+ askDC = Drawing $ \ctx s -> (ctx, s)+ localize upd ma = Drawing $ \ctx s -> getDrawing ma (upd ctx) s instance Monad m => DrawingCtxM (DrawingT u m) where- askCtx = DrawingT $ \ctx s -> return (ctx,s)- localCtx cF ma = DrawingT $ \ctx s -> getDrawingT ma (cF ctx) s+ askDC = DrawingT $ \ctx s -> return (ctx,s)+ localize upd ma = DrawingT $ \ctx s -> getDrawingT ma (upd ctx) s @@ -281,7 +280,7 @@ -- This operation is analogeous to @tell@ in a Writer monad. -- draw :: (TraceM m, DrawingCtxM m, u ~ MonUnit m) => Graphic u -> m ()-draw gf = askCtx >>= \ctx -> trace (runGraphic ctx gf)+draw gf = askDC >>= \ctx -> trace (runGraphic ctx gf) -- | Hyperlink version of 'draw'. --@@ -298,7 +297,7 @@ -- monad, and the result is returned. -- drawi :: (TraceM m, DrawingCtxM m, u ~ MonUnit m) => Image u a -> m a-drawi img = askCtx >>= \ctx -> +drawi img = askDC >>= \ctx -> let (a,o) = runImage ctx img in trace o >> return a -- | Hyperlink version of 'drawi'.@@ -326,13 +325,13 @@ node :: (TraceM m, DrawingCtxM m, PointSupplyM m, u ~ MonUnit m) => LocGraphic u -> m ()-node gfL = askCtx >>= \ctx -> +node gfL = askDC >>= \ctx -> position >>= \pt -> trace (runGraphic ctx $ gfL pt) nodei :: (TraceM m, DrawingCtxM m, PointSupplyM m, u ~ MonUnit m) => LocImage u a -> m a-nodei imgL = askCtx >>= \ctx -> +nodei imgL = askDC >>= \ctx -> position >>= \pt -> let (a,o) = runImage ctx (imgL pt) in trace o >> return a
src/Wumpus/Basic/Graphic/DrawingContext.hs view
@@ -8,7 +8,7 @@ -- -- Maintainer : Stephen Tetley <stephen.tetley@gmail.com> -- Stability : highly unstable--- Portability : GHC with TypeFamilies and more+-- Portability : GHC -- -- Drawing attributes --@@ -25,8 +25,10 @@ -- * Drawing context DrawingContext(..)+ , DrawingContextF , standardContext+ , default_drawing_context -- * Modifiers -- ** Line widths@@ -34,6 +36,16 @@ , ultrathick , thin + -- ** Line caps+ , capButt+ , capRound+ , capSquare++ -- ** Line joins+ , joinMiter+ , joinRound+ , joinBevel+ -- ** Dash Pattern , dashPattern , unit_dash_pattern@@ -42,20 +54,20 @@ , doublegaps , doubledashes - -- ** Font properties+ -- * Font properties , fontsize , fontface - -- ** Mark drawing size+ -- * Font / mark drawing size , doublesize , halfsize - -- ** Colour+ -- * Colour , swapColours- , bothPrimary- , bothSecondary- , primaryColour- , secondaryColour + , bothStrokeColour+ , bothFillColour+ , strokeColour+ , fillColour @@ -73,32 +85,34 @@ data DrawingContext = DrawingContext { stroke_props :: StrokeAttr , font_props :: FontAttr- , primary_colour :: RGBi -- usually the stroke colour- , secondary_colour :: RGBi -- usually the fill colour+ , stroke_colour :: RGBi -- also text colour...+ , fill_colour :: RGBi , line_spacing_factor :: Double } deriving (Eq,Show) +type DrawingContextF = DrawingContext -> DrawingContext + standardContext :: FontSize -> DrawingContext standardContext sz = - DrawingContext { stroke_props = default_stroke_attr- , font_props = FontAttr sz courier- , primary_colour = black- , secondary_colour = light_gray- , line_spacing_factor = 1.2 + DrawingContext { stroke_props = default_stroke_attr+ , font_props = FontAttr sz courier+ , stroke_colour = black+ , fill_colour = light_gray+ , line_spacing_factor = 1.2 } -+default_drawing_context :: DrawingContext+default_drawing_context = + standardContext (font_size wumpus_default_font) -updateStrokeProps :: (StrokeAttr -> StrokeAttr) - -> DrawingContext -> DrawingContext+updateStrokeProps :: (StrokeAttr -> StrokeAttr) -> DrawingContextF updateStrokeProps fn = (\s i -> s { stroke_props = fn i }) <*> stroke_props -updateFontProps :: (FontAttr -> FontAttr) - -> DrawingContext -> DrawingContext+updateFontProps :: (FontAttr -> FontAttr) -> DrawingContextF updateFontProps fn = (\s i -> s { font_props = fn i }) <*> font_props @@ -120,7 +134,7 @@ thin_line :: Double thin_line = 0.5 -setLineWidth :: Double -> DrawingContext -> DrawingContext+setLineWidth :: Double -> DrawingContextF setLineWidth d = updateStrokeProps (\s -> s { line_width = d }) -- | Set the line width to a /thick/.@@ -128,18 +142,47 @@ -- Note this context update is /oblivious/ - operationally the -- line width is set to exactly @2.0@. ---thick :: DrawingContext -> DrawingContext+thick :: DrawingContextF thick = setLineWidth thick_line -ultrathick :: DrawingContext -> DrawingContext+ultrathick :: DrawingContextF ultrathick = setLineWidth ultra_thick_line -thin :: DrawingContext -> DrawingContext+thin :: DrawingContextF thin = setLineWidth thin_line ++setLineCap :: LineCap -> DrawingContextF+setLineCap d = updateStrokeProps (\s -> s { line_cap = d })+++capButt :: DrawingContextF+capButt = setLineCap CapButt++capRound :: DrawingContextF+capRound = setLineCap CapRound++capSquare :: DrawingContextF+capSquare = setLineCap CapSquare+++setLineJoin :: LineJoin -> DrawingContextF+setLineJoin d = updateStrokeProps (\s -> s { line_join = d })+++joinMiter :: DrawingContextF+joinMiter = setLineJoin JoinMiter++joinRound :: DrawingContextF+joinRound = setLineJoin JoinRound++joinBevel :: DrawingContextF+joinBevel = setLineJoin JoinBevel++ -------------------------------------------------------------------------------- -dashPattern :: DashPattern -> DrawingContext -> DrawingContext+dashPattern :: DashPattern -> DrawingContextF dashPattern d = updateStrokeProps (\s -> s { dash_pattern = d }) unit_dash_pattern :: DashPattern@@ -171,10 +214,10 @@ -------------------------------------------------------------------------------- -fontface :: FontFace -> DrawingContext -> DrawingContext+fontface :: FontFace -> DrawingContextF fontface ff = updateFontProps (\(FontAttr sz _) -> FontAttr sz ff) -fontsize :: Int -> DrawingContext -> DrawingContext+fontsize :: Int -> DrawingContextF fontsize sz = updateFontProps (\(FontAttr _ ff) -> FontAttr sz ff) --------------------------------------------------------------------------------@@ -182,7 +225,7 @@ -- | Set the font size to double the current size, note the font -- size also controls the size of dots, arrowsheads etc. -- -doublesize :: DrawingContext -> DrawingContext+doublesize :: DrawingContextF doublesize = (\s sz -> fontsize (sz*2) s) <*> (font_size . font_props) @@ -192,30 +235,30 @@ -- As fontsize is an integer this is not exact - half size of -- 15pt type is 7pt. -- -halfsize :: DrawingContext -> DrawingContext+halfsize :: DrawingContextF halfsize = (\s sz -> fontsize (sz `div` 2) s) <*> (font_size . font_props) -------------------------------------------------------------------------------- -swapColours :: DrawingContext -> DrawingContext+swapColours :: DrawingContextF swapColours = - (\s a b -> s { primary_colour = b, secondary_colour = a })- <*> primary_colour <*> secondary_colour+ (\s a b -> s { stroke_colour = b, fill_colour = a })+ <*> stroke_colour <*> fill_colour -bothPrimary :: DrawingContext -> DrawingContext-bothPrimary = (\s a -> s { secondary_colour = a }) <*> primary_colour+bothStrokeColour :: DrawingContextF+bothStrokeColour = (\s a -> s { fill_colour = a }) <*> stroke_colour -bothSecondary :: DrawingContext -> DrawingContext-bothSecondary = (\s a -> s { primary_colour = a }) <*> secondary_colour+bothFillColour :: DrawingContextF+bothFillColour = (\s a -> s { stroke_colour = a }) <*> fill_colour -primaryColour :: RGBi -> DrawingContext -> DrawingContext-primaryColour rgb = \s -> s { primary_colour = rgb } +strokeColour :: RGBi -> DrawingContextF+strokeColour rgb = \s -> s { stroke_colour = rgb } -secondaryColour :: RGBi -> DrawingContext -> DrawingContext-secondaryColour rgb = \s -> s { secondary_colour = rgb } +fillColour :: RGBi -> DrawingContextF+fillColour rgb = \s -> s { fill_colour = rgb }
src/Wumpus/Basic/Graphic/PrimGraphic.hs view
@@ -49,6 +49,7 @@ , straightLine , straightLineBetween+ , curveBetween , strokedRectangle , filledRectangle@@ -66,7 +67,7 @@ ) where -import Wumpus.Basic.Graphic.BaseTypes+import Wumpus.Basic.Graphic.Base import Wumpus.Basic.Graphic.DrawingContext import Wumpus.Basic.Graphic.Query @@ -217,6 +218,10 @@ straightLineBetween :: Fractional u => Point2 u -> Point2 u -> Graphic u straightLineBetween p1 p2 = openStroke $ path p1 [lineTo p2]++curveBetween :: Fractional u + => Point2 u -> Point2 u -> Point2 u -> Point2 u -> Graphic u+curveBetween sp cp1 cp2 ep = openStroke $ path sp [curveTo cp1 cp2 ep]
src/Wumpus/Basic/Graphic/Query.hs view
@@ -8,7 +8,7 @@ -- -- Maintainer : Stephen Tetley <stephen.tetley@gmail.com> -- Stability : highly unstable--- Portability : GHC with TypeFamilies and more+-- Portability : GHC -- -- Querying the Drawing Context. --@@ -33,6 +33,7 @@ , lineWidth , fontSize , markHeight+ , markHalfHeight , lineSpacing -- @@ -48,7 +49,7 @@ , monoVecToCenter ) where -import Wumpus.Basic.Graphic.BaseTypes+import Wumpus.Basic.Graphic.Base import Wumpus.Basic.Graphic.DrawingContext @@ -57,54 +58,57 @@ import Control.Applicative -textAttr :: DrawingF (RGBi,FontAttr)-textAttr = (,) <$> asksDF primary_colour <*> asksDF font_props+textAttr :: (Applicative m, DrawingCtxM m) => m (RGBi,FontAttr)+textAttr = (,) <$> asksDC stroke_colour <*> asksDC font_props -- | Because @textAttr@ is so commonly used here is a functional -- version that avoids tupling. ---withTextAttr :: (RGBi -> FontAttr -> a) -> DrawingF a-withTextAttr fn = fn <$> asksDF primary_colour <*> asksDF font_props+withTextAttr :: (Applicative m, DrawingCtxM m) + => (RGBi -> FontAttr -> a) -> m a+withTextAttr fn = fn <$> asksDC stroke_colour <*> asksDC font_props -strokeAttr :: DrawingF (RGBi, StrokeAttr)-strokeAttr = (,) <$> asksDF primary_colour <*> asksDF stroke_props+strokeAttr :: (Applicative m, DrawingCtxM m) => m (RGBi, StrokeAttr)+strokeAttr = (,) <$> asksDC stroke_colour <*> asksDC stroke_props -withStrokeAttr :: (RGBi -> StrokeAttr -> a) -> DrawingF a-withStrokeAttr fn = fn <$> asksDF primary_colour <*> asksDF stroke_props+withStrokeAttr :: (Applicative m, DrawingCtxM m) + => (RGBi -> StrokeAttr -> a) -> m a+withStrokeAttr fn = fn <$> asksDC stroke_colour <*> asksDC stroke_props -fillAttr :: DrawingF RGBi-fillAttr = asksDF secondary_colour+fillAttr :: (Applicative m, DrawingCtxM m) => m RGBi+fillAttr = asksDC fill_colour -withFillAttr :: (RGBi -> a) -> DrawingF a-withFillAttr fn = fn <$> asksDF secondary_colour+withFillAttr :: (Applicative m, DrawingCtxM m) => (RGBi -> a) -> m a+withFillAttr fn = fn <$> asksDC fill_colour -borderedAttr :: DrawingF (RGBi, StrokeAttr, RGBi)-borderedAttr = (,,) <$> asksDF secondary_colour <*> asksDF stroke_props - <*> asksDF primary_colour+borderedAttr :: (Applicative m, DrawingCtxM m) => m (RGBi, StrokeAttr, RGBi)+borderedAttr = (,,) <$> asksDC fill_colour <*> asksDC stroke_props + <*> asksDC stroke_colour -withBorderedAttr :: (RGBi -> StrokeAttr -> RGBi -> a) -> DrawingF a+withBorderedAttr :: (Applicative m, DrawingCtxM m) + => (RGBi -> StrokeAttr -> RGBi -> a) -> m a withBorderedAttr fn = - fn <$> asksDF secondary_colour <*> asksDF stroke_props - <*> asksDF primary_colour+ fn <$> asksDC fill_colour <*> asksDC stroke_props + <*> asksDC stroke_colour -lineWidth :: DrawingF Double-lineWidth = line_width <$> asksDF stroke_props+lineWidth :: (Applicative m, DrawingCtxM m) => m Double+lineWidth = line_width <$> asksDC stroke_props -fontSize :: DrawingF Int-fontSize = font_size <$> asksDF font_props+fontSize :: (Applicative m, DrawingCtxM m) => m Int+fontSize = font_size <$> asksDC font_props -- Maybe these functions are better as queries - i.e. functions--- of type DrawingF, e.g.+-- of type DrawingR, e.g. -- --- > lineSpacing :: Fractional u => DrawingF u+-- > lineSpacing :: Fractional u => DrawingR u -- -- Then the /client/ can just bound the answer directly -- rather than using @@ -112,19 +116,26 @@ -- > askDF lineSpacing >>= \u -> ... -- -lineSpacing :: Fractional u => DrawingF u+lineSpacing :: (Applicative m, DrawingCtxM m, Fractional u) => m u lineSpacing = (\sz factor -> realToFrac $ factor * fromIntegral sz)- <$> asksDF (font_size . font_props) <*> asksDF line_spacing_factor+ <$> asksDC (font_size . font_props) <*> asksDC line_spacing_factor --- | A Mark is consider to be the height of a lowercase letter--- in the current font.--- --- Note better to use xlowerHeight+-- | The /mark/ height is the height of a lowercase letter in the +-- current font.+--+-- Arrowheads, dots etc. should generally be drawn at the mark +-- height. -- -markHeight :: FromPtSize u => DrawingF u-markHeight = (fromPtSize . xcharHeight . font_size) <$> asksDF font_props+markHeight :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u+markHeight = (fromPtSize . xcharHeight . font_size) <$> asksDC font_props ++markHalfHeight :: (Applicative m, DrawingCtxM m, Fractional u, FromPtSize u) + => m u+markHalfHeight = (0.5*) <$> markHeight++ -- Note - there are probably enough functions that use just -- markHeight to merit a withMarkHeight function. @@ -135,28 +146,28 @@ -------------------------------------------------------------------------------- -withFontSize :: (FontSize -> u) -> DrawingF u-withFontSize fn = fn . font_size <$> asksDF font_props+withFontSize :: (Applicative m, DrawingCtxM m) => (FontSize -> u) -> m u+withFontSize fn = (fn . font_size) <$> asksDC font_props -monoCharWidth :: FromPtSize u => DrawingF u+monoCharWidth :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u monoCharWidth = withFontSize (fromPtSize . charWidth) -monoSpacerWidth :: FromPtSize u => DrawingF u+monoSpacerWidth :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u monoSpacerWidth = withFontSize (fromPtSize . spacerWidth) -monoTextWidth :: FromPtSize u => Int -> DrawingF u+monoTextWidth :: (Applicative m, DrawingCtxM m, FromPtSize u) => Int -> m u monoTextWidth n = withFontSize $ \sz -> fromPtSize $ textWidth sz n -monoTextLength :: FromPtSize u => String -> DrawingF u+monoTextLength :: (Applicative m, DrawingCtxM m, FromPtSize u) => String -> m u monoTextLength ss = monoTextWidth $ charCount ss -monoTextHeight :: FromPtSize u => DrawingF u+monoTextHeight :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u monoTextHeight = withFontSize (fromPtSize . textHeight) -monoNumeralHeight :: FromPtSize u => DrawingF u+monoNumeralHeight :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u monoNumeralHeight = withFontSize (fromPtSize . numeralHeight) @@ -164,10 +175,10 @@ -- -- \'x\' has no ascenders or descenders. -- -monoLowerxHeight :: FromPtSize u => DrawingF u+monoLowerxHeight :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u monoLowerxHeight = withFontSize (fromPtSize . xcharHeight) -monoDescenderDepth :: FromPtSize u => DrawingF u+monoDescenderDepth :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u monoDescenderDepth = withFontSize (fromPtSize . descenderDepth) @@ -177,16 +188,18 @@ -- Note - the width will generally be a over-estimate for -- non-monospaced fonts. -- -monoTextDimensions :: (Num u, Ord u, FromPtSize u) => String -> DrawingF (u,u)+monoTextDimensions :: (Applicative m, DrawingCtxM m, Num u, Ord u, FromPtSize u)+ => String -> m (u,u) monoTextDimensions ss = (\sz -> post $ textBounds sz zeroPt ss) - <$> asksDF (font_size . font_props)+ <$> asksDC (font_size . font_props) where post bb = (boundaryWidth bb, boundaryHeight bb) -- | Vector from baseline left to center-monoVecToCenter :: (Fractional u, Ord u, FromPtSize u) - => String -> DrawingF (Vec2 u)+monoVecToCenter :: ( Applicative m, DrawingCtxM m+ , Fractional u, Ord u, FromPtSize u ) + => String -> m (Vec2 u) monoVecToCenter ss = (\(w,h) dy -> vec (0.5*w) (0.5*h - dy)) <$> monoTextDimensions ss <*> monoDescenderDepth
src/Wumpus/Basic/Graphic/ScalingContext.hs view
@@ -17,8 +17,10 @@ module Wumpus.Basic.Graphic.ScalingContext (- ScalingContext(..) + ScalingM(..)+ , ScalingContext(..)+ , Scaling , runScaling , ScalingT@@ -33,12 +35,28 @@ ) where -import Wumpus.Basic.Graphic.BaseClasses+import Wumpus.Basic.Graphic.Base import Wumpus.Core -- package: wumpus-core import Control.Applicative +++-- | Scaling...+--+class Monad m => ScalingM m where+ type XDim m :: *+ type YDim m :: *+ scaleX :: (u ~ MonUnit m, ux ~ XDim m) => ux -> m u+ scaleY :: (u ~ MonUnit m, uy ~ YDim m) => uy -> m u+ scalePt :: (u ~ MonUnit m, ux ~ XDim m, uy ~ YDim m) + => ux -> uy -> m (Point2 u)+ scaleVec :: (u ~ MonUnit m, ux ~ XDim m, uy ~ YDim m) + => ux -> uy -> m (Vec2 u)+++ data ScalingContext ux uy u = ScalingContext { scale_in_x :: ux -> u , scale_in_y :: uy -> u@@ -128,8 +146,8 @@ -- Cross instances - needed to run SalingT /locally/ in Drawing. instance DrawingCtxM m => DrawingCtxM (ScalingT ux uy u m) where- askCtx = ScalingT $ \_ -> askCtx >>= \dctx -> return dctx- localCtx ctx mf = ScalingT $ \sctx -> localCtx ctx (getScalingT mf sctx)+ askDC = ScalingT $ \_ -> askDC >>= \dctx -> return dctx+ localize upd mf = ScalingT $ \sctx -> localize upd (getScalingT mf sctx) instance (Monad m, TraceM m, u ~ MonUnit m) => TraceM (ScalingT ux uy u m) where
src/Wumpus/Basic/Monads/TurtleMonad.hs view
@@ -125,8 +125,8 @@ -- Cross instances instance DrawingCtxM m => DrawingCtxM (TurtleT u m) where- askCtx = TurtleT $ \s -> askCtx >>= \ ctx -> return (ctx,s)- localCtx ctx mf = TurtleT $ \s -> localCtx ctx (getTurtleT mf s)+ askDC = TurtleT $ \s -> askDC >>= \ ctx -> return (ctx,s)+ localize upd mf = TurtleT $ \s -> localize upd (getTurtleT mf s) -- This needs undecidable instances...
src/Wumpus/Basic/Paths/Base.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE FlexibleContexts #-} {-# OPTIONS -Wall #-} @@ -22,23 +23,38 @@ module Wumpus.Basic.Paths.Base ( - Path(..)- , PathSeg(..)- , Curve(..)- , Line(..)- , emptyPath- , pline- , pcurve- , addSegment- , segmentLength- , segmentStart- , segmentEnd+ Path+ , DPath+ , length+ , line+ , curve+ , tracePoints+ , curveByAngles , toPrimPath , toPrimPathU- , subdivide- , subdividet- +++ , tipL+ , tipR++ , shortenBoth+ , shortenL+ , shortenR+ , directionL+ , directionR++ , midpoint++ , PathViewL(..)+ , DPathViewL+ , PathViewR(..)+ , DPathViewR+ , PathSegment(..)+ , DPathSegment+ , pathViewL+ , pathViewR+ ) where @@ -48,77 +64,127 @@ import Data.VectorSpace import Data.Maybe-import Data.Sequence ( Seq, ViewL(..), viewl, (|>) )+import Data.Monoid+import Data.Sequence ( Seq, (><), ViewL(..), viewl+ , ViewR(..), viewr, (<|) , (|>) ) import qualified Data.Sequence as S --- Note - path doesn\'t need a drawing context for --- construction...------ type PathF u = Point2 u -> Point2 u -> Path u-+import Prelude hiding ( length ) -data Path u = Path - { path_length :: u - , path_elements :: Seq (PathSeg u)- }+data Path u = PathEmpty + | Path { _path_length :: u + , _path_start :: Point2 u+ , _path_elements :: Seq (PathSeg u)+ , _path_end :: Point2 u+ } deriving (Eq,Ord,Show) +type DPath = Path Double +-- Annotating each segment with length is \*\* good \*\*.+-- Makes it much more efficient to find the midpoint.+--+-- But what do we do about the start point:+--+-- a) put it in the segment - too much info in the type, allows +-- consistency problems vis-a-vis gaps in the path.+--+-- b) leave it out - too little info in the type, allows +-- consistency problems with length.+--+-- Option (a) is probably most convenient espcially as the +-- constructors won\'t be exported.+ -- Annotation is length... -- -data PathSeg u = LineSeg u (Line u)- | CurveSeg u (Curve u)+data PathSeg u = LineSeg { _line_length :: u + , _line_start :: Point2 u+ , _line_end :: Point2 u+ }+ | CurveSeg { _curve_length :: u + , _curve_start :: Point2 u+ , _ctrl_pt_one :: Point2 u+ , _ctrl_pt_two :: Point2 u+ , _curve_end :: Point2 u+ } deriving (Eq,Ord,Show) -data Curve u = Curve - { curve_start :: Point2 u- , ctrl_point1 :: Point2 u- , ctrl_point2 :: Point2 u- , curve_end :: Point2 u- }- deriving (Eq,Ord,Show)+type instance DUnit (Path u) = u+type instance DUnit (PathSeg u) = u -data Line u = Line - { line_start :: Point2 u- , line_end :: Point2 u - }- deriving (Eq,Ord,Show) -emptyPath :: Num u => Path u -emptyPath = Path 0 S.empty+length :: Num u => Path u -> u+length PathEmpty = 0+length (Path u _ _ _) = u +append :: Floating u => Path u -> Path u -> Path u+append PathEmpty b = b+append a PathEmpty = a+append (Path len1 start1 se1 end1) (Path len2 start2 se2 end2) + | end1 == start2 = Path (len1+len2) start1 (se1 >< se2) end2 + | otherwise = let join = lineSegment end1 start2+ total_len = len1 + len2 + segmentLength join+ in Path total_len start1 (se1 >< (join <| se2)) end2 -addSegment :: Num u => Path u -> PathSeg u -> Path u-addSegment (Path n se) e@(LineSeg u _) = Path (n+u) (se |> e)-addSegment (Path n se) e@(CurveSeg u _) = Path (n+u) (se |> e) +instance Floating u => Monoid (Path u) where+ mempty = PathEmpty+ mappend = append+++ segmentLength :: PathSeg u -> u-segmentLength (LineSeg u _) = u-segmentLength (CurveSeg u _) = u+segmentLength (LineSeg u _ _) = u+segmentLength (CurveSeg u _ _ _ _) = u + segmentStart :: PathSeg u -> Point2 u-segmentStart (LineSeg _ (Line p0 _)) = p0-segmentStart (CurveSeg _ (Curve p0 _ _ _)) = p0+segmentStart (LineSeg _ p0 _) = p0+segmentStart (CurveSeg _ p0 _ _ _) = p0 segmentEnd :: PathSeg u -> Point2 u-segmentEnd (LineSeg _ (Line _ p1)) = p1-segmentEnd (CurveSeg _ (Curve _ _ _ p3)) = p3+segmentEnd (LineSeg _ _ p1) = p1+segmentEnd (CurveSeg _ _ _ _ p3) = p3 -pline :: Floating u => Point2 u -> Point2 u -> PathSeg u -pline p0 p1 = LineSeg (vlength $ pvec p0 p1) (Line p0 p1)+lineSegment :: Floating u => Point2 u -> Point2 u -> PathSeg u +lineSegment p0 p1 = let v = vlength $ pvec p0 p1 in LineSeg v p0 p1 -pcurve :: (Floating u, Ord u)- => Point2 u -> Point2 u -> Point2 u -> Point2 u -> PathSeg u -pcurve p0 p1 p2 p3 = - let c = Curve p0 p1 p2 p3 in CurveSeg (curveLength c) c+line :: Floating u => Point2 u -> Point2 u -> Path u +line p0 p1 = let v = vlength $ pvec p0 p1 + in Path v p0 (S.singleton $ LineSeg v p0 p1) p1+ +curve :: (Floating u, Ord u)+ => Point2 u -> Point2 u -> Point2 u -> Point2 u -> Path u +curve p0 p1 p2 p3 = let v = curveLength p0 p1 p2 p3+ in Path v p0 (S.singleton $ CurveSeg v p0 p1 p2 p3) p3 --- | Turn a BasicPath into an ordinary Path.++tracePoints :: Floating u => [Point2 u] -> Path u+tracePoints [] = PathEmpty+tracePoints [a] = line a a+tracePoints (a:b:xs) = step (line a b) b xs+ where+ step acc _ [] = acc+ step acc e (y:ys) = step (acc `mappend` line e y) y ys+++curveByAngles :: (Floating u, Ord u) + => Point2 u -> Radian -> Radian -> Point2 u -> Path u+curveByAngles start cin cout end = curve start (start .+^ v1) (end .+^ v2) end+ where+ sz = 0.375 * (vlength $ pvec start end)+ v1 = avec cin sz+ v2 = avec cout sz++++-- | Turn a Path into an ordinary PrimPath. -- -- An empty path returns Nothing - the path representation in -- Wumpus-Core does not allow empty paths - a path must always@@ -129,21 +195,22 @@ -- segment. -- toPrimPath :: Path u -> Maybe (PrimPath u)-toPrimPath = step1 . viewl . path_elements+toPrimPath PathEmpty = Nothing+toPrimPath (Path _ _ segs _) = step1 $ viewl segs where- step1 EmptyL = Nothing- step1 (e :< se) = let (p1,s) = elemP e in - Just $ path p1 $ s : step2 (viewl se)+ step1 EmptyL = Nothing+ step1 (e :< se) = let (start,a) = seg1 e in + Just $ path start $ a : step2 (viewl se) - step2 EmptyL = []- step2 (e :< se) = snd (elemP e) : step2 (viewl se)+ step2 EmptyL = []+ step2 (e :< se) = seg2 e : step2 (viewl se) - elemP (LineSeg _ l) = elemL l- elemP (CurveSeg _ c) = elemC c+ seg1 (LineSeg _ p0 p1) = (p0, lineTo p1)+ seg1 (CurveSeg _ p0 p1 p2 p3) = (p0, curveTo p1 p2 p3) - elemL (Line p1 p2) = (p1, lineTo p2)- elemC (Curve p1 p2 p3 p4) = (p1, curveTo p2 p3 p4)-+ seg2 (LineSeg _ _ p1) = lineTo p1+ seg2 (CurveSeg _ _ p1 p2 p3) = curveTo p1 p2 p3+ toPrimPathU :: Path u -> PrimPath u toPrimPathU = fromMaybe errK . toPrimPath where@@ -154,14 +221,18 @@ -------------------------------------------------------------------------------- -- Curve length -curveLength :: (Floating u, Ord u) => Curve u -> u-curveLength = gravesenLength 0.1+data StrictCurve u = Curve !(Point2 u) !(Point2 u) !(Point2 u) !(Point2 u) +curveLength :: (Floating u, Ord u) + => Point2 u -> Point2 u -> Point2 u -> Point2 u -> u+curveLength p0 p1 p2 p3 = gravesenLength 0.1 $ Curve p0 p1 p2 p3++ -- | Jens Gravesen\'s bezier arc-length approximation. -- -- Note this implementation is parametrized on error tolerance. ---gravesenLength :: (Floating u, Ord u) => u -> Curve u -> u+gravesenLength :: (Floating u, Ord u) => u -> StrictCurve u -> u gravesenLength err_tol crv = step crv where step c = let l1 = ctrlPolyLength c l0 = cordLength c@@ -170,12 +241,12 @@ else 0.5*l0 + 0.5*l1 -ctrlPolyLength :: Floating u => Curve u -> u+ctrlPolyLength :: Floating u => StrictCurve u -> u ctrlPolyLength (Curve p0 p1 p2 p3) = len p0 p1 + len p1 p2 + len p2 p3 where len pa pb = vlength $ pvec pa pb -cordLength :: Floating u => Curve u -> u+cordLength :: Floating u => StrictCurve u -> u cordLength (Curve p0 _ _ p3) = vlength $ pvec p0 p3 @@ -187,7 +258,8 @@ -- | Curve subdivision via de Casteljau\'s algorithm. ---subdivide :: Fractional u => Curve u -> (Curve u, Curve u)+subdivide :: Fractional u + => StrictCurve u -> (StrictCurve u, StrictCurve u) subdivide (Curve p0 p1 p2 p3) = (Curve p0 p01 p012 p0123, Curve p0123 p123 p23 p3) where@@ -201,7 +273,7 @@ -- | subdivide with an affine weight along the line... -- subdividet :: Real u- => u -> Curve u -> (Curve u, Curve u)+ => u -> StrictCurve u -> (StrictCurve u, StrictCurve u) subdividet t (Curve p0 p1 p2 p3) = (Curve p0 p01 p012 p0123, Curve p0123 p123 p23 p3) where@@ -215,3 +287,196 @@ affineCombination :: Real u => u -> Point2 u -> Point2 u -> Point2 u affineCombination a p1 p2 = p1 .+^ a *^ (p2 .-. p1) +--------------------------------------------------------------------------------+-- tips ++tipL :: Path u -> Maybe (Point2 u)+tipL PathEmpty = Nothing+tipL (Path _ sp _ _) = Just sp+++tipR :: Path u -> Maybe (Point2 u)+tipR PathEmpty = Nothing+tipR (Path _ _ _ ep) = Just ep+++-- | Shorten both ends...+--+shortenBoth :: (Real u, Floating u) => u -> Path u -> Path u+shortenBoth u p = shortenL u $ shortenR u p++--------------------------------------------------------------------------------+-- shorten from the left...++shortenL :: (Real u, Floating u) => u -> Path u -> Path u+shortenL _ PathEmpty = PathEmpty+shortenL n (Path u _ segs ep) + | n >= u = PathEmpty+ | otherwise = step n (viewl segs)+ where+ step _ EmptyL = PathEmpty+ step d (e :< se) = let z = segmentLength e in+ case compare d z of+ GT -> step (d-z) (viewl se)+ EQ -> makeLeftPath (u-n) se ep+ LT -> let e1 = shortenSegL d e+ in Path (u-n) (segmentStart e1) (e1 <| se) ep+++makeLeftPath :: u -> Seq (PathSeg u) -> Point2 u -> Path u+makeLeftPath u se ep = + case viewl se of+ EmptyL -> PathEmpty + (e :< _) -> Path u (segmentStart e) se ep+++shortenSegL :: (Real u, Floating u) => u -> PathSeg u -> PathSeg u+shortenSegL n (LineSeg u p0 p1) = + LineSeg (u-n) (shortenLineL n p0 p1) p1++shortenSegL n (CurveSeg u p0 p1 p2 p3) = + let (Curve p0' p1' p2' p3') = snd $ subdividet (n/u) (Curve p0 p1 p2 p3)+ in CurveSeg (u-n) p0' p1' p2' p3'+++shortenLineL :: (Real u, Floating u) + => u -> Point2 u -> Point2 u -> Point2 u+shortenLineL n p0 p1 = p0 .+^ v+ where+ v0 = p1 .-. p0+ v = avec (direction v0) n++++--------------------------------------------------------------------------------+-- shorten from the right ...+ +shortenR :: (Real u, Floating u) => u -> Path u -> Path u+shortenR _ PathEmpty = PathEmpty+shortenR n (Path u sp segs _) + | n >= u = PathEmpty+ | otherwise = step n (viewr segs)+ where+ step _ EmptyR = PathEmpty+ step d (se :> e) = let z = segmentLength e in+ case compare d z of+ GT -> step (d-z) (viewr se)+ EQ -> makeRightPath n sp se+ LT -> let e1 = shortenSegR d e+ in Path (u-n) sp (se |> e1) (segmentEnd e1)+ ++makeRightPath :: u -> Point2 u -> Seq (PathSeg u) -> Path u+makeRightPath u sp se = + case viewr se of+ EmptyR -> PathEmpty + (_ :> e) -> Path u sp se (segmentEnd e)++++shortenSegR :: (Real u, Floating u) => u -> PathSeg u -> PathSeg u+shortenSegR n (LineSeg u p0 p1) = + LineSeg (u-n) p0 (shortenLineR n p0 p1) ++shortenSegR n (CurveSeg u p0 p1 p2 p3) = + let (Curve p0' p1' p2' p3') = fst $ subdividet ((u-n)/u) (Curve p0 p1 p2 p3)+ in CurveSeg (u-n) p0' p1' p2' p3'+++shortenLineR :: (Real u, Floating u) + => u -> Point2 u -> Point2 u -> Point2 u+shortenLineR n p0 p1 = p1 .+^ v+ where+ v0 = p0 .-. p1+ v = avec (direction v0) n+++++--------------------------------------------------------------------------------+-- line direction++-- | Direction of empty path is considered to be 0.+--+directionL :: (Real u, Floating u) => Path u -> Radian+directionL PathEmpty = 0+directionL (Path _ _ se _) = step $ viewl se+ where+ step (LineSeg _ p0 p1 :< _) = lineDirection p1 p0 -- 1-to-0+ step (CurveSeg _ p0 p1 _ _ :< _) = lineDirection p1 p0+ step _ = 0+++-- | Direction of empty path is considered to be 0.+--+directionR :: (Real u, Floating u) => Path u -> Radian+directionR PathEmpty = 0+directionR (Path _ _ se _) = step $ viewr se+ where+ step (_ :> LineSeg _ p0 p1) = lineDirection p0 p1+ step (_ :> CurveSeg _ _ _ p2 p3) = lineDirection p2 p3+ step _ = 0++{-+-- Note - previously Paths were using this version of +-- lineDirection+-- +-- Needs testing as to whether the new one does what is expected. +--+lineDirection :: (Real u, Floating u) => Point2 u -> Point2 u -> Radian+lineDirection p0 p1 = direction (pvec p0 p1)+-}++++--------------------------------------------------------------------------------+++-- Return direction as well because the calculation is expensive...+--+midpoint :: (Real u, Floating u) => Path u -> Maybe (Point2 u, Radian)+midpoint pa = let u = length pa in+ if u == 0 then Nothing + else let pa1 = shortenR (u/2) pa + in fmap (\a -> (a,directionR pa1)) $ tipR pa1+++--------------------------------------------------------------------------------++data PathViewL u = EmptyPathL+ | PathSegment u :<< Path u+ deriving (Eq,Ord,Show) ++type DPathViewL = PathViewL Double++data PathViewR u = EmptyPathR+ | Path u :>> PathSegment u+ deriving (Eq,Ord,Show) ++type DPathViewR = PathViewR Double+++data PathSegment u = Line1 (Point2 u) (Point2 u)+ | Curve1 (Point2 u) (Point2 u) (Point2 u) (Point2 u)+ deriving (Eq,Ord,Show) ++type DPathSegment = PathSegment Double++type instance DUnit (PathViewL u) = u+type instance DUnit (PathViewR u) = u+type instance DUnit (PathSegment u) = u++pathViewL :: Num u => Path u -> PathViewL u+pathViewL PathEmpty = EmptyPathL+pathViewL (Path u _ segs ep) = case viewl segs of+ EmptyL -> EmptyPathL + (LineSeg v p0 p1 :< se) -> Line1 p0 p1 :<< Path (u-v) p1 se ep+ (CurveSeg v p0 p1 p2 p3 :< se) -> Curve1 p0 p1 p2 p3 :<< Path (u-v) p3 se ep+++pathViewR :: Num u => Path u -> PathViewR u+pathViewR PathEmpty = EmptyPathR+pathViewR (Path u _ segs ep) = case viewr segs of+ EmptyR -> EmptyPathR+ (se :> LineSeg v p0 p1) -> Path (u-v) p1 se ep :>> Line1 p0 p1+ (se :> CurveSeg v p0 p1 p2 p3) -> Path (u-v) p3 se ep :>> Curve1 p0 p1 p2 p3
src/Wumpus/Basic/Paths/Connectors.hs view
@@ -10,8 +10,7 @@ -- Stability : highly unstable -- Portability : GHC ----- Extended path type - more amenable for complex drawings than--- the type in Wumpus-Core.+-- Library of connector paths... -- -- \*\* WARNING \*\* this module is an experiment, and may -- change significantly or even be dropped from future revisions.@@ -21,191 +20,67 @@ module Wumpus.Basic.Paths.Connectors ( - ConnPath- , connectS+ Connector+ , connect , vhconn , hvconn- , arbv- , arbh+ , vhvconn+ , hvhconn , curveconn , joint- , pathGraphic- , fillPath - , shorten- , shortenL- , shortenR- , midpoint- , directionL- , directionR + ) where -import Wumpus.Basic.Graphic import Wumpus.Basic.Paths.Base-import Wumpus.Basic.Paths.Construction import Wumpus.Core -- package: wumpus-core import Data.AffineSpace -- package: vector-space -import Data.Sequence+import Prelude hiding ( length ) -type ConnPath u = Point2 u -> Point2 u -> Path u+type Connector u = Point2 u -> Point2 u -> Path u -connectS :: Floating u => ConnPath u-connectS = \p1 p2 -> execPath p1 $ lineto p2+connect :: Floating u => Connector u+connect = line -vhconn :: Floating u => ConnPath u-vhconn p1 p2 = execPath p1 $ verticalHorizontal p2+vhconn :: Floating u => Connector u+vhconn p1@(P2 x1 _) p2@(P2 _ y2) = + let mid = P2 x1 y2 in tracePoints [p1, mid, p2] -hvconn :: Floating u => ConnPath u-hvconn p1 p2 = execPath p1 $ horizontalVertical p2+hvconn :: Floating u => Connector u+hvconn p1@(P2 _ y1) p2@(P2 x2 _) = + let mid = P2 x2 y1 in tracePoints [p1, mid, p2] -arbv :: Floating u => u -> ConnPath u-arbv v p1@(P2 x1 y1) (P2 x2 y2) = execPath p1 $ vline v >> hline dx >> vline dy+vhvconn :: Floating u => u -> Connector u+vhvconn v p1@(P2 x1 _) p2@(P2 x2 _) = tracePoints [p1, a1, a2, p2] where- dx = x2 - x1- dy = y2 - (y1+v)+ a1 = p1 .+^ vvec v+ a2 = a1 .+^ hvec (x2 - x1) -arbh :: Floating u => u -> ConnPath u-arbh h p1@(P2 x1 y1) (P2 x2 y2) = execPath p1 $ hline h >> vline dy >> hline dx+hvhconn :: Floating u => u -> Connector u+hvhconn h p1@(P2 _ y1) p2@(P2 _ y2) = tracePoints [p1,a1,a2,p2] where- dx = x2 - (x1+h)- dy = y2 - y1+ a1 = p1 .+^ hvec h+ a2 = a1 .+^ vvec (y2 - y1) -curveconn :: (Floating u, Ord u) => Radian -> Radian -> ConnPath u-curveconn r1 r2 p1 p2 = execPath p1 $ curveto r1 r2 p2+curveconn :: (Floating u, Ord u) => Radian -> Radian -> Connector u+curveconn r1 r2 p1 p2 = curveByAngles p1 r1 r2 p2 -joint :: (Real u, Floating u) => u -> ConnPath u +joint :: (Real u, Floating u) => u -> Connector u joint u p1@(P2 x1 y1) p2@(P2 x2 y2) = - execPath p1 $ lineto (mid_pt .+^ avec perp_ang u) >> lineto p2+ tracePoints [p1, mid_pt .+^ avec perp_ang u, p2] where mid_pt = P2 (x1 + 0.5*(x2-x1)) (y1 + 0.5*(y2-y1)) perp_ang = (pi*0.5) + direction (pvec p2 p1) --- This one might be more useful...--- --- ... No - can\'t a add tips to this one.----pathGraphic :: Num u => ConnPath u -> ConnGraphic u-pathGraphic bpath = \p1 p2 -> openStroke $ toPrimPathU $ bpath p1 p2 --- Mind out for name clash... --- | Closes and fills a path----fillPath :: Num u => Path u -> Graphic u-fillPath = filledPath . toPrimPathU----shorten :: (Real u, Floating u, Ord u) => u -> Path u -> Path u-shorten u p = shortenL u $ shortenR u p- ----------------------------------------------------------------------------------- shorten from the left... -shortenL :: (Real u, Floating u, Ord u) => u -> Path u -> Path u-shortenL n (Path u bp) | n >= u = emptyPath- | otherwise = step n (viewl bp)- where- step _ EmptyL = emptyPath- step d (e :< se) = let z = segmentLength e in- case compare d z of- GT -> step (d-z) (viewl se)- EQ -> Path (u-n) se- _ -> Path (u-n) (shortenSegL d e <| se) --shortenSegL :: (Real u, Floating u) => u -> PathSeg u -> PathSeg u-shortenSegL n (LineSeg u l) = LineSeg (u-n) (shortenLineL n l) -shortenSegL n (CurveSeg u c) = CurveSeg (u-n) (snd $ subdividet (n/u) c)--shortenLineL :: (Real u, Floating u) => u -> Line u -> Line u-shortenLineL n (Line p1 p2) = Line (p1 .+^ v) p2- where- v0 = p2 .-. p1- v = avec (direction v0) n- ------------------------------------------------------------------------------------ shorten from the right ...- -shortenR :: (Real u, Floating u, Ord u) => u -> Path u -> Path u-shortenR n (Path u bp) | n >= u = emptyPath- | otherwise = step n (viewr bp)- where- step _ EmptyR = emptyPath- step d (se :> e) = let z = segmentLength e in- case compare d z of- GT -> step (d-z) (viewr se)- EQ -> Path (u-n) se- _ -> Path (u-n) (se |> shortenSegR d e)----shortenSegR :: (Real u, Floating u) => u -> PathSeg u -> PathSeg u-shortenSegR n (LineSeg u l) = LineSeg (u-n) (shortenLineR n l) -shortenSegR n (CurveSeg u c) = CurveSeg (u-n) (fst $ subdividet ((u-n)/u) c)---shortenLineR :: (Real u, Floating u) => u -> Line u -> Line u-shortenLineR n (Line p1 p2) = Line p1 (p2 .+^ v)- where- v0 = p1 .-. p2- v = avec (direction v0) n---------------------------------------------------------------------------------------- This should return direction as well...----midpoint :: (Real u, Floating u) => Path u -> Point2 u-midpoint (Path u bp) = step (u/2) (viewl bp)- where- step _ EmptyL = zeroPt- step d (e :< se) = let z = segmentLength e in- case compare d z of- GT -> step (d-z) (viewl se)- EQ -> segmentEnd e- _ -> segmentEnd $ shortenSegR d e ----------------------------------------------------------------------------------------- tangents---directionL :: (Real u, Floating u) => Path u -> Radian-directionL (Path _ se) = step $ viewl se- where- step (LineSeg _ l :< _) = lineDirectionL l - step (CurveSeg _ c :< _) = curveDirectionL c- step _ = 0--directionR :: (Real u, Floating u) => Path u -> Radian-directionR (Path _ se) = step $ viewr se- where- step (_ :> LineSeg _ l) = lineDirectionR l - step (_ :> CurveSeg _ c) = curveDirectionR c- step _ = 0---lineDirectionL :: (Real u, Floating u) => Line u -> Radian-lineDirectionL (Line p0 p1) = direction (pvec p1 p0)--lineDirectionR :: (Real u, Floating u) => Line u -> Radian-lineDirectionR (Line p0 p1) = direction (pvec p0 p1)--curveDirectionL :: (Real u, Floating u) => Curve u -> Radian-curveDirectionL (Curve p0 p1 _ _) = direction $ pvec p1 p0--curveDirectionR :: (Real u, Floating u) => Curve u -> Radian-curveDirectionR (Curve _ _ p2 p3) = direction $ pvec p2 p3-
src/Wumpus/Basic/Paths/Construction.hs view
@@ -12,7 +12,7 @@ -- Stability : highly unstable -- Portability : GHC ----- Build paths.+-- Build paths monadically. -- -- \*\* WARNING \*\* this module is an experiment, and may -- change significantly or even be dropped from future revisions.@@ -25,12 +25,17 @@ PathM , runPath , execPath++ , tip+ , lineto , rlineto- , vline , hline+ , vline+ , bezierto , curveto+ , verticalHorizontal , horizontalVertical @@ -43,15 +48,29 @@ import Data.AffineSpace -- package: vector-space import Control.Applicative+import Data.Maybe+import Data.Monoid -data PathState u = PathState ++-- Are connectors and paths quite different things?+--+-- It looks like they are - connectors always know start and end +-- points.+--+++-- State monad version is quite good - it ameliorates the problem+-- of joing to the end point of an empty path...++data St u = St { current_point :: Point2 u - , path_accum :: Path u+ , path_acc :: Path u } -newtype PathM u a = PathM { getPathM :: PathState u -> (a,PathState u) } +newtype PathM u a = PathM { getPathM :: St u -> (a,St u) } + instance Functor (PathM u) where fmap f mf = PathM $ \s -> let (a,s1) = getPathM mf s in (f a,s1) @@ -68,77 +87,64 @@ (getPathM . k) a s1 --- Design note - it is probably best to follow LRText and have--- the path monad isolated from the trace monad. While it would --- be nice to trace arbitrary labels as we go, state changes to the --- DrawingCtx would make things complicated.--- -{--openStrokePathM :: (Num u, TraceM m, DrawingCtxM m, u ~ MonUnit m) - => Point2 u -> PathM u a -> m a-openStrokePathM pt ma = let (a,p) = runPath pt ma in - draw (openStroke $ toPrimPathU p) >> return a--}---- Running the path is agnostic to the DrawingCtx.--runPath :: Num u => Point2 u -> PathM u a -> (a, Path u)-runPath start mf = let (a,s') = getPathM mf s in (a, path_accum s')+-- Running the path is (probably) agnostic to the DrawingCtx.+--+runPath :: Floating u => Point2 u -> PathM u a -> (a, Path u)+runPath start mf = let (a,s') = getPathM mf s in (a, path_acc s') where- s = PathState { current_point = start- , path_accum = emptyPath- }+ s = St { current_point = start+ , path_acc = mempty+ } -execPath :: Num u => Point2 u -> PathM u a -> Path u+execPath :: Floating u => Point2 u -> PathM u a -> Path u execPath start mf = snd $ runPath start mf +snocline :: Floating u => Vec2 u -> PathM u ()+snocline v = PathM $ \(St pt ac) -> let ep = pt .+^ v + in ((), St ep (ac `mappend` line pt ep)) -exchTip :: Point2 u -> (Point2 u -> Path u -> Path u) -> PathM u ()-exchTip new updP = - PathM $ \(PathState old bp) -> ((), PathState new (updP old bp)) tip :: PathM u (Point2 u) tip = PathM $ \s -> (current_point s,s) lineto :: Floating u => Point2 u -> PathM u ()-lineto end = exchTip end upd- where- upd start bp = bp `addSegment` pline start end-+lineto pt = PathM $ \(St p0 ac) -> ((), St pt (ac `mappend` line p0 pt)) rlineto :: Floating u => Vec2 u -> PathM u () rlineto (V2 dx dy) = tip >>= \(P2 x y) -> lineto (P2 (x+dx) (y+dy)) + hline :: Floating u => u -> PathM u ()-hline dx = tip >>= \(P2 x y) -> lineto (P2 (x+dx) y)+hline len = snocline (hvec len) vline :: Floating u => u -> PathM u ()-vline dy = tip >>= \(P2 x y) -> lineto (P2 x (y+dy))- +vline len = snocline (vvec len) ++ bezierto :: (Floating u, Ord u) => Point2 u -> Point2 u -> Point2 u -> PathM u ()-bezierto cp1 cp2 end = exchTip end upd - where- upd start bp = bp `addSegment` pcurve start cp1 cp2 end+bezierto c1 c2 ep = PathM $ \(St p0 ac) -> + ((), St ep (ac `mappend` curve p0 c1 c2 ep)) ++++--++ curveto :: (Floating u, Ord u) => Radian -> Radian -> Point2 u -> PathM u ()-curveto cin cout end = exchTip end upd- where - upd start bp = bp `addSegment` pcurveAng start cin cout end+curveto cin cout end = PathM $ \(St p0 ac) -> + let seg = curveByAngles p0 cin cout end + ac1 = ac `mappend` seg+ end1 = fromMaybe end $ tipR ac1+ in ((), St end1 ac1) -pcurveAng :: (Floating u, Ord u) - => Point2 u -> Radian -> Radian -> Point2 u -> PathSeg u-pcurveAng start cin cout end = pcurve start (start .+^ v1) (end .+^ v2) end- where- sz = 0.375 * (vlength $ pvec start end)- v1 = avec cin sz- v2 = avec cout sz verticalHorizontal :: Floating u => Point2 u -> PathM u ()@@ -148,3 +154,4 @@ horizontalVertical :: Floating u => Point2 u -> PathM u () horizontalVertical (P2 x y) = tip >>= \(P2 _ y0) -> lineto (P2 x y0) >> lineto (P2 x y)+
+ src/Wumpus/Basic/Paths/RoundCorners.hs view
@@ -0,0 +1,114 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module : Wumpus.Basic.Paths.RoundCorners+-- Copyright : (c) Stephen Tetley 2010+-- License : BSD3+--+-- Maintainer : Stephen Tetley <stephen.tetley@gmail.com>+-- Stability : highly unstable+-- Portability : GHC+--+-- Drawing round cornered polygons.+-- +--------------------------------------------------------------------------------++module Wumpus.Basic.Paths.RoundCorners+ ( + cornerCurve+ , illustratePath+ , roundEvery++ ) where++import Wumpus.Basic.Colour.SVGColours+import Wumpus.Basic.Graphic+import Wumpus.Basic.Paths.Base hiding ( length )+import Wumpus.Basic.Utils.Intersection+++import Wumpus.Core -- package: wumpus-core++import Data.AffineSpace -- package: vector-space++import Data.Monoid+++-- | The length of the control-point vector wants to be slighly +-- longer than half of /d/ (d - being the distance between the +-- /truncated/ points and the corner).+--+cornerCurve :: (Real u, Floating u) + => Point2 u -> Point2 u -> Point2 u -> Path u+cornerCurve p1 p2 p3 = curve p1 cp1 cp2 p3+ where+ len1 = 0.6 * (vlength $ pvec p1 p2)+ len2 = 0.6 * (vlength $ pvec p3 p2)+ cp1 = p1 .+^ (avec (langle p1 p2) len1)+ cp2 = p3 .+^ (avec (langle p3 p2) len2)+++roundEvery :: (Real u, Floating u) + => u -> [Point2 u] -> Path u +roundEvery u (start:b:c:xs) = step (twoParts u start b c) (b:c:xs)+ where+ step acc (m:n:o:ps) = step (acc `mappend` twoParts u m n o) (n:o:ps)+ step acc [n,o] = acc `mappend` twoParts u n o start+ `mappend` twoParts u o start b + step acc _ = acc+roundEvery _ _ = mempty+++-- | Two parts - line and corner curve...+--+twoParts :: (Real u, Floating u) + => u -> Point2 u -> Point2 u -> Point2 u -> Path u+twoParts u a b c = line p1 p2 `mappend` cornerCurve p2 b p3+ where+ p1 = a .+^ (avec (direction $ pvec a b) u)+ p2 = b .+^ (avec (direction $ pvec b a) u)+ p3 = b .+^ (avec (direction $ pvec b c) u)+ +++--------------------------------------------------------------------------------+-- ++-- This needs moving outside of the Path modules as it has +-- dependencies on SVGColour and Graphic (the Path modules should+-- be /neutral/ to wards depenedencies on other parts of +-- Wumpus-Basic).+--++illustratePath :: Fractional u => Path u -> Graphic u+illustratePath = localize (strokeColour black) . step1 . pathViewL+ where+ step1 EmptyPathL = mempty+ step1 (e :<< se) = drawPathBoth e `mappend` rest (pathViewL se)++ rest EmptyPathL = mempty+ rest (e :<< se) = drawPath1 e `mappend` rest (pathViewL se)++drawPathBoth :: Fractional u => PathSegment u -> Graphic u+drawPathBoth pa@(Line1 p1 _) = drawPath1 pa `mappend` pathPoint p1+drawPathBoth pa@(Curve1 p1 _ _ _) = drawPath1 pa `mappend` pathPoint p1++drawPath1 :: Fractional u => PathSegment u -> Graphic u+drawPath1 (Line1 p1 p2) = + straightLineBetween p1 p2 `mappend` pathPoint p2++drawPath1 (Curve1 p1 p2 p3 p4) = + mconcat [ bezierCtrl p1 p2, bezierCtrl p4 p3, curveBetween p1 p2 p3 p4+ , pathPoint p4]+++bezierCtrl :: Fractional u => Point2 u -> Point2 u -> Graphic u+bezierCtrl p1 p2 = + localize (strokeColour light_steel_blue . fillColour red) $+ straightLineBetween p1 p2 `mappend` filledDisk 1 p2+++pathPoint :: Num u => Point2 u -> Graphic u+pathPoint = localize bothStrokeColour . filledDisk 1+
src/Wumpus/Basic/Shapes/Base.hs view
@@ -50,6 +50,21 @@ import Data.Monoid +-- | Note - this formulation prevents rounded corner shapes...+--+-- Currently shapes that aren\'t paths:+--+-- > Coordinate+-- > FreeLabel+--+-- Alternative +--+-- > out_fun :: ShapeCTM u -> (Path u,sh)+--+-- All shapes expect FreeLabel are oblivious to the +-- DrawingContext for the /shape/+--+ data Shape u sh = Shape { src_ctm :: ShapeCTM u , out_fun :: ShapeCTM u -> Image u sh
src/Wumpus/Basic/Shapes/Derived.hs view
@@ -119,7 +119,7 @@ outputRect :: (Real u, Floating u) => u -> u -> ShapeLabel u -> ShapeCTM u -> Image u (Rectangle u)-outputRect hw hh shl ctm = intoImage (pureDF a) (drawRect a `mappend` label) +outputRect hw hh shl ctm = intoImage (return a) (drawRect a `mappend` label) where a = Rectangle { rect_ctm = ctm, rect_hw = hw, rect_hh = hh } label = runShapeLabel ctm shl@@ -193,7 +193,7 @@ outputCirc :: (Real u, Floating u) => u -> ShapeLabel u -> ShapeCTM u -> Image u (Circle u)-outputCirc rad shl ctm = intoImage (pureDF a) (drawCirc a `mappend` label) +outputCirc rad shl ctm = intoImage (return a) (drawCirc a `mappend` label) where a = Circle { circ_ctm = ctm, circ_radius = rad } label = runShapeLabel ctm shl@@ -234,13 +234,13 @@ } outputCoord :: (Real u, Floating u) => ShapeCTM u -> Image u (Coordinate u)-outputCoord ctm = intoImage (pureDF a) (drawCoord a) +outputCoord ctm = intoImage (return a) (drawCoord a) where a = Coordinate { coord_ctm = ctm } drawCoord :: (Real u, Floating u) => Coordinate u -> Graphic u-drawCoord coord = localDF swapColours $ filledEllipse 2 2 (center coord)+drawCoord coord = localize swapColours $ filledEllipse 2 2 (center coord) -------------------------------------------------------------------------------- -- Diamond@@ -288,7 +288,7 @@ outputDia :: (Real u, Floating u) => u -> u -> ShapeLabel u -> ShapeCTM u -> Image u (Diamond u)-outputDia hw hh shl ctm = intoImage (pureDF a) (drawDia a `mappend` label) +outputDia hw hh shl ctm = intoImage (return a) (drawDia a `mappend` label) where a = Diamond { dia_ctm = ctm, dia_hw = hw, dia_hh = hh } label = runShapeLabel ctm shl@@ -335,7 +335,7 @@ outputEll :: (Real u, Floating u) => u -> u -> ShapeLabel u -> ShapeCTM u -> Image u (Ellipse u)-outputEll rx ry shl ctm = intoImage (pureDF a) (drawEll a `mappend` label)+outputEll rx ry shl ctm = intoImage (return a) (drawEll a `mappend` label) where a = Ellipse { ell_ctm = ctm, ell_rx = rx, ell_ry = ry } label = runShapeLabel ctm shl
src/Wumpus/Basic/Text/LRText.hs view
@@ -117,10 +117,10 @@ runLRText :: (Num u, FromPtSize u) => LRText u a -> LocImage u a runLRText ma = \pt -> envZero >>= \e1 -> - let (a,st) = getLRText ma e1 st_zero - in mkline pt (acc_chr st) >>= \g1 ->- localDF (fontface symbol) (mkline pt (acc_sym st)) >>= \g2 ->- return (a,g1 `mappend` g2)+ let (a,st) = getLRText ma e1 st_zero + in mkline pt (acc_chr st) >>= \g1 ->+ localize (fontface symbol) (mkline pt (acc_sym st)) >>= \g2 ->+ return (a,g1 `mappend` g2) where mkline pt h = case toListH h of [] -> return mempty@@ -137,7 +137,7 @@ , acc_sym = emptyH } -envZero :: FromPtSize u => DrawingF (Env u)+envZero :: FromPtSize u => DrawingR (Env u) envZero = (\sz -> Env { char_width = fromPtSize $ charWidth sz , spacer_width = fromPtSize $ spacerWidth sz }) <$> fontSize
src/Wumpus/Basic/Utils/Intersection.hs view
@@ -8,7 +8,7 @@ -- -- Maintainer : Stephen Tetley <stephen.tetley@gmail.com> -- Stability : highly unstable--- Portability : GHC with TypeFamilies and more+-- Portability : GHC -- -- Intersection of line to line and line to plane --
src/Wumpus/Basic/VersionNumber.hs view
@@ -23,7 +23,7 @@ -- | Version number ----- > (0,9,0)+-- > (0,10,0) -- wumpus_basic_version :: (Int,Int,Int)-wumpus_basic_version = (0,9,0)+wumpus_basic_version = (0,10,0)
wumpus-basic.cabal view
@@ -1,5 +1,5 @@ name: wumpus-basic-version: 0.9.0+version: 0.10.0 license: BSD3 license-file: LICENSE copyright: Stephen Tetley <stephen.tetley@gmail.com>@@ -14,66 +14,57 @@ library turns out to be much more demanding than designing a low-level one (Wumpus-Core). .- A few of the modules (SafeFonts, SVGColours, X11Colours) are- fairly stable others simply aren\'t and may even disappear in- subsequent updates.+ Some of the modules (SafeFonts, SVGColours, X11Colours) are+ relatively stable. The core modules of @Basic.Graphic@ (@Base@,+ @PrimGraphic@, @DrawingContext@) are quite weather-beaten if + not exactly stable, although the newer modules + (@ScalingContext@, @DirectionContext@) are still quite green.+ Other modules (Paths, Chains, Shapes) are essentially sketches + and may be radically different in subsequent updates. . . Changelog: .- 0.8.0 to 0.9.0:- .- * Re-worked @Basic.Text.LRSymbol@ changed the type name and the- types of the run functions. Added more symbols and a new demo - @Symbols.hs@.+ 0.9.0 to 0.10.0: .- * @ScalingContext@ added to @Basic.Graphic@. Changed - @monoTextWidth@ to take a character count, the old behaviour - is recreated by the new function @monoTextLength@. + * @Basic.Graphic.BaseClasses@ and @Basic.Graphic.BaseTypes@ + merged into same module so they can depend on each other + without orphans instances. .- * @Basic.Graphic.Chain@ removed. It is now superseded by- @Basic.Chains@.+ * @DrawingF@ renamed to @DrawingR@, the related type synonyms+ have also been changed, e.g. @LocDrawingF@ is now + @LocDrawingR@. .- * Added new property to @DrawingContext@ for line spacing - scaling factor, and added a new drawing primitive - @textlineMulti@ for multi-line, left justified labels.+ * Method names in the @DrawingCtxM@ class changed - @askCtx@ is+ now @askDC@, @localCtx@ is now @localize@. Removed the + functions @askDF@, @asksDF@, @pureDF@ that worked for + @DrawingF@ (now @DrawingR@), @DrawingR@ now uses the + Applicative\'s @pure@ and the @DrawingCtxM@ class for these + functionalities. .- * Synthezied attribute /getters/ such as @textDimensions@ moved- from @Basic.Graphic.DrawingContext@ to the new module- @Basic.Graphic.Query@. The type of all the functions has - changed to DrawingF. @lowerxHeight@ is renamed - @monoLowerxHeight@ emphasizing that the metrics pertain to- monospaced Courier font.+ * @Basic.Graphic.DrawingContext@ - renamed @primary_colour@ to+ @stroke_colour@ and @secondary_colour@ to @fill_colour@. The + setter functions has been similarly renamed. .- * Added Shapes modules.- . - * TurtleMonad module - the TurtleDrawing type and run functions- have been removed and the internals have been reworked. - Turtle is now run solely as a /local effect/ within the - Drawing monad. + * Added the type synonym @DrawingContextF@ to + @Basic.Graphic.DrawingContext@. Changed relevant function+ signatures to use it. .- 0.7.0 to 0.8.0:+ * Re-worked the Path modules - base types entirely different,+ connectors entirely different, monadic path construction + largely the same. .- * Re-introduced LRText and LRSymbol - they now work with - Wumpus-Core\'s kerning support.+ * Initial work on round cornered paths. . - * Changes to @Graphic.Basic.BaseTypes@ - @DrawingObject@ - renamed to @DrawingF@. @HPrim@ wrapped as a newtype to - support a Monoid instance. Removed @appendGraphic@ and @gcat@ - as they can be achieved with @mappend@ and @mconcat@. - @appendAt@ renamed to @lgappend@. @PointT@ remaned to - @PointF@.- .- * Changes to @Graphic.Basic.Drawing@ - @drawAt@, @drawAtImg@, - @drawConn@, @drawConnImg@ all removed. They are replaced - by @draw@ and @drawi@ together with then new @at@ and @conn@- combinators.- .- * Changes to @Basic.Graphic.PrimGraphic@ - @localDrawingContext@- renamed to @localLG@ and moved to @Basic.Graphic.BaseTypes@.+ * Removed the type class @TextAnchor@ from @Basic.Anchors@. + This was a left-over from a previous implementation of + Shapes and is not relevant to the current implementation.+ . + * Added @DirectionContext@ to @Basic.Graphic@. .- * Updates to @Basic.SafeFonts@ to work with changes to - @Wumpus.Core@.+ * @localLG@ removed it can be acheived with composition -+ @localize upd . loc_graphic_function@. @lgappend@ is also + removed - it can be recreated applicatively. . . build-type: Simple@@ -88,6 +79,7 @@ demo/ColourCharts.hs, demo/ColourDefns.hs, demo/FontPic.hs,+ demo/PetriNet.hs, demo/Picture.hs, demo/Shapes.hs, demo/Symbols.hs@@ -97,7 +89,7 @@ build-depends: base < 5, containers >= 0.3 && <= 0.4, vector-space >= 0.6,- wumpus-core == 0.34.0+ wumpus-core == 0.35.0 exposed-modules:@@ -112,8 +104,8 @@ Wumpus.Basic.Dots, Wumpus.Basic.Dots.Primitive, Wumpus.Basic.Graphic,- Wumpus.Basic.Graphic.BaseClasses,- Wumpus.Basic.Graphic.BaseTypes,+ Wumpus.Basic.Graphic.Base,+ Wumpus.Basic.Graphic.DirectionContext, Wumpus.Basic.Graphic.Drawing, Wumpus.Basic.Graphic.DrawingContext, Wumpus.Basic.Graphic.PrimGraphic,@@ -125,6 +117,7 @@ Wumpus.Basic.Paths.Base, Wumpus.Basic.Paths.Connectors, Wumpus.Basic.Paths.Construction,+ Wumpus.Basic.Paths.RoundCorners, Wumpus.Basic.SafeFonts, Wumpus.Basic.Shapes.Base, Wumpus.Basic.Shapes.Derived,