Skip to content

Commit

Permalink
Merge pull request #169 from diagrams/units2
Browse files Browse the repository at this point in the history
Rework of units
  • Loading branch information
jeffreyrosenbluth committed Mar 25, 2014
2 parents 92c40fe + d00b132 commit 2662f88
Show file tree
Hide file tree
Showing 42 changed files with 1,140 additions and 439 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ env:
- HPVER=2013.2.0.0
- GHCVER=7.4.2
- GHCVER=7.6.3
- GHCVER=7.8.1
- GHCVER=head
global:
- CABALVER=1.18
Expand Down
84 changes: 84 additions & 0 deletions CHANGES.markdown
Original file line number Diff line number Diff line change
@@ -1,3 +1,87 @@
1.1.0.3 (19 March 2014)
----------------------

- Allow `lens-4.1`

1.1.0.2 (18 March 2014)
-----------------------

- Allow `optparse-applicative-0.8`

1.1.0.1 (9 March 2014)
----------------------

- Allow `vector-space-points-0.2`

1.1 (8 March 2014)
------------------

* **New features**

- Support for `Deformation`s, arbitrary (non-affine)
transformations on objects such as points, paths, and located
trails (though not on diagrams).

- New functions `clipTo`, which clips a diagram's envelope and
trace along with its visual representation, and `clipped`, which
clips the diagram's visual representation but replaces its
envelope and trace with those of the clipping path.

- New `arrowV` function, for creating an arrow with the direction
and magnitude of a given vector.

- `gap` traversal, for setting the head and tail gaps of an arrow
simultaneously.

