Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New scaleInvPrim function #71

Merged
merged 9 commits into from
Apr 17, 2013
2 changes: 2 additions & 0 deletions src/Diagrams/Path.hs
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,8 @@ but that doesn't take into account the fact that some
of the v's are inside Points and hence ought to be translated.
-}

instance HasLinearMap v => IsPrim (Path v)

instance (InnerSpace v, OrderedField (Scalar v)) => Enveloped (Path v) where
getEnvelope = F.foldMap trailEnvelope . pathTrails
-- this type signature is necessary to work around an apparent bug in ghc 6.12.1
Expand Down
2 changes: 2 additions & 0 deletions src/Diagrams/ThreeD/Shapes.hs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ type instance V Ellipsoid = R3
instance Transformable Ellipsoid where
transform t1 (Ellipsoid t2) = Ellipsoid (t1 <> t2)

instance IsPrim Ellipsoid

instance Renderable Ellipsoid NullBackend where
render _ _ = mempty

Expand Down
2 changes: 2 additions & 0 deletions src/Diagrams/TwoD/Image.hs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ type instance V Image = R2
instance Transformable Image where
transform t1 (Image file sz t2) = Image file sz (t1 <> t2)

instance IsPrim Image

instance HasOrigin Image where
moveOriginTo p = translate (origin .-. p)

Expand Down
2 changes: 2 additions & 0 deletions src/Diagrams/TwoD/Text.hs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ type instance V Text = R2
instance Transformable Text where
transform t (Text tt a s) = Text (t <> tt) a s

instance IsPrim Text

instance HasOrigin Text where
moveOriginTo p = translate (origin .-. p)

Expand Down
70 changes: 50 additions & 20 deletions src/Diagrams/TwoD/Transform.hs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{-# LANGUAGE FlexibleContexts
, FlexibleInstances
, TypeFamilies
, ViewPatterns
#-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ViewPatterns #-}
-----------------------------------------------------------------------------
-- |
-- Module : Diagrams.TwoD.Transform
Expand Down Expand Up @@ -46,28 +46,28 @@ module Diagrams.TwoD.Transform
, shearingY, shearY

-- * Scale invariance
, ScaleInv(..), scaleInv
, ScaleInv(..), scaleInv, scaleInvPrim

-- * component-wise
, onBasis
) where

import Diagrams.Core
import Diagrams.Core
import qualified Diagrams.Core.Transform as T

import Control.Newtype (over)
import Control.Newtype (over)

import Diagrams.Coordinates
import Diagrams.Transform
import Diagrams.TwoD.Size (width, height)
import Diagrams.TwoD.Types
import Diagrams.TwoD.Vector (direction)
import Diagrams.Coordinates
import Diagrams.Transform
import Diagrams.TwoD.Size (height, width)
import Diagrams.TwoD.Types
import Diagrams.TwoD.Vector (direction)

import Data.Semigroup
import Data.Semigroup

import Data.AffineSpace
import Data.AffineSpace

import Control.Arrow (first, second)
import Control.Arrow (first, second)

-- Rotation ------------------------------------------------

Expand Down Expand Up @@ -251,9 +251,6 @@ shearY = transform . shearingY

-- Scale invariance ----------------------------------------

-- XXX what about freezing? Doesn't interact with ScaleInv the way it
-- ought.

-- | The @ScaleInv@ wrapper creates two-dimensional /scale-invariant/
-- objects. Intuitively, a scale-invariant object is affected by
-- transformations like translations and rotations, but not by scales.
Expand Down Expand Up @@ -287,7 +284,7 @@ shearY = transform . shearingY

data ScaleInv t =
ScaleInv
{ unScaleInv :: t
{ unScaleInv :: t
, scaleInvDir :: R2
, scaleInvLoc :: P2
}
Expand All @@ -312,6 +309,39 @@ instance (V t ~ R2, Transformable t) => Transformable (ScaleInv t) where
l' = transform tr l
trans = translate (l' .-. l)

-- This is how we handle freezing properly with ScaleInv wrappers.
-- Normal transformations are applied ignoring scaling; "frozen"
-- transformations (i.e. transformations applied after a freeze) are
-- applied directly to the underlying object, scales and all. We must
-- take care to transform the reference point and direction vector
-- appropriately.
instance (V t ~ R2, Transformable t) => IsPrim (ScaleInv t) where
transformWithFreeze t1 t2 s = ScaleInv t'' d'' origin''
where
-- first, apply t2 normally, i.e. ignoring scaling
s'@(ScaleInv t' _ _) = transform t2 s

-- now apply t1 to get the new direction and origin
(ScaleInv _ d'' origin'') = transform t1 s'

-- but apply t1 directly to the underlying thing, scales and all.
t'' = transform t1 t'

instance (Renderable t b, V t ~ R2) => Renderable (ScaleInv t) b where
render b = render b . unScaleInv

-- | Create a diagram from a single scale-invariant primitive, which
-- will have an /empty/ envelope, trace, and query. The reason is
-- that the envelope, trace, and query cannot be cached---applying a
-- transformation would cause the cached envelope, etc. to get "out
-- of sync" with the scale-invariant object. The intention, at any
-- rate, is that scale-invariant things will be used only as
-- "decorations" (/e.g./ arrowheads) which should not affect the
-- envelope, trace, and query.
scaleInvPrim :: (Transformable t, Renderable t b, V t ~ R2, Monoid m)
=> t -> R2 -> QDiagram b R2 m
scaleInvPrim t d = mkQD (Prim $ scaleInv t d) mempty mempty mempty mempty

-- | Get the matrix equivalent of the linear transform,
-- (as a pair of columns) and the translation vector. This
-- is mostly useful for implementing backends.
Expand Down