{-# OPTIONS -Wall #-} -------------------------------------------------------------------------------- -- | -- Module : Wumpus.Basic.Paths.Connectors -- Copyright : (c) Stephen Tetley 2010 -- License : BSD3 -- -- Maintainer : Stephen Tetley -- Stability : highly unstable -- Portability : GHC -- -- Library of connector paths... -- -- \*\* WARNING \*\* this module is experimental and may change -- significantly in future revisions. -- -------------------------------------------------------------------------------- module Wumpus.Basic.Paths.Connectors ( ConnectorPath , DConnectorPath , connLine , connRightVH , connRightHV , connRightVHV , connRightHVH , connIsosceles , connIsosceles2 , connLightningBolt , connIsoscelesCurve , connSquareCurve , connUSquareCurve , connTrapezoidCurve , connZSquareCurve , connUZSquareCurve ) where import Wumpus.Basic.Paths.Base import Wumpus.Basic.Paths.ControlPoints import Wumpus.Core -- package: wumpus-core import Data.AffineSpace -- package: vector-space import Prelude hiding ( length ) type ConnectorPath u = Point2 u -> Point2 u -> Path u type DConnectorPath = ConnectorPath Double -------------------------------------------------------------------------------- -- | Connect with a straight line. -- connLine :: Floating u => ConnectorPath u connLine = line -- | Right-angled connector - go vertical, then go horizontal. -- connRightVH :: Floating u => ConnectorPath u connRightVH p1@(P2 x1 _) p2@(P2 _ y2) = let mid = P2 x1 y2 in traceLinePoints [p1, mid, p2] -- | Right-angled connector - go horizontal, then go vertical. -- connRightHV :: Floating u => ConnectorPath u connRightHV p1@(P2 _ y1) p2@(P2 x2 _) = let mid = P2 x2 y1 in traceLinePoints [p1, mid, p2] -- | Right-angled connector - go vertical for the supplied -- distance, go horizontal, go vertical again for the -- remaining distance. -- connRightVHV :: Floating u => u -> ConnectorPath u connRightVHV v p1@(P2 x1 _) p2@(P2 x2 _) = traceLinePoints [p1, a1, a2, p2] where a1 = p1 .+^ vvec v a2 = a1 .+^ hvec (x2 - x1) -- | Right-angled connector - go horizontal for the supplied -- distance, go verical, go horizontal again for the -- remaining distance. -- connRightHVH :: Floating u => u -> ConnectorPath u connRightHVH h p1@(P2 _ y1) p2@(P2 _ y2) = traceLinePoints [p1,a1,a2,p2] where a1 = p1 .+^ hvec h a2 = a1 .+^ vvec (y2 - y1) -- | /Triangular/ joint. -- -- @u@ is the altitude of the triangle. -- connIsosceles :: (Real u, Floating u) => u -> ConnectorPath u connIsosceles dy p1 p2 = traceLinePoints [p1, mid_pt, p2] where mid_pt = midpointIsosceles dy p1 p2 -- | Double /triangular/ joint. -- -- @u@ is the altitude of the triangle. -- connIsosceles2 :: (Real u, Floating u) => u -> ConnectorPath u connIsosceles2 u p1 p2 = traceLinePoints [ p1, cp1, cp2, p2 ] where (cp1,cp2) = dblpointIsosceles u p1 p2 -- | /Lightning bolt/ joint - a two joint connector with an /axis/ -- perpendicular to the connector direction. -- -- @u@ is the half length of the of the axis. -- connLightningBolt :: (Real u, Floating u) => u -> ConnectorPath u connLightningBolt u p1 p2 = traceLinePoints [ p1, cp1, cp2, p2 ] where cp1 = midpointIsosceles u p1 p2 cp2 = midpointIsosceles (-u) p1 p2 -------------------------------------------------------------------------------- -- | Form a curve inside an isosceles triangle. -- -- The two Bezier control points take the same point - the -- altitude of the triangle. The curve tends to be quite shallow -- relative to the altitude. -- -- @u@ is the altitude of the triangle. -- connIsoscelesCurve :: (Real u, Floating u) => u -> ConnectorPath u connIsoscelesCurve u p1 p2 = traceCurvePoints [p1, control_pt, control_pt, p2] where control_pt = midpointIsosceles u p1 p2 -- | Form a curve inside a square. -- -- The two Bezier control points take the /top/ corners. The -- curve tends to be very deep. -- connSquareCurve :: (Real u, Floating u) => ConnectorPath u connSquareCurve p1 p2 = traceCurvePoints [p1, cp1, cp2, p2] where (cp1,cp2) = squareFromBasePoints p1 p2 -- | Form a curve inside a square. -- -- As per 'connSquareCurve' but the curve is drawn /underneath/ -- the line formed between the start and end points. -- -- (Underneath is modulo the direction, of course). -- connUSquareCurve :: (Real u, Floating u) => ConnectorPath u connUSquareCurve p1 p2 = traceCurvePoints [p1, cp1, cp2, p2] where (cp1,cp2) = usquareFromBasePoints p1 p2 -- | altitude * ratio_to_base -- -- Form a curve inside a trapeziod. -- connTrapezoidCurve :: (Real u, Floating u) => u -> u -> ConnectorPath u connTrapezoidCurve u ratio_to_base p1 p2 = traceCurvePoints [p1, cp1, cp2, p2] where (cp1,cp2) = trapezoidFromBasePoints u ratio_to_base p1 p2 -- | Make a curve within a square, following the corner points as -- a Z. -- connZSquareCurve :: (Real u, Floating u) => ConnectorPath u connZSquareCurve p1 p2 = traceCurvePoints [p1,cp1,cp2,p2] where (cp1,cp2) = squareFromCornerPoints p1 p2 -- | Make a curve within a square, following the corner points as -- a Z. -- -- The order of tracing flips the control points, so this is an -- /underneath/ version of 'connZSquareCurve'. -- connUZSquareCurve :: (Real u, Floating u) => ConnectorPath u connUZSquareCurve p1 p2 = traceCurvePoints [p1,cp2,cp1,p2] where (cp1,cp2) = squareFromCornerPoints p1 p2