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 sized, sizedAs, and sizeSpec2D functions #52

Merged
merged 2 commits into from
Oct 22, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,25 @@

- New 'withTrace' function for setting the Trace of a diagram

- Three new size-related functions:

- New 'sized' function for scaling an object to a particular size.
One particularly nice use of this is to obviate the need to keep
fiddling with the line width to get diagrams to "look right";
just set the line width relative to some arbitrary scale
(e.g. assuming the final diagram will fit into a 1x1 box) and
then apply 'sized' to the final diagram to make it that given
arbitrary size. It can also be used for easily making something
(a diagram, path, trail, ...) the same size as something else,
with the help of the new 'sizeSpec2D' function.

- New 'sizedAs' function, for setting the size of some object to
be "the same as" some other object.

- New 'sizeSpec2D' function for conveniently calculating the size
of an object as a SizeSpec2D value (for use with the new 'sized'
funtion).

* New instances

- The Show instance for R2 now produces something like "2 & 6"
Expand All @@ -49,6 +68,9 @@
- Data.Colour is now re-exported from Diagrams.Prelude for
convenience.

- Diagrams.TwoD.Adjust.adjustSize is now deprecated; it has been
renamed and moved to Diagrams.TwoD.Size.requiredScaleT.

* Dependency/version changes

- Allow data-default 0.4 and 0.5
Expand Down
5 changes: 4 additions & 1 deletion src/Diagrams/TwoD.hs
Original file line number Diff line number Diff line change
Expand Up @@ -164,13 +164,16 @@ module Diagrams.TwoD

-- * Size
-- ** Computing size
, width, height, size2D
, width, height, size2D, sizeSpec2D
, extentX, extentY, center2D

-- ** Specifying size
, SizeSpec2D(..)
, mkSizeSpec

-- ** Adjusting size
, sized, sizedAs

-- * Visual aids for understanding the internal model
, showOrigin
, showOrigin'
Expand Down
38 changes: 9 additions & 29 deletions src/Diagrams/TwoD/Adjust.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ module Diagrams.TwoD.Adjust
setDefault2DAttributes
, adjustDiaSize2D
, adjustDia2D
, adjustSize
, requiredScale

, adjustSize -- for backwards compatibility
, requiredScale -- re-exported for backwards compatibility
) where

import Diagrams.Core
Expand All @@ -29,7 +28,9 @@ import Diagrams.Attributes (lw, lc)
import Diagrams.Util ((#))

import Diagrams.TwoD.Types (R2, p2)
import Diagrams.TwoD.Size (size2D, center2D, SizeSpec2D(..))
import Diagrams.TwoD.Size ( size2D, center2D, SizeSpec2D(..)
, requiredScaleT, requiredScale
)
import Diagrams.TwoD.Text (fontSize)

import Data.AffineSpace ((.-.))
Expand Down Expand Up @@ -99,29 +100,8 @@ adjustDia2D :: Monoid' m
adjustDia2D getSize setSize b opts d
= adjustDiaSize2D getSize setSize b opts (d # setDefault2DAttributes # freeze)

-- | @adjustSize spec sz@ returns a transformation (a uniform scale)
-- which can be applied to something of size @sz@ to make it the
-- requested size @spec@.
{-# DEPRECATED adjustSize "Use Diagrams.TwoD.Size.requiredScaleT instead." #-}
-- | Re-export 'requiredScaleT' with the name 'adjustSize' for
-- backwards compatibility.
adjustSize :: SizeSpec2D -> (Double, Double) -> Transformation R2
adjustSize spec size = scaling (requiredScale spec size)

-- | @requiredScale spec sz@ returns a scaling factor necessary to
-- make something of size @sz@ fit the requested size @spec@,
-- without changing the aspect ratio. Hence an explicit
-- specification of both dimensions may not be honored if the aspect
-- ratios do not match; in that case the scaling will be as large as
-- possible so that the object still fits within the requested size.
requiredScale :: SizeSpec2D -> (Double, Double) -> Double
requiredScale Absolute _ = 1
requiredScale (Width wSpec) (w,_)
| wSpec == 0 || w == 0 = 1
| otherwise = wSpec / w
requiredScale (Height hSpec) (_,h)
| hSpec == 0 || h == 0 = 1
| otherwise = hSpec / h
requiredScale (Dims wSpec hSpec) (w,h) = s
where xscale = wSpec / w
yscale = hSpec / h
s' = min xscale yscale
s | isInfinite s' = 1
| otherwise = s'
adjustSize = requiredScaleT
54 changes: 52 additions & 2 deletions src/Diagrams/TwoD/Size.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,17 @@ module Diagrams.TwoD.Size
(
-- * Size and extent of diagrams in R2
-- ** Computing sizes
width, height, size2D
width, height, size2D, sizeSpec2D
, extentX, extentY, center2D

-- ** Specifying sizes
, SizeSpec2D(..)
, mkSizeSpec

, requiredScaleT, requiredScale

-- ** Changing the size of things
, sized, sizedAs
) where

import Diagrams.Core
Expand All @@ -46,6 +51,10 @@ height = maybe 0 (negate . uncurry (-)) . extentY
size2D :: (Enveloped a, V a ~ R2) => a -> (Double, Double)
size2D = width &&& height

-- | Compute the size of an enveloped object as a 'SizeSpec2D' value.
sizeSpec2D :: (Enveloped a, V a ~ R2) => a -> SizeSpec2D
sizeSpec2D = uncurry Dims . size2D

-- | Compute the absolute x-coordinate range of an enveloped object in
-- R2, in the form (lo,hi). Return @Nothing@ for objects with an
-- empty envelope.
Expand Down Expand Up @@ -90,4 +99,45 @@ mkSizeSpec :: Maybe Double -> Maybe Double -> SizeSpec2D
mkSizeSpec Nothing Nothing = Absolute
mkSizeSpec (Just w) Nothing = Width w
mkSizeSpec Nothing (Just h) = Height h
mkSizeSpec (Just w) (Just h) = Dims w h
mkSizeSpec (Just w) (Just h) = Dims w h

-- | @requiredScaleT spec sz@ returns a transformation (a uniform scale)
-- which can be applied to something of size @sz@ to make it fit the
-- requested size @spec@, without changing the aspect ratio.
requiredScaleT :: SizeSpec2D -> (Double, Double) -> Transformation R2
requiredScaleT spec size = scaling (requiredScale spec size)

-- | @requiredScale spec sz@ returns a scaling factor necessary to
-- make something of size @sz@ fit the requested size @spec@,
-- without changing the aspect ratio. Hence an explicit
-- specification of both dimensions may not be honored if the aspect
-- ratios do not match; in that case the scaling will be as large as
-- possible so that the object still fits within the requested size.
requiredScale :: SizeSpec2D -> (Double, Double) -> Double
requiredScale Absolute _ = 1
requiredScale (Width wSpec) (w,_)
| wSpec == 0 || w == 0 = 1
| otherwise = wSpec / w
requiredScale (Height hSpec) (_,h)
| hSpec == 0 || h == 0 = 1
| otherwise = hSpec / h
requiredScale (Dims wSpec hSpec) (w,h) = s
where xscale = wSpec / w
yscale = hSpec / h
s' = min xscale yscale
s | isInfinite s' = 1
| otherwise = s'

-- | Uniformly scale any enveloped object so that it fits within the
-- given size.
sized :: (Transformable a, Enveloped a, V a ~ R2)
=> SizeSpec2D -> a -> a
sized spec a = transform (requiredScaleT spec (size2D a)) a

-- | Uniformly scale an enveloped object so that it \"has the same
-- size as\" (fits within the width and height of) some other
-- object.
sizedAs :: ( Transformable a, Enveloped a, V a ~ R2
, Enveloped b, V b ~ R2)
=> b -> a -> a
sizedAs other = sized (sizeSpec2D other)