Portability | GHC |
---|---|
Stability | highly unstable |
Maintainer | Stephen Tetley <stephen.tetley@gmail.com> |
Anchor points on shapes, bounding boxes, etc.
Anchors are addressable positions, an examplary use is taking anchors on node shapes to get the start and end points for connectors in a network (graph) diagram.
** WARNING ** - The API here needs some thought as to a good balance of the type classes - in a nutshell "are corners better than cardinals". Originally I tried to follow how I understand the TikZ anchors to work, but this is perhaps not ideal for dividing into type-classes.
- type Anchor u = Point2 u
- class CenterAnchor a where
- class ApexAnchor a where
- class CardinalAnchor a where
- class CardinalAnchor2 a where
- class RadialAnchor a where
- radialAnchor :: Radian -> u ~ DUnit a => a -> Anchor u
- class TopCornerAnchor a where
- topLeftCorner :: u ~ DUnit a => a -> Anchor u
- topRightCorner :: u ~ DUnit a => a -> Anchor u
- class BottomCornerAnchor a where
- bottomLeftCorner :: u ~ DUnit a => a -> Anchor u
- bottomRightCorner :: u ~ DUnit a => a -> Anchor u
- class SideMidpointAnchor a where
- sideMidpoint :: Int -> u ~ DUnit a => a -> Anchor u
- projectAnchor :: (Real u, Floating u, CenterAnchor a, u ~ DUnit a) => (a -> Anchor u) -> u -> a -> Anchor u
- radialConnectorPoints :: (Real u, Floating u, CenterAnchor a, RadialAnchor a, CenterAnchor b, RadialAnchor b, u ~ DUnit a, u ~ DUnit b) => a -> b -> (Point2 u, Point2 u)
Anchors
Anchor classes
class CardinalAnchor a whereSource
Cardinal (compass) positions on an object.
Cardinal anchors should be at their equivalent radial position. However, some shapes may not be able to easily define radial positions or may be able to provide more efficient definitions for the cardinal anchors. Hence the redundancy seems justified.
north :: u ~ DUnit a => a -> Anchor uSource
south :: u ~ DUnit a => a -> Anchor uSource
Fractional u => CardinalAnchor (BoundingBox u) |
class CardinalAnchor2 a whereSource
Secondary group of cardinal (compass) positions on an object for the diagonal positions.
It seems possible that for some objects defining the primary compass points (north, south,...) will be straight-forward whereas defining the secondary compass points may be problematic, hence the compass points are split into two classes.
northeast :: u ~ DUnit a => a -> Anchor uSource
southeast :: u ~ DUnit a => a -> Anchor uSource
Fractional u => CardinalAnchor2 (BoundingBox u) |
class RadialAnchor a whereSource
Anchor on a border that can be addressed by an angle.
The angle is counter-clockwise from the right-horizontal, i.e. 0 is east.
radialAnchor :: Radian -> u ~ DUnit a => a -> Anchor uSource
class TopCornerAnchor a whereSource
Anchors at the top left and right corners of a shape.
For some shapes (Rectangle) the TikZ convention appears to be have cardinals as the corner anchors, but this doesn't seem to be uniform. Wumpus will need to reconsider anchors at some point...
topLeftCorner :: u ~ DUnit a => a -> Anchor uSource
topRightCorner :: u ~ DUnit a => a -> Anchor uSource
class BottomCornerAnchor a whereSource
Anchors at the bottom left and right corners of a shape.
bottomLeftCorner :: u ~ DUnit a => a -> Anchor uSource
bottomRightCorner :: u ~ DUnit a => a -> Anchor uSource
class SideMidpointAnchor a whereSource
Anchors in the center of a side.
Sides are addressable by index. Following TikZ, side 1 is expected to be the top of the shape. If the shape has an apex instead of a side then side 1 is expected to be the first side left of the apex.
Implementations are also expected to modulo the side number, rather than throw an out-of-bounds error.
sideMidpoint :: Int -> u ~ DUnit a => a -> Anchor uSource
Extended anchor points
projectAnchor :: (Real u, Floating u, CenterAnchor a, u ~ DUnit a) => (a -> Anchor u) -> u -> a -> Anchor uSource
projectAnchor
: extract_func * dist * object -> Point
Derive a anchor by projecting a line from the center of an
object through the intermediate anchor (produced by the
extraction function). The final answer point is located along
the projected line at the supplied distance dist
.
E.g. take the north of a rectangle and project it 10 units further on:
projectAnchor north 10 my_rect
If the distance is zero the answer with be whatever point the the extraction function produces.
If the distance is negative the answer will be along the projection line, between the center and the intermediate anchor.
If the distance is positive the anchor will be extend outwards from the intermediate anchor.
radialConnectorPoints :: (Real u, Floating u, CenterAnchor a, RadialAnchor a, CenterAnchor b, RadialAnchor b, u ~ DUnit a, u ~ DUnit b) => a -> b -> (Point2 u, Point2 u)Source
radialConnectorPoints
: object_a * object_b -> (Point_a, Point_b)
Find the radial connectors points for objects a
and b
along
the line joining their centers.