- Generalized types for `centerXY` and `snugXY`, based on new
`basis` function from `diagrams-core

- New 3D `Transform`s, alignment, and 3D-specific `Prelude`.

- New `frame` function similar to `pad`, but increases the envelope
of a diagram by an amount specified in local units in every direction
irrespective of the local origin.

- New `splitFills` function for pushing fill attributes down to
subtrees containing only loops (mostly of relevance only to
backend implementors).

* **New instances**

- `Typeable` instances for all data types that are used as diagram
primitives.
- `Sectionable` instance for `FixedSegment`.

* **API changes**

- `Angle` is now a type, rather than a class. It uses a single
internal representation for angles, and lenses `turn`, `rad,`
and `deg` are supplied for constructing (using `@@`) and viewing
(using `^.`) `Angle`s in various units. In addition, the `Num`
instance for `Angle` has been removed, eliminating a class of
errors where a bare number is interpreted in units other than
what you expect.

- Removed `Num` instance for angles.

* **Dependency/version changes**

- Require `lens >= 4.0`.
- Allow `array-0.5`.
- Allow `hashable-1.1`.
- Remove `NumInstances` dependency.

* **Bug fixes**

- Exclude joins in offsets on close segments (#160).
- Exclude extra segment when joining loops in offset (#155).

* **Performance improvements**

- `colorToSRGBA` function now avoids expensive matrix operations,
offering dramatic speedups in rendering diagrams with many color
attributes.

1.0.1 (26 January 2014)
-----------------------

Expand Down
3 changes: 2 additions & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
Copyright (c) 2011-2013 diagrams-lib team:
Copyright (c) 2011-2014 diagrams-lib team:

Jan Bracker <jan.bracker@googlemail.com>
Daniel Bergey <bergey@alum.mit.edu>
Denys Duchier <denys.duchier@univ-orleans.fr>
Daniil Frumin <difrumin@gmail.com>
Niklas Haas <nand@lavabit.com>
Peter Hall <peter.hall@memorphic.com>
Expand Down
16 changes: 9 additions & 7 deletions diagrams-lib.cabal
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Name: diagrams-lib
Version: 1.1
Version: 1.1.0.1
Synopsis: Embedded domain-specific language for declarative graphics
Description: Diagrams is a flexible, extensible EDSL for creating
graphics of many types. Graphics can be created
Expand All @@ -19,7 +19,7 @@ Build-type: Simple
Cabal-version: >=1.10
Extra-source-files: CHANGES.markdown, README.markdown, diagrams/*.svg
Extra-doc-files: diagrams/*.svg
Tested-with: GHC == 7.4.2, GHC == 7.6.1
Tested-with: GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.1
Source-repository head
type: git
location: http://github.com/diagrams/diagrams-lib.git
Expand All @@ -28,9 +28,11 @@ Library
Exposed-modules: Diagrams.Prelude,
Diagrams.Prelude.ThreeD,
Diagrams.Align,
Diagrams.Angle,
Diagrams.Combinators,
Diagrams.Coordinates,
Diagrams.Attributes,
Diagrams.Attributes.Compile,
Diagrams.Points,
Diagrams.Located,
Diagrams.Parametric,
Expand Down Expand Up @@ -63,7 +65,6 @@ Library
Diagrams.TwoD.Ellipse,
Diagrams.TwoD.Arc,
Diagrams.TwoD.Segment,
Diagrams.TwoD.Compile,
Diagrams.TwoD.Curvature,
Diagrams.TwoD.Offset,
Diagrams.TwoD.Path,
Expand All @@ -76,6 +77,7 @@ Library
Diagrams.TwoD.Image,
Diagrams.TwoD.Adjust,
Diagrams.ThreeD.Align,
Diagrams.ThreeD.Attributes,
Diagrams.ThreeD.Camera,
Diagrams.ThreeD.Deform,
Diagrams.ThreeD.Light,
Expand All @@ -94,19 +96,19 @@ Library
array >= 0.3 && < 0.6,
semigroups >= 0.3.4 && < 0.13,
monoid-extras >= 0.3 && < 0.4,
diagrams-core >= 1.0 && < 1.1,
diagrams-core >= 1.1 && < 1.2,
active >= 0.1 && < 0.2,
vector-space >= 0.7.7 && < 0.9,
vector-space-points >= 0.1.2 && < 0.2,
vector-space-points >= 0.1.2 && < 0.3,
MemoTrie >= 0.6 && < 0.7,
colour >= 2.3.2 && < 2.4,
data-default-class < 0.1,
pretty >= 1.0.1.2 && < 1.2,
fingertree >= 0.1 && < 0.2,
intervals >= 0.3 && < 0.5,
lens >= 4.0 && < 4.1,
lens >= 4.0 && < 4.2,
tagged >= 0.7,
optparse-applicative >= 0.7 && < 0.8,
optparse-applicative >= 0.7 && < 0.9,
filepath,
safe >= 0.2 && < 0.4,
hashable >= 1.1 && < 1.3
Expand Down
113 changes: 113 additions & 0 deletions src/Diagrams/Angle.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
-----------------------------------------------------------------------------
-- |
-- Module : Diagrams.Angle
-- Copyright : (c) 2013 diagrams-lib team (see LICENSE)
-- License : BSD-style (see LICENSE)
-- Maintainer : diagrams-discuss@googlegroups.com
--
-- Type for representing angles, independent of vector-space
--
-----------------------------------------------------------------------------

module Diagrams.Angle
(
Angle
, rad, turn, deg
, fullTurn, fullCircle, angleRatio
, sinA, cosA, tanA, asinA, acosA, atanA
, (@@)
, angleBetween
, HasTheta(..)
) where

import Control.Lens (Iso', Lens', iso, review, (^.))
-- , review , (^.), _1, _2, Lens', lens)

import Data.VectorSpace

-- | Angles can be expressed in a variety of units. Internally,
-- they are represented in radians.
newtype Angle = Radians Double
deriving (Read, Show, Eq, Ord, Enum, AdditiveGroup)

instance VectorSpace Angle where
type Scalar Angle = Double
s *^ Radians t = Radians (s*t)

-- | The radian measure of an @Angle@ @a@ can be accessed as @a
-- ^. rad@. A new @Angle@ can be defined in radians as @pi \@\@ rad@.
rad :: Iso' Angle Double
rad = iso (\(Radians r) -> r) Radians

-- | The measure of an @Angle@ @a@ in full circles can be accessed as
-- @a ^. turn@. A new @Angle@ of one-half circle can be defined in as
-- @1/2 \@\@ turn@.
turn :: Iso' Angle Double
turn = iso (\(Radians r) -> r/2/pi) (Radians . (*(2*pi)))

-- | The degree measure of an @Angle@ @a@ can be accessed as @a
-- ^. deg@. A new @Angle@ can be defined in degrees as @180 \@\@
-- deg@.
deg :: Iso' Angle Double
deg = iso (\(Radians r) -> r/2/pi*360) (Radians . (*(2*pi/360)))

-- | An angle representing one full turn.
fullTurn :: Angle
fullTurn = 1 @@ turn

-- | Deprecated synonym for 'fullTurn', retained for backwards compatibility.
fullCircle :: Angle
fullCircle = fullTurn

-- | Calculate ratio between two angles.
angleRatio :: Angle -> Angle -> Double
angleRatio a b = (a^.rad) / (b^.rad)

-- | The sine of the given @Angle@.
sinA :: Angle -> Double
sinA (Radians r) = sin r

-- | The cosine of the given @Angle@.
cosA :: Angle -> Double
cosA (Radians r) = cos r

-- | The tangent function of the given @Angle@.
tanA :: Angle -> Double
tanA (Radians r) = tan r

-- | The @Angle@ with the given sine.
asinA :: Double -> Angle
asinA = Radians . asin

-- | The @Angle@ with the given cosine.
acosA :: Double -> Angle
acosA = Radians . acos

-- | The @Angle@ with the given tangent.
atanA :: Double -> Angle
atanA = Radians . atan

-- | @30 \@\@ deg@ is an @Angle@ of the given measure and units.
--
-- More generally, @\@\@@ reverses the @Iso\'@ on its right, and
-- applies the @Iso\'@ to the value on the left. @Angle@s are the
-- motivating example where this order improves readability.
(@@) :: b -> Iso' a b -> a
-- The signature above is slightly specialized, in favor of readability
a @@ i = review i a

infixl 5 @@

-- | compute the positive angle between the two vectors in their common plane
angleBetween :: (InnerSpace v, Scalar v ~ Double) => v -> v -> Angle
angleBetween v1 v2 = acos (normalized v1 <.> normalized v2) @@ rad

------------------------------------------------------------
-- Polar Coordinates

-- | The class of types with at least one angle coordinate, called _theta.
class HasTheta t where
_theta :: Lens' t Angle
57 changes: 30 additions & 27 deletions src/Diagrams/Attributes.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
-----------------------------------------------------------------------------
-- |
-- Module : Diagrams.Attributes
Expand Down Expand Up @@ -49,24 +51,28 @@ module Diagrams.Attributes (
-- ** Miter limit
, LineMiterLimit(..), getLineMiterLimit, lineMiterLimit, lineMiterLimitA

-- ** Dashing
, Dashing(..), DashingA, getDashing, dashing

-- * Compilation utilities
, splitFills

) where

import Control.Lens (Setter, sets)
import Control.Lens (Setter, sets)
import Data.Colour
import Data.Colour.RGBSpace (RGB(..))
import Data.Colour.SRGB (toSRGB)
import Data.Colour.RGBSpace (RGB (..))
import Data.Colour.SRGB (toSRGB)
import Data.Default.Class
import Data.Maybe (fromMaybe)
import Data.Maybe (fromMaybe)
import Data.Monoid.Recommend
import Data.Semigroup
import Data.Typeable

import Diagrams.Attributes.Compile
import Diagrams.Core
import Diagrams.Core.Style (setAttr)
import Diagrams.Core.Style (setAttr)
import Diagrams.Core.Types (RTree)
import Diagrams.Located (unLoc)
import Diagrams.Path (Path, pathTrails)
import Diagrams.Trail (isLoop)

------------------------------------------------------------
-- Color -------------------------------------------------
Expand Down Expand Up @@ -333,24 +339,21 @@ lineMiterLimit = applyAttr . LineMiterLimit . Last
-- | Apply a 'LineMiterLimit' attribute.
lineMiterLimitA :: HasStyle a => LineMiterLimit -> a -> a
lineMiterLimitA = applyAttr
------------------------------------------------------------

-- | Create lines that are dashing... er, dashed.
data Dashing = Dashing [Double] Double
deriving (Typeable, Eq)
data FillLoops v = FillLoops

newtype DashingA = DashingA (Last Dashing)
deriving (Typeable, Semigroup, Eq)
instance AttributeClass DashingA

getDashing :: DashingA -> Dashing
getDashing (DashingA (Last d)) = d

-- | Set the line dashing style.
dashing :: HasStyle a =>
[Double] -- ^ A list specifying alternate lengths of on
-- and off portions of the stroke. The empty
-- list indicates no dashing.
-> Double -- ^ An offset into the dash pattern at which the
-- stroke should start.
-> a -> a
dashing ds offs = applyAttr (DashingA (Last (Dashing ds offs)))
instance Typeable v => SplitAttribute (FillLoops v) where
type AttrType (FillLoops v) = FillColor
type PrimType (FillLoops v) = Path v

primOK _ = all (isLoop . unLoc) . pathTrails

-- | Push fill attributes down until they are at the root of subtrees
-- containing only loops. This makes life much easier for backends,
-- which typically have a semantics where fill attributes are
-- applied to lines/non-closed paths as well as loops/closed paths,
-- whereas in the semantics of diagrams, fill attributes only apply
-- to loops.
splitFills :: forall b v a. Typeable v => RTree b v a -> RTree b v a
splitFills = splitAttr (FillLoops :: FillLoops v)
Loading

0 comments on commit 2662f88

Please sign in to comment.