{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE FlexibleContexts #-} {-# OPTIONS -Wall #-} -------------------------------------------------------------------------------- -- | -- Module : Wumpus.Drawing.Shapes.InvSemiellipse -- Copyright : (c) Stephen Tetley 2011 -- License : BSD3 -- -- Maintainer : Stephen Tetley -- Stability : highly unstable -- Portability : GHC -- -- Inverse semiellipse. -- -------------------------------------------------------------------------------- module Wumpus.Drawing.Shapes.InvSemiellipse ( InvSemiellipse , DInvSemiellipse , invsemiellipse ) where import Wumpus.Drawing.Shapes.Base import Wumpus.Drawing.Shapes.Semiellipse import Wumpus.Basic.Kernel -- package: wumpus-basic import Wumpus.Core -- package: wumpus-core -------------------------------------------------------------------------------- -- Inverse semiellipse newtype InvSemiellipse u = InvSemiellipse { getInvSemiellipse :: Semiellipse u } type DInvSemiellipse = InvSemiellipse Double type instance DUnit (InvSemiellipse u) = u -------------------------------------------------------------------------------- -- Affine trans mapSemiellipse :: (Semiellipse u -> Semiellipse u) -> InvSemiellipse u -> InvSemiellipse u mapSemiellipse f = InvSemiellipse . f . getInvSemiellipse instance Num u => Scale (InvSemiellipse u) where scale sx sy = mapSemiellipse (scale sx sy) instance Rotate (InvSemiellipse u) where rotate ang = mapSemiellipse (rotate ang) instance (Real u, Floating u) => RotateAbout (InvSemiellipse u) where rotateAbout ang pt = mapSemiellipse (rotateAbout ang pt) instance Num u => Translate (InvSemiellipse u) where translate dx dy = mapSemiellipse (translate dx dy) -------------------------------------------------------------------------------- -- Anchors runRotateAnchor :: (Real u, Floating u) => (Semiellipse u -> Point2 u) -> InvSemiellipse u -> Point2 u runRotateAnchor f (InvSemiellipse a) = rotateAbout pi (center a) (f a) instance (Real u, Floating u) => CenterAnchor (InvSemiellipse u) where center = center . getInvSemiellipse instance (Real u, Floating u, FromPtSize u) => ApexAnchor (InvSemiellipse u) where apex = runRotateAnchor apex instance (Real u, Floating u) => TopCornerAnchor (InvSemiellipse u) where topLeftCorner = runRotateAnchor bottomRightCorner topRightCorner = runRotateAnchor bottomLeftCorner instance (Real u, Floating u, FromPtSize u) => CardinalAnchor (InvSemiellipse u) where north = runRotateAnchor south south = runRotateAnchor north east = runRotateAnchor west west = runRotateAnchor east instance (Real u, Floating u, FromPtSize u) => CardinalAnchor2 (InvSemiellipse u) where northeast = runRotateAnchor southwest southeast = runRotateAnchor northwest southwest = runRotateAnchor northeast northwest = runRotateAnchor southeast instance (Real u, Floating u, FromPtSize u) => RadialAnchor (InvSemiellipse u) where radialAnchor theta = runRotateAnchor (radialAnchor $ circularModulo $ pi+theta) -------------------------------------------------------------------------------- -- Construction -- | 'invsemiellipse' : @ rx * ry -> Shape @ -- invsemiellipse :: (Real u, Floating u, FromPtSize u) => u -> u -> Shape u (InvSemiellipse u) invsemiellipse rx ry = fmap InvSemiellipse $ updatePathAngle (+ pi) $ semiellipse rx ry