{-# LANGUAGE TypeFamilies
, TypeSynonymInstances
, FlexibleInstances
, GeneralizedNewtypeDeriving
, MultiParamTypeClasses
, ViewPatterns
, DeriveDataTypeable
#-}{-# OPTIONS_GHC -fno-warn-orphans #-}------------------------------------------------------------------------------- |-- Module : Diagrams.TwoD.Types-- Copyright : (c) 2011 diagrams-lib team (see LICENSE)-- License : BSD-style (see LICENSE)-- Maintainer : diagrams-discuss@googlegroups.com---- Basic types for two-dimensional Euclidean space.-------------------------------------------------------------------------------moduleDiagrams.TwoD.Types(-- * 2D Euclidean spaceR2,r2,unr2,P2,p2,unp2,T2-- * Angles,Angle(..),CircleFrac(..),Rad(..),Deg(..),fullCircle,convertAngle)whereimportGraphics.Rendering.DiagramsimportDiagrams.Util(tau)importControl.NewtypeimportData.BasisimportData.NumInstances()importData.VectorSpaceimportData.Typeable-------------------------------------------------------------- 2D Euclidean space-- | The two-dimensional Euclidean vector space R^2. This type is-- intentionally abstract.---- * To construct a vector, use 'r2'.---- * To construct the vector from the origin to a point @p@, use-- @p .-. origin@.---- * To convert a vector @v@ into the point obtained by following-- @v@ from the origin, use @'origin' '.+^' v@.---- * To convert a vector back into a pair of components, use 'unv2'.newtypeR2=R2{unR2::(Double,Double)}deriving(AdditiveGroup,Eq,Ord,Show,Read,Typeable,Num,Fractional)instanceNewtypeR2(Double,Double)wherepack=R2unpack=unR2-- | Construct a 2D vector from a pair of components.r2::(Double,Double)->R2r2=pack-- | Convert a 2D vector back into a pair of components.unr2::R2->(Double,Double)unr2=unpacktypeinstanceVR2=R2instanceVectorSpaceR2wheretypeScalarR2=Double(*^)=overR2.(*^)instanceHasBasisR2wheretypeBasisR2=Either()()-- = Basis (Double, Double)basisValue=R2.basisValuedecompose=decompose.unR2decompose'=decompose'.unR2instanceInnerSpaceR2where(unR2->vec1)<.>(unR2->vec2)=vec1<.>vec2-- | Points in R^2. This type is intentionally abstract.---- * To construct a point, use 'p2'.---- * To construct a point from a vector @v@, use @origin .+^ v@.---- * To convert a point @p@ into the vector from the origin to @p@,-- use @p '.-.' 'origin'@.---- * To convert a point back into a pair of coordinates, use 'unp2'.typeP2=PointR2-- | Construct a 2D point from a pair of coordinates.p2::(Double,Double)->P2p2=pack.pack-- | Convert a 2D point back into a pair of coordinates.unp2::P2->(Double,Double)unp2=unpack.unpack-- | Transformations in R^2.typeT2=TransformationR2instanceTransformableR2wheretransform=apply-------------------------------------------------------------- Angles-- | Newtype wrapper used to represent angles as fractions of a-- circle. For example, 1/3 = tau/3 radians = 120 degrees.newtypeCircleFrac=CircleFrac{getCircleFrac::Double}deriving(Read,Show,Eq,Ord,Enum,Floating,Fractional,Num,Real,RealFloat,RealFrac)-- | Newtype wrapper for representing angles in radians.newtypeRad=Rad{getRad::Double}deriving(Read,Show,Eq,Ord,Enum,Floating,Fractional,Num,Real,RealFloat,RealFrac)-- | Newtype wrapper for representing angles in degrees.newtypeDeg=Deg{getDeg::Double}deriving(Read,Show,Eq,Ord,Enum,Floating,Fractional,Num,Real,RealFloat,RealFrac)-- | Type class for types that measure angles.classNuma=>Angleawhere-- | Convert to a fraction of a circle.toCircleFrac::a->CircleFrac-- | Convert from a fraction of a circle.fromCircleFrac::CircleFrac->ainstanceAngleCircleFracwheretoCircleFrac=idfromCircleFrac=id-- | tau radians = 1 full circle.instanceAngleRadwheretoCircleFrac=CircleFrac.(/tau).getRadfromCircleFrac=Rad.(*tau).getCircleFrac-- | 360 degrees = 1 full circle.instanceAngleDegwheretoCircleFrac=CircleFrac.(/360).getDegfromCircleFrac=Deg.(*360).getCircleFrac-- | An angle representing a full circle.fullCircle::Anglea=>afullCircle=fromCircleFrac1-- | Convert between two angle representations.convertAngle::(Anglea,Angleb)=>a->bconvertAngle=fromCircleFrac.toCircleFrac