-
Notifications
You must be signed in to change notification settings - Fork 62
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
3d color & lighting, more solids, Angle utilities #166
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
2594195
3D colors, material reflectance
bergey d1806e4
simpler angleBetween
bergey 26807c2
Add trig functions using Angle
bergey 44bdbad
lenses for polar coordinates
bergey 7ff0263
make R3 strict data like R2
bergey 216317f
Make Direction a type, not a type class
bergey 03833af
Add Box
bergey 2e03dec
Add Frustum
bergey 1229c55
Wall: remove extra imports
bergey ec8f0a9
explicit instances for HasPhi, HasR, HasTheta to avoid overlap
bergey 9148c6a
make HasR _r lens be the vector magnitude
bergey debf974
clean up R3 instances
bergey 78c0522
Wall: remove unneeded import
bergey a52e8e5
generalize angleBetween for arbitrary InnerSpace
bergey e4312f0
move Angle definition to separate module
bergey 3ebb80d
move angleBetween to Diagrams.Angle
bergey daca572
export more Angle functions from TwoD.hs
bergey d7a09ea
import Data.Proxy iff GHC < 7.7
bergey 7b356a7
Better Haddock comments for 3D attributes, _r Lens
bergey e1897ca
Use _relative from Diagrams.Core
bergey 49d298f
Wall: remove AffineSpace import
bergey 77480c0
Export Angle module from Prelude instead of TwoD
bergey File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
{-# LANGUAGE DeriveDataTypeable #-} | ||
{-# LANGUAGE ExistentialQuantification #-} | ||
{-# LANGUAGE GeneralizedNewtypeDeriving #-} | ||
{-# LANGUAGE TemplateHaskell #-} | ||
----------------------------------------------------------------------------- | ||
-- | | ||
-- Module : Diagrams.ThreeD.Attributes | ||
-- Copyright : (c) 2014 diagrams-lib team (see LICENSE) | ||
-- License : BSD-style (see LICENSE) | ||
-- Maintainer : diagrams-discuss@googlegroups.com | ||
-- | ||
-- Diagrams may have /attributes/ which affect the way they are | ||
-- rendered. This module defines some common attributes relevant in | ||
-- 3D; particular backends may also define more backend-specific | ||
-- attributes. | ||
-- | ||
-- Every attribute type must have a /semigroup/ structure, that is, an | ||
-- associative binary operation for combining two attributes into one. | ||
-- Unless otherwise noted, all the attributes defined here use the | ||
-- 'Last' structure, that is, combining two attributes simply keeps | ||
-- the second one and throws away the first. This means that child | ||
-- attributes always override parent attributes. | ||
-- | ||
----------------------------------------------------------------------------- | ||
|
||
module Diagrams.ThreeD.Attributes where | ||
|
||
import Control.Lens | ||
import Data.Semigroup | ||
import Data.Typeable | ||
|
||
import Data.Colour | ||
|
||
import Diagrams.Core | ||
|
||
-- | @SurfaceColor@ is the inherent pigment of an object, assumed to | ||
-- be opaque. | ||
newtype SurfaceColor = SurfaceColor (Last (Colour Double)) | ||
deriving (Typeable, Semigroup) | ||
instance AttributeClass SurfaceColor | ||
|
||
surfaceColor :: Iso' SurfaceColor (Colour Double) | ||
surfaceColor = iso (\(SurfaceColor (Last c)) -> c) (SurfaceColor . Last) | ||
|
||
-- | Set the surface color. | ||
sc :: HasStyle d => Colour Double -> d -> d | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should add a Haddock comment for |
||
sc = applyAttr . review surfaceColor | ||
|
||
-- | @Diffuse@ is the fraction of incident light reflected diffusely, | ||
-- that is, in all directions. The actual light reflected is the | ||
-- product of this value, the incident light, and the @SurfaceColor@ | ||
-- Attribute. For physical reasonableness, @Diffuse@ should have a | ||
-- value between 0 and 1; this is not checked. | ||
newtype Diffuse = Diffuse (Last Double) | ||
deriving (Typeable, Semigroup) | ||
instance AttributeClass Diffuse | ||
|
||
_Diffuse :: Iso' Diffuse Double | ||
_Diffuse = iso (\(Diffuse (Last d)) -> d) (Diffuse . Last) | ||
|
||
-- | Set the diffuse reflectance. | ||
diffuse :: HasStyle d => Double -> d -> d | ||
diffuse = applyAttr . review _Diffuse | ||
|
||
-- | @Ambient@ is an ad-hoc representation of indirect lighting. The | ||
-- product of @Ambient@ and @SurfaceColor@ is added to the light | ||
-- leaving an object due to diffuse and specular terms. @Ambient@ can | ||
-- be set per-object, and can be loosely thought of as the product of | ||
-- indirect lighting incident on that object and the diffuse | ||
-- reflectance. | ||
newtype Ambient = Ambient (Last Double) | ||
deriving (Typeable, Semigroup) | ||
instance AttributeClass Ambient | ||
|
||
_Ambient :: Iso' Ambient Double | ||
_Ambient = iso (\(Ambient (Last d)) -> d) (Ambient . Last) | ||
|
||
-- | Set the emittance due to ambient light. | ||
ambient :: HasStyle d => Double -> d -> d | ||
ambient = applyAttr . review _Ambient | ||
|
||
-- | A specular highlight has two terms, the intensity, between 0 and | ||
-- 1, and the size. The highlight size is assumed to be the exponent | ||
-- in a Phong shading model (though Backends are free to use a | ||
-- different shading model). In this model, reasonable values are | ||
-- between 1 and 50 or so, with higher values for shinier objects. | ||
-- Physically, the intensity and the value of @Diffuse@ must add up to | ||
-- less than 1; this is not enforced. | ||
data Specular = Specular { _specularIntensity :: Double | ||
, _specularSize :: Double | ||
} | ||
|
||
makeLenses ''Specular | ||
|
||
newtype Highlight = Highlight (Last Specular) | ||
deriving (Typeable, Semigroup) | ||
instance AttributeClass Highlight | ||
|
||
_Highlight :: Iso' Highlight Specular | ||
_Highlight = iso (\(Highlight (Last s)) -> s) (Highlight . Last) | ||
|
||
-- | Set the specular highlight. | ||
highlight :: HasStyle d => Specular -> d -> d | ||
highlight = applyAttr . review _Highlight |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea of moving angle stuff into a separate module. This also paves the way for something else I'd like to think about, which is to generalize
Direction
over the vector space and do a better job distinguishing angles and directions (in 2D we currently conflate the two notions). (But note I'm not saying we should worry about that for this PR, it's just something I thought I would mention.)Does
Diagrams.Angle
need to be added to the exported modules list in the.cabal
file?