AC-Vector 2.3.2 → 2.4.0
raw patch · 17 files changed
+855/−852 lines, 17 filesdep ~basesetup-changednew-uploaderPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base
API changes (from Hackage documentation)
- Data.BoundingBox.B1: instance Eq BBox1
- Data.BoundingBox.B1: instance Show BBox1
- Data.BoundingBox.B1: range :: BBox1 -> Range
- Data.BoundingBox.B2: instance Eq BBox2
- Data.BoundingBox.B2: instance Show BBox2
- Data.BoundingBox.B2: maxX :: BBox2 -> {-# UNPACK #-} !Scalar
- Data.BoundingBox.B2: maxY :: BBox2 -> {-# UNPACK #-} !Scalar
- Data.BoundingBox.B2: minX :: BBox2 -> {-# UNPACK #-} !Scalar
- Data.BoundingBox.B2: minY :: BBox2 -> {-# UNPACK #-} !Scalar
- Data.BoundingBox.B3: instance Eq BBox3
- Data.BoundingBox.B3: instance Show BBox3
- Data.BoundingBox.B3: maxX :: BBox3 -> {-# UNPACK #-} !Scalar
- Data.BoundingBox.B3: maxY :: BBox3 -> {-# UNPACK #-} !Scalar
- Data.BoundingBox.B3: maxZ :: BBox3 -> {-# UNPACK #-} !Scalar
- Data.BoundingBox.B3: minX :: BBox3 -> {-# UNPACK #-} !Scalar
- Data.BoundingBox.B3: minY :: BBox3 -> {-# UNPACK #-} !Scalar
- Data.BoundingBox.B3: minZ :: BBox3 -> {-# UNPACK #-} !Scalar
- Data.BoundingBox.B4: instance Eq BBox4
- Data.BoundingBox.B4: instance Show BBox4
- Data.BoundingBox.B4: maxW :: BBox4 -> {-# UNPACK #-} !Scalar
- Data.BoundingBox.B4: maxX :: BBox4 -> {-# UNPACK #-} !Scalar
- Data.BoundingBox.B4: maxY :: BBox4 -> {-# UNPACK #-} !Scalar
- Data.BoundingBox.B4: maxZ :: BBox4 -> {-# UNPACK #-} !Scalar
- Data.BoundingBox.B4: minW :: BBox4 -> {-# UNPACK #-} !Scalar
- Data.BoundingBox.B4: minX :: BBox4 -> {-# UNPACK #-} !Scalar
- Data.BoundingBox.B4: minY :: BBox4 -> {-# UNPACK #-} !Scalar
- Data.BoundingBox.B4: minZ :: BBox4 -> {-# UNPACK #-} !Scalar
- Data.BoundingBox.Range: instance Eq Range
- Data.BoundingBox.Range: instance Show Range
- Data.BoundingBox.Range: max_point :: Range -> {-# UNPACK #-} !Scalar
- Data.BoundingBox.Range: min_point :: Range -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T1: instance Eq Transform1
- Data.Vector.Transform.T1: instance Monoid Transform1
- Data.Vector.Transform.T1: instance Show Transform1
- Data.Vector.Transform.T1: t1_1X :: Transform1 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T1: t1_XX :: Transform1 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T2: instance Eq Transform2
- Data.Vector.Transform.T2: instance Monoid Transform2
- Data.Vector.Transform.T2: instance Show Transform2
- Data.Vector.Transform.T2: t2_1X :: Transform2 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T2: t2_1Y :: Transform2 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T2: t2_XX :: Transform2 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T2: t2_XY :: Transform2 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T2: t2_YX :: Transform2 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T2: t2_YY :: Transform2 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T3: instance Eq Transform3
- Data.Vector.Transform.T3: instance Monoid Transform3
- Data.Vector.Transform.T3: instance Show Transform3
- Data.Vector.Transform.T3: t3_1X :: Transform3 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T3: t3_1Y :: Transform3 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T3: t3_1Z :: Transform3 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T3: t3_XX :: Transform3 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T3: t3_XY :: Transform3 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T3: t3_XZ :: Transform3 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T3: t3_YX :: Transform3 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T3: t3_YY :: Transform3 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T3: t3_YZ :: Transform3 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T3: t3_ZX :: Transform3 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T3: t3_ZY :: Transform3 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T3: t3_ZZ :: Transform3 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T4: instance Eq Transform4
- Data.Vector.Transform.T4: instance Monoid Transform4
- Data.Vector.Transform.T4: instance Show Transform4
- Data.Vector.Transform.T4: t4_1W :: Transform4 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T4: t4_1X :: Transform4 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T4: t4_1Y :: Transform4 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T4: t4_1Z :: Transform4 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T4: t4_WW :: Transform4 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T4: t4_WX :: Transform4 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T4: t4_WY :: Transform4 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T4: t4_WZ :: Transform4 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T4: t4_XW :: Transform4 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T4: t4_XX :: Transform4 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T4: t4_XY :: Transform4 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T4: t4_XZ :: Transform4 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T4: t4_YW :: Transform4 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T4: t4_YX :: Transform4 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T4: t4_YY :: Transform4 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T4: t4_YZ :: Transform4 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T4: t4_ZW :: Transform4 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T4: t4_ZX :: Transform4 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T4: t4_ZY :: Transform4 -> {-# UNPACK #-} !Scalar
- Data.Vector.Transform.T4: t4_ZZ :: Transform4 -> {-# UNPACK #-} !Scalar
- Data.Vector.V1: instance BasicVector Vector1
- Data.Vector.V1: instance Enum Vector1
- Data.Vector.V1: instance Eq Vector1
- Data.Vector.V1: instance Fractional Vector1
- Data.Vector.V1: instance Num Vector1
- Data.Vector.V1: instance Ord Vector1
- Data.Vector.V1: instance Show Vector1
- Data.Vector.V1: instance Vector Vector1
- Data.Vector.V1: v1x :: Vector1 -> Scalar
- Data.Vector.V2: instance BasicVector Vector2
- Data.Vector.V2: instance Eq Vector2
- Data.Vector.V2: instance Fractional Vector2
- Data.Vector.V2: instance Num Vector2
- Data.Vector.V2: instance Show Vector2
- Data.Vector.V2: instance Vector Vector2
- Data.Vector.V2: v2x :: Vector2 -> {-# UNPACK #-} !Scalar
- Data.Vector.V2: v2y :: Vector2 -> {-# UNPACK #-} !Scalar
- Data.Vector.V3: instance BasicVector Vector3
- Data.Vector.V3: instance Eq Vector3
- Data.Vector.V3: instance Fractional Vector3
- Data.Vector.V3: instance Num Vector3
- Data.Vector.V3: instance Show Vector3
- Data.Vector.V3: instance Vector Vector3
- Data.Vector.V3: v3x :: Vector3 -> {-# UNPACK #-} !Scalar
- Data.Vector.V3: v3y :: Vector3 -> {-# UNPACK #-} !Scalar
- Data.Vector.V3: v3z :: Vector3 -> {-# UNPACK #-} !Scalar
- Data.Vector.V4: instance BasicVector Vector4
- Data.Vector.V4: instance Eq Vector4
- Data.Vector.V4: instance Fractional Vector4
- Data.Vector.V4: instance Num Vector4
- Data.Vector.V4: instance Show Vector4
- Data.Vector.V4: instance Vector Vector4
- Data.Vector.V4: v4w :: Vector4 -> {-# UNPACK #-} !Scalar
- Data.Vector.V4: v4x :: Vector4 -> {-# UNPACK #-} !Scalar
- Data.Vector.V4: v4y :: Vector4 -> {-# UNPACK #-} !Scalar
- Data.Vector.V4: v4z :: Vector4 -> {-# UNPACK #-} !Scalar
+ Data.BoundingBox.B1: [range] :: BBox1 -> Range
+ Data.BoundingBox.B1: instance GHC.Classes.Eq Data.BoundingBox.B1.BBox1
+ Data.BoundingBox.B1: instance GHC.Show.Show Data.BoundingBox.B1.BBox1
+ Data.BoundingBox.B2: [minX, minY, maxX, maxY] :: BBox2 -> {-# UNPACK #-} !Scalar
+ Data.BoundingBox.B2: instance GHC.Classes.Eq Data.BoundingBox.B2.BBox2
+ Data.BoundingBox.B2: instance GHC.Show.Show Data.BoundingBox.B2.BBox2
+ Data.BoundingBox.B3: [minX, minY, minZ, maxX, maxY, maxZ] :: BBox3 -> {-# UNPACK #-} !Scalar
+ Data.BoundingBox.B3: instance GHC.Classes.Eq Data.BoundingBox.B3.BBox3
+ Data.BoundingBox.B3: instance GHC.Show.Show Data.BoundingBox.B3.BBox3
+ Data.BoundingBox.B4: [minX, minY, minZ, minW, maxX, maxY, maxZ, maxW] :: BBox4 -> {-# UNPACK #-} !Scalar
+ Data.BoundingBox.B4: instance GHC.Classes.Eq Data.BoundingBox.B4.BBox4
+ Data.BoundingBox.B4: instance GHC.Show.Show Data.BoundingBox.B4.BBox4
+ Data.BoundingBox.Range: [min_point, max_point] :: Range -> {-# UNPACK #-} !Scalar
+ Data.BoundingBox.Range: instance GHC.Classes.Eq Data.BoundingBox.Range.Range
+ Data.BoundingBox.Range: instance GHC.Show.Show Data.BoundingBox.Range.Range
+ Data.Vector.Class: infixl 7 /|
+ Data.Vector.Transform.T1: [t1_XX, t1_1X] :: Transform1 -> {-# UNPACK #-} !Scalar
+ Data.Vector.Transform.T1: instance GHC.Base.Monoid Data.Vector.Transform.T1.Transform1
+ Data.Vector.Transform.T1: instance GHC.Base.Semigroup Data.Vector.Transform.T1.Transform1
+ Data.Vector.Transform.T1: instance GHC.Classes.Eq Data.Vector.Transform.T1.Transform1
+ Data.Vector.Transform.T1: instance GHC.Show.Show Data.Vector.Transform.T1.Transform1
+ Data.Vector.Transform.T2: [t2_XX, t2_YX, t2_1X, t2_XY, t2_YY, t2_1Y] :: Transform2 -> {-# UNPACK #-} !Scalar
+ Data.Vector.Transform.T2: instance GHC.Base.Monoid Data.Vector.Transform.T2.Transform2
+ Data.Vector.Transform.T2: instance GHC.Base.Semigroup Data.Vector.Transform.T2.Transform2
+ Data.Vector.Transform.T2: instance GHC.Classes.Eq Data.Vector.Transform.T2.Transform2
+ Data.Vector.Transform.T2: instance GHC.Show.Show Data.Vector.Transform.T2.Transform2
+ Data.Vector.Transform.T3: [t3_XX, t3_YX, t3_ZX, t3_1X, t3_XY, t3_YY, t3_ZY, t3_1Y, t3_XZ, t3_YZ, t3_ZZ, t3_1Z] :: Transform3 -> {-# UNPACK #-} !Scalar
+ Data.Vector.Transform.T3: instance GHC.Base.Monoid Data.Vector.Transform.T3.Transform3
+ Data.Vector.Transform.T3: instance GHC.Base.Semigroup Data.Vector.Transform.T3.Transform3
+ Data.Vector.Transform.T3: instance GHC.Classes.Eq Data.Vector.Transform.T3.Transform3
+ Data.Vector.Transform.T3: instance GHC.Show.Show Data.Vector.Transform.T3.Transform3
+ Data.Vector.Transform.T4: [t4_XX, t4_YX, t4_ZX, t4_WX, t4_1X, t4_XY, t4_YY, t4_ZY, t4_WY, t4_1Y, t4_XZ, t4_YZ, t4_ZZ, t4_WZ, t4_1Z, t4_XW, t4_YW, t4_ZW, t4_WW, t4_1W] :: Transform4 -> {-# UNPACK #-} !Scalar
+ Data.Vector.Transform.T4: instance GHC.Base.Monoid Data.Vector.Transform.T4.Transform4
+ Data.Vector.Transform.T4: instance GHC.Base.Semigroup Data.Vector.Transform.T4.Transform4
+ Data.Vector.Transform.T4: instance GHC.Classes.Eq Data.Vector.Transform.T4.Transform4
+ Data.Vector.Transform.T4: instance GHC.Show.Show Data.Vector.Transform.T4.Transform4
+ Data.Vector.V1: [v1x] :: Vector1 -> Scalar
+ Data.Vector.V1: instance Data.Vector.Class.BasicVector Data.Vector.V1.Vector1
+ Data.Vector.V1: instance Data.Vector.Class.Vector Data.Vector.V1.Vector1
+ Data.Vector.V1: instance GHC.Classes.Eq Data.Vector.V1.Vector1
+ Data.Vector.V1: instance GHC.Classes.Ord Data.Vector.V1.Vector1
+ Data.Vector.V1: instance GHC.Enum.Enum Data.Vector.V1.Vector1
+ Data.Vector.V1: instance GHC.Num.Num Data.Vector.V1.Vector1
+ Data.Vector.V1: instance GHC.Real.Fractional Data.Vector.V1.Vector1
+ Data.Vector.V1: instance GHC.Show.Show Data.Vector.V1.Vector1
+ Data.Vector.V2: [v2x, v2y] :: Vector2 -> {-# UNPACK #-} !Scalar
+ Data.Vector.V2: instance Data.Vector.Class.BasicVector Data.Vector.V2.Vector2
+ Data.Vector.V2: instance Data.Vector.Class.Vector Data.Vector.V2.Vector2
+ Data.Vector.V2: instance GHC.Classes.Eq Data.Vector.V2.Vector2
+ Data.Vector.V2: instance GHC.Num.Num Data.Vector.V2.Vector2
+ Data.Vector.V2: instance GHC.Real.Fractional Data.Vector.V2.Vector2
+ Data.Vector.V2: instance GHC.Show.Show Data.Vector.V2.Vector2
+ Data.Vector.V3: [v3x, v3y, v3z] :: Vector3 -> {-# UNPACK #-} !Scalar
+ Data.Vector.V3: instance Data.Vector.Class.BasicVector Data.Vector.V3.Vector3
+ Data.Vector.V3: instance Data.Vector.Class.Vector Data.Vector.V3.Vector3
+ Data.Vector.V3: instance GHC.Classes.Eq Data.Vector.V3.Vector3
+ Data.Vector.V3: instance GHC.Num.Num Data.Vector.V3.Vector3
+ Data.Vector.V3: instance GHC.Real.Fractional Data.Vector.V3.Vector3
+ Data.Vector.V3: instance GHC.Show.Show Data.Vector.V3.Vector3
+ Data.Vector.V4: [v4x, v4y, v4z, v4w] :: Vector4 -> {-# UNPACK #-} !Scalar
+ Data.Vector.V4: instance Data.Vector.Class.BasicVector Data.Vector.V4.Vector4
+ Data.Vector.V4: instance Data.Vector.Class.Vector Data.Vector.V4.Vector4
+ Data.Vector.V4: instance GHC.Classes.Eq Data.Vector.V4.Vector4
+ Data.Vector.V4: instance GHC.Num.Num Data.Vector.V4.Vector4
+ Data.Vector.V4: instance GHC.Real.Fractional Data.Vector.V4.Vector4
+ Data.Vector.V4: instance GHC.Show.Show Data.Vector.V4.Vector4
- Data.BoundingBox.B2: BBox2 :: {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> BBox2
+ Data.BoundingBox.B2: BBox2 :: {-# UNPACK #-} !Scalar -> BBox2
- Data.BoundingBox.B3: BBox3 :: {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> BBox3
+ Data.BoundingBox.B3: BBox3 :: {-# UNPACK #-} !Scalar -> BBox3
- Data.BoundingBox.B4: BBox4 :: {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> BBox4
+ Data.BoundingBox.B4: BBox4 :: {-# UNPACK #-} !Scalar -> BBox4
- Data.BoundingBox.Range: Range :: {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> Range
+ Data.BoundingBox.Range: Range :: {-# UNPACK #-} !Scalar -> Range
- Data.Vector.Class: vfold :: BasicVector v => (Scalar -> Scalar -> Scalar) -> (v -> Scalar)
+ Data.Vector.Class: vfold :: BasicVector v => (Scalar -> Scalar -> Scalar) -> v -> Scalar
- Data.Vector.Class: vmap :: BasicVector v => (Scalar -> Scalar) -> (v -> v)
+ Data.Vector.Class: vmap :: BasicVector v => (Scalar -> Scalar) -> v -> v
- Data.Vector.Class: vzip :: BasicVector v => (Scalar -> Scalar -> Scalar) -> (v -> v -> v)
+ Data.Vector.Class: vzip :: BasicVector v => (Scalar -> Scalar -> Scalar) -> v -> v -> v
- Data.Vector.Transform.T1: Transform1 :: {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> Transform1
+ Data.Vector.Transform.T1: Transform1 :: {-# UNPACK #-} !Scalar -> Transform1
- Data.Vector.Transform.T2: Transform2 :: {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> Transform2
+ Data.Vector.Transform.T2: Transform2 :: {-# UNPACK #-} !Scalar -> Transform2
- Data.Vector.Transform.T3: Transform3 :: {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> Transform3
+ Data.Vector.Transform.T3: Transform3 :: {-# UNPACK #-} !Scalar -> Transform3
- Data.Vector.Transform.T4: Transform4 :: {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> Transform4
+ Data.Vector.Transform.T4: Transform4 :: {-# UNPACK #-} !Scalar -> Transform4
- Data.Vector.V2: Vector2 :: {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> Vector2
+ Data.Vector.V2: Vector2 :: {-# UNPACK #-} !Scalar -> Vector2
- Data.Vector.V3: Vector3 :: {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> Vector3
+ Data.Vector.V3: Vector3 :: {-# UNPACK #-} !Scalar -> Vector3
- Data.Vector.V4: Vector4 :: {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> {-# UNPACK #-} !Scalar -> Vector4
+ Data.Vector.V4: Vector4 :: {-# UNPACK #-} !Scalar -> Vector4
Files
- AC-Vector.cabal +38/−47
- Data/BoundingBox/B1.hs +46/−46
- Data/BoundingBox/B2.hs +76/−76
- Data/BoundingBox/B3.hs +84/−84
- Data/BoundingBox/B4.hs +93/−93
- Data/BoundingBox/Range.hs +40/−40
- Data/Vector/Class.hs +98/−98
- Data/Vector/Transform/T1.hs +38/−35
- Data/Vector/Transform/T2.hs +49/−46
- Data/Vector/Transform/T3.hs +58/−55
- Data/Vector/Transform/T4.hs +69/−66
- Data/Vector/V1.hs +32/−32
- Data/Vector/V2.hs +36/−36
- Data/Vector/V3.hs +50/−50
- Data/Vector/V4.hs +36/−36
- License.txt +10/−10
- Setup.hs +2/−2
AC-Vector.cabal view
@@ -1,47 +1,38 @@-Cabal-Version: >= 1.6 -Name: AC-Vector -Version: 2.3.2 -Stability: Experimental -Synopsis: Efficient geometric vectors and transformations. - -Description: - - This Haskell library implements several small vectors types - with @Double@ fields, with seperate types for each size of - vector, and a type class for handling vectors generally. - (Note that although this package is listed in the \"graphics\" - category, the package itself has no graphics facilities. It - just contains data structures that are useful for graphics - work.) - . - Changes: - . - * Fixed a stupid bug in @union@. Until now, the function could - sometimes return gibberish answers. Hopefully this is now fixed. - -Category: Data, Math, Numerical, Graphics -License: BSD3 -License-file: License.txt -Author: Andrew Coppin -Maintainer: MathematicalOrchid@hotmail.com -Build-Type: Simple -Tested-With: GHC == 6.10.3 - -Library - Exposed-modules: - Data.Vector.Class, - Data.Vector.V1, - Data.Vector.V2, - Data.Vector.V3, - Data.Vector.V4, - Data.Vector.Transform.T1, - Data.Vector.Transform.T2, - Data.Vector.Transform.T3, - Data.Vector.Transform.T4, - Data.BoundingBox.Range, - Data.BoundingBox.B1, - Data.BoundingBox.B2, - Data.BoundingBox.B3, - Data.BoundingBox.B4 - Build-Depends: base >= 4 && < 5 - HS-Source-Dirs: . +Cabal-Version: >= 1.10+Name: AC-Vector+Version: 2.4.0+Stability: Experimental+Synopsis: Efficient geometric vectors and transformations.+Description:+ This Haskell library implements several small vectors types with @Double@+ fields, with seperate types for each size of vector, and a type class for+ handling vectors generally. (Note that although this package is listed in the+ \"graphics\" category, the package itself has no graphics facilities. It just+ contains data structures that are useful for graphics work.)+Category: Data, Math, Numerical, Graphics+License: BSD3+License-file: License.txt+Author: Andrew Coppin+Maintainer: jan@rochel.info+Build-Type: Simple+Tested-With: GHC == 6.10.3, GHC == 9.0.2++Library+ Exposed-modules:+ Data.Vector.Class,+ Data.Vector.V1,+ Data.Vector.V2,+ Data.Vector.V3,+ Data.Vector.V4,+ Data.Vector.Transform.T1,+ Data.Vector.Transform.T2,+ Data.Vector.Transform.T3,+ Data.Vector.Transform.T4,+ Data.BoundingBox.Range,+ Data.BoundingBox.B1,+ Data.BoundingBox.B2,+ Data.BoundingBox.B3,+ Data.BoundingBox.B4+ Build-Depends: base >= 4.9 && < 5+ HS-Source-Dirs: .+ Default-Language: Haskell2010
Data/BoundingBox/B1.hs view
@@ -1,46 +1,46 @@-{- | - This module provides the 'BBox1' type (mainly for completeness). --} - -module Data.BoundingBox.B1 where - -import Data.Vector.Class -import Data.Vector.V1 -import qualified Data.BoundingBox.Range as R - --- | The 'BBox1' type is basically a 'Range', but all the operations over it work with 'Vector1' (which is really 'Scalar'). While it's called a bounding /box/, a 1-dimensional box is in truth a simple line interval, just like 'Range'. -newtype BBox1 = BBox1 {range :: R.Range} deriving (Eq, Show) - --- | Given two vectors, construct a bounding box (swapping the endpoints if necessary). -bound_corners :: Vector1 -> Vector1 -> BBox1 -bound_corners (Vector1 xa) (Vector1 xb) = BBox1 $ R.bound_corners xa xb - --- | Find the bounds of a list of points. (Throws an exception if the list is empty.) -bound_points :: [Vector1] -> BBox1 -bound_points = BBox1 . R.bound_points . map v1x - --- | Test whether a 'Vector1' lies within a 'BBox1'. -within_bounds :: Vector1 -> BBox1 -> Bool -within_bounds (Vector1 x) (BBox1 r) = x `R.within_bounds` r - --- | Return the minimum endpoint for a 'BBox1'. -min_point :: BBox1 -> Vector1 -min_point = Vector1 . R.min_point . range - --- | Return the maximum endpoint for a 'BBox1'. -max_point :: BBox1 -> Vector1 -max_point = Vector1 . R.max_point . range - --- | Take the union of two 'BBox1' values. The result is a new 'BBox1' that contains all the points the original boxes contained, plus any extra space between them. -union :: BBox1 -> BBox1 -> BBox1 -union (BBox1 r0) (BBox1 r1) = BBox1 (r0 `R.union` r1) - --- | Take the intersection of two 'BBox1' values. If the boxes do not overlap, return 'Nothing'. Otherwise return a 'BBox1' containing only the points common to both argument boxes. -isect :: BBox1 -> BBox1 -> Maybe BBox1 -isect (BBox1 r0) (BBox1 r1) = do - r <- (r0 `R.isect` r1) - return (BBox1 r) - --- | Efficiently compute the union of a list of bounding boxes. -unions :: [BBox1] -> BBox1 -unions = BBox1 . R.unions . map range +{- |+ This module provides the 'BBox1' type (mainly for completeness).+-}++module Data.BoundingBox.B1 where++import Data.Vector.Class+import Data.Vector.V1+import qualified Data.BoundingBox.Range as R++-- | The 'BBox1' type is basically a 'Range', but all the operations over it work with 'Vector1' (which is really 'Scalar'). While it's called a bounding /box/, a 1-dimensional box is in truth a simple line interval, just like 'Range'.+newtype BBox1 = BBox1 {range :: R.Range} deriving (Eq, Show)++-- | Given two vectors, construct a bounding box (swapping the endpoints if necessary).+bound_corners :: Vector1 -> Vector1 -> BBox1+bound_corners (Vector1 xa) (Vector1 xb) = BBox1 $ R.bound_corners xa xb++-- | Find the bounds of a list of points. (Throws an exception if the list is empty.)+bound_points :: [Vector1] -> BBox1+bound_points = BBox1 . R.bound_points . map v1x++-- | Test whether a 'Vector1' lies within a 'BBox1'.+within_bounds :: Vector1 -> BBox1 -> Bool+within_bounds (Vector1 x) (BBox1 r) = x `R.within_bounds` r++-- | Return the minimum endpoint for a 'BBox1'.+min_point :: BBox1 -> Vector1+min_point = Vector1 . R.min_point . range++-- | Return the maximum endpoint for a 'BBox1'.+max_point :: BBox1 -> Vector1+max_point = Vector1 . R.max_point . range++-- | Take the union of two 'BBox1' values. The result is a new 'BBox1' that contains all the points the original boxes contained, plus any extra space between them.+union :: BBox1 -> BBox1 -> BBox1+union (BBox1 r0) (BBox1 r1) = BBox1 (r0 `R.union` r1)++-- | Take the intersection of two 'BBox1' values. If the boxes do not overlap, return 'Nothing'. Otherwise return a 'BBox1' containing only the points common to both argument boxes.+isect :: BBox1 -> BBox1 -> Maybe BBox1+isect (BBox1 r0) (BBox1 r1) = do+ r <- (r0 `R.isect` r1)+ return (BBox1 r)++-- | Efficiently compute the union of a list of bounding boxes.+unions :: [BBox1] -> BBox1+unions = BBox1 . R.unions . map range
Data/BoundingBox/B2.hs view
@@ -1,76 +1,76 @@-{- | - This module provides the 'BBox2' type for 2-dimensional bounding boxes. --} - -module Data.BoundingBox.B2 where - -import Data.Vector.Class -import Data.Vector.V2 -import qualified Data.BoundingBox.Range as R - --- | A 'BBox2' is a 2D bounding box (aligned to the coordinate axies). -data BBox2 = BBox2 {minX, minY, maxX, maxY :: {-# UNPACK #-} !Scalar} deriving (Eq, Show) - --- | Return the X-range that this bounding box covers. -rangeX :: BBox2 -> R.Range -rangeX b = R.Range (minX b) (maxX b) - --- | Return the Y-range that this bounding box covers. -rangeY :: BBox2 -> R.Range -rangeY b = R.Range (minY b) (maxY b) - --- | Given ranges for each coordinate axis, construct a bounding box. -rangeXY :: R.Range -> R.Range -> BBox2 -rangeXY (R.Range x0 x1) (R.Range y0 y1) = BBox2 x0 y0 x1 y1 - --- | Given a pair of corner points, construct a bounding box. (The points must be from opposite corners, but it doesn't matter /which/ corners nor which order they are given in.) -bound_corners :: Vector2 -> Vector2 -> BBox2 -bound_corners (Vector2 xa ya) (Vector2 xb yb) = BBox2 (min xa xb) (min ya yb) (max xa xb) (max ya yb) - --- | Find the bounds of a list of points. (Throws an exception if the list is empty.) -bound_points :: [Vector2] -> BBox2 -bound_points ps = - let - xs = map v2x ps - ys = map v2y ps - in BBox2 (minimum xs) (minimum ys) (maximum xs) (maximum ys) - --- | Test whether a given 2D vector is inside this bounding box. -within_bounds :: Vector2 -> BBox2 -> Bool -within_bounds (Vector2 x y) b = - x `R.within_bounds` (rangeX b) && - y `R.within_bounds` (rangeY b) - --- | Return the minimum values for both coordinates. (In usual 2D space, the bottom-left corner point.) -min_point :: BBox2 -> Vector2 -min_point (BBox2 x0 y0 x1 y1) = Vector2 x0 y0 - --- | Return the maximum values for both coordinates. (In usual 2D space, the top-right corner point.) -max_point :: BBox2 -> Vector2 -max_point (BBox2 x0 y0 x1 y1) = Vector2 x1 y1 - --- | Take the union of two bounding boxes. The result is a new bounding box that contains all the points the original boxes contained, plus any extra space between them. -union :: BBox2 -> BBox2 -> BBox2 -union b0 b1 = - let - rx = (rangeX b0) `R.union` (rangeX b1) - ry = (rangeY b0) `R.union` (rangeY b1) - in rangeXY rx ry - --- | Take the intersection of two bounding boxes. If the boxes do not overlap, return 'Nothing'. Otherwise return a new bounding box containing only the points common to both argument boxes. -isect :: BBox2 -> BBox2 -> Maybe BBox2 -isect b0 b1 = do - rx <- (rangeX b0) `R.isect` (rangeX b1) - ry <- (rangeY b0) `R.isect` (rangeY b1) - return (rangeXY rx ry) - --- | Efficiently compute the union of a list of bounding boxes. -unions :: [BBox2] -> BBox2 -unions bs = - let - minP = map min_point bs - maxP = map max_point bs - in - BBox2 - (minimum $ map v2x minP) (minimum $ map v2y minP) - (maximum $ map v2x maxP) (maximum $ map v2y maxP) +{- |+ This module provides the 'BBox2' type for 2-dimensional bounding boxes.+-}++module Data.BoundingBox.B2 where++import Data.Vector.Class+import Data.Vector.V2+import qualified Data.BoundingBox.Range as R++-- | A 'BBox2' is a 2D bounding box (aligned to the coordinate axies).+data BBox2 = BBox2 {minX, minY, maxX, maxY :: {-# UNPACK #-} !Scalar} deriving (Eq, Show)++-- | Return the X-range that this bounding box covers.+rangeX :: BBox2 -> R.Range+rangeX b = R.Range (minX b) (maxX b)++-- | Return the Y-range that this bounding box covers.+rangeY :: BBox2 -> R.Range+rangeY b = R.Range (minY b) (maxY b)++-- | Given ranges for each coordinate axis, construct a bounding box.+rangeXY :: R.Range -> R.Range -> BBox2+rangeXY (R.Range x0 x1) (R.Range y0 y1) = BBox2 x0 y0 x1 y1++-- | Given a pair of corner points, construct a bounding box. (The points must be from opposite corners, but it doesn't matter /which/ corners nor which order they are given in.)+bound_corners :: Vector2 -> Vector2 -> BBox2+bound_corners (Vector2 xa ya) (Vector2 xb yb) = BBox2 (min xa xb) (min ya yb) (max xa xb) (max ya yb)++-- | Find the bounds of a list of points. (Throws an exception if the list is empty.)+bound_points :: [Vector2] -> BBox2+bound_points ps =+ let+ xs = map v2x ps+ ys = map v2y ps+ in BBox2 (minimum xs) (minimum ys) (maximum xs) (maximum ys)++-- | Test whether a given 2D vector is inside this bounding box.+within_bounds :: Vector2 -> BBox2 -> Bool+within_bounds (Vector2 x y) b =+ x `R.within_bounds` (rangeX b) &&+ y `R.within_bounds` (rangeY b)++-- | Return the minimum values for both coordinates. (In usual 2D space, the bottom-left corner point.)+min_point :: BBox2 -> Vector2+min_point (BBox2 x0 y0 x1 y1) = Vector2 x0 y0++-- | Return the maximum values for both coordinates. (In usual 2D space, the top-right corner point.)+max_point :: BBox2 -> Vector2+max_point (BBox2 x0 y0 x1 y1) = Vector2 x1 y1++-- | Take the union of two bounding boxes. The result is a new bounding box that contains all the points the original boxes contained, plus any extra space between them.+union :: BBox2 -> BBox2 -> BBox2+union b0 b1 =+ let+ rx = (rangeX b0) `R.union` (rangeX b1)+ ry = (rangeY b0) `R.union` (rangeY b1)+ in rangeXY rx ry++-- | Take the intersection of two bounding boxes. If the boxes do not overlap, return 'Nothing'. Otherwise return a new bounding box containing only the points common to both argument boxes.+isect :: BBox2 -> BBox2 -> Maybe BBox2+isect b0 b1 = do+ rx <- (rangeX b0) `R.isect` (rangeX b1)+ ry <- (rangeY b0) `R.isect` (rangeY b1)+ return (rangeXY rx ry)++-- | Efficiently compute the union of a list of bounding boxes.+unions :: [BBox2] -> BBox2+unions bs =+ let+ minP = map min_point bs+ maxP = map max_point bs+ in+ BBox2+ (minimum $ map v2x minP) (minimum $ map v2y minP)+ (maximum $ map v2x maxP) (maximum $ map v2y maxP)
Data/BoundingBox/B3.hs view
@@ -1,84 +1,84 @@-{- | - This module provides the 'BBox3' type for 3-dimensional bounding boxes (\"bounding volumes\"). --} - -module Data.BoundingBox.B3 where - -import Data.Vector.Class -import Data.Vector.V3 -import qualified Data.BoundingBox.Range as R - --- | A 'BBox3' is a 3D bounding box (aligned to the coordinate axies). -data BBox3 = BBox3 {minX, minY, minZ, maxX, maxY, maxZ :: {-# UNPACK #-} !Scalar} deriving (Eq, Show) - --- | Return the X-range that this bounding box covers. -rangeX :: BBox3 -> R.Range -rangeX b = R.Range (minX b) (maxX b) - --- | Return the Y-range that this bounding box covers. -rangeY :: BBox3 -> R.Range -rangeY b = R.Range (minY b) (maxY b) - --- | Return the Z-range that this bounding box covers. -rangeZ :: BBox3 -> R.Range -rangeZ b = R.Range (minZ b) (maxZ b) - --- | Given ranges for each coordinate axis, construct a bounding box. -rangeXYZ :: R.Range -> R.Range -> R.Range -> BBox3 -rangeXYZ (R.Range x0 x1) (R.Range y0 y1) (R.Range z0 z1) = BBox3 x0 y0 z0 x1 y1 z1 - --- | Given a pair of corner points, construct a bounding box. (The points must be from opposite corners, but it doesn't matter /which/ corners nor which order they are given in.) -bound_corners :: Vector3 -> Vector3 -> BBox3 -bound_corners (Vector3 xa ya za) (Vector3 xb yb zb) = BBox3 (min xa xb) (min ya yb) (min za zb) (max xa xb) (max ya yb) (max za zb) - --- | Find the bounds of a list of points. (Throws an exception if the list is empty.) -bound_points :: [Vector3] -> BBox3 -bound_points ps = - let - xs = map v3x ps - ys = map v3y ps - zs = map v3z ps - in BBox3 (minimum xs) (minimum ys) (minimum zs) (maximum xs) (maximum ys) (maximum zs) - --- | Test whether a given 3D vector is inside this bounding box. -within_bounds :: Vector3 -> BBox3 -> Bool -within_bounds (Vector3 x y z) b = - x `R.within_bounds` (rangeX b) && - y `R.within_bounds` (rangeY b) && - z `R.within_bounds` (rangeZ b) - --- | Return the minimum values for all coordinates. -min_point :: BBox3 -> Vector3 -min_point (BBox3 x0 y0 z0 x1 y1 z1) = Vector3 x0 y0 z0 - --- | Return the maximum values for all coordinates. -max_point :: BBox3 -> Vector3 -max_point (BBox3 x0 y0 z0 x1 y1 z1) = Vector3 x1 y1 z1 - --- | Take the union of two bounding boxes. The result is a new bounding box that contains all the points the original boxes contained, plus any extra space between them. -union :: BBox3 -> BBox3 -> BBox3 -union b0 b1 = - let - rx = (rangeX b0) `R.union` (rangeX b1) - ry = (rangeY b0) `R.union` (rangeY b1) - rz = (rangeZ b0) `R.union` (rangeZ b1) - in rangeXYZ rx ry rz - --- | Take the intersection of two bounding boxes. If the boxes do not overlap, return 'Nothing'. Otherwise return a new bounding box containing only the points common to both argument boxes. -isect :: BBox3 -> BBox3 -> Maybe BBox3 -isect b0 b1 = do - rx <- (rangeX b0) `R.isect` (rangeX b1) - ry <- (rangeY b0) `R.isect` (rangeY b1) - rz <- (rangeZ b0) `R.isect` (rangeZ b1) - return (rangeXYZ rx ry rz) - --- | Efficiently compute the union of a list of bounding boxes. -unions :: [BBox3] -> BBox3 -unions bs = - let - minP = map min_point bs - maxP = map max_point bs - in - BBox3 - (minimum $ map v3x minP) (minimum $ map v3y minP) (minimum $ map v3z minP) - (maximum $ map v3x maxP) (maximum $ map v3y maxP) (maximum $ map v3z maxP) +{- |+ This module provides the 'BBox3' type for 3-dimensional bounding boxes (\"bounding volumes\").+-}++module Data.BoundingBox.B3 where++import Data.Vector.Class+import Data.Vector.V3+import qualified Data.BoundingBox.Range as R++-- | A 'BBox3' is a 3D bounding box (aligned to the coordinate axies).+data BBox3 = BBox3 {minX, minY, minZ, maxX, maxY, maxZ :: {-# UNPACK #-} !Scalar} deriving (Eq, Show)++-- | Return the X-range that this bounding box covers.+rangeX :: BBox3 -> R.Range+rangeX b = R.Range (minX b) (maxX b)++-- | Return the Y-range that this bounding box covers.+rangeY :: BBox3 -> R.Range+rangeY b = R.Range (minY b) (maxY b)++-- | Return the Z-range that this bounding box covers.+rangeZ :: BBox3 -> R.Range+rangeZ b = R.Range (minZ b) (maxZ b)++-- | Given ranges for each coordinate axis, construct a bounding box.+rangeXYZ :: R.Range -> R.Range -> R.Range -> BBox3+rangeXYZ (R.Range x0 x1) (R.Range y0 y1) (R.Range z0 z1) = BBox3 x0 y0 z0 x1 y1 z1++-- | Given a pair of corner points, construct a bounding box. (The points must be from opposite corners, but it doesn't matter /which/ corners nor which order they are given in.)+bound_corners :: Vector3 -> Vector3 -> BBox3+bound_corners (Vector3 xa ya za) (Vector3 xb yb zb) = BBox3 (min xa xb) (min ya yb) (min za zb) (max xa xb) (max ya yb) (max za zb)++-- | Find the bounds of a list of points. (Throws an exception if the list is empty.)+bound_points :: [Vector3] -> BBox3+bound_points ps =+ let+ xs = map v3x ps+ ys = map v3y ps+ zs = map v3z ps+ in BBox3 (minimum xs) (minimum ys) (minimum zs) (maximum xs) (maximum ys) (maximum zs)++-- | Test whether a given 3D vector is inside this bounding box.+within_bounds :: Vector3 -> BBox3 -> Bool+within_bounds (Vector3 x y z) b =+ x `R.within_bounds` (rangeX b) &&+ y `R.within_bounds` (rangeY b) &&+ z `R.within_bounds` (rangeZ b)++-- | Return the minimum values for all coordinates.+min_point :: BBox3 -> Vector3+min_point (BBox3 x0 y0 z0 x1 y1 z1) = Vector3 x0 y0 z0++-- | Return the maximum values for all coordinates.+max_point :: BBox3 -> Vector3+max_point (BBox3 x0 y0 z0 x1 y1 z1) = Vector3 x1 y1 z1++-- | Take the union of two bounding boxes. The result is a new bounding box that contains all the points the original boxes contained, plus any extra space between them.+union :: BBox3 -> BBox3 -> BBox3+union b0 b1 =+ let+ rx = (rangeX b0) `R.union` (rangeX b1)+ ry = (rangeY b0) `R.union` (rangeY b1)+ rz = (rangeZ b0) `R.union` (rangeZ b1)+ in rangeXYZ rx ry rz++-- | Take the intersection of two bounding boxes. If the boxes do not overlap, return 'Nothing'. Otherwise return a new bounding box containing only the points common to both argument boxes.+isect :: BBox3 -> BBox3 -> Maybe BBox3+isect b0 b1 = do+ rx <- (rangeX b0) `R.isect` (rangeX b1)+ ry <- (rangeY b0) `R.isect` (rangeY b1)+ rz <- (rangeZ b0) `R.isect` (rangeZ b1)+ return (rangeXYZ rx ry rz)++-- | Efficiently compute the union of a list of bounding boxes.+unions :: [BBox3] -> BBox3+unions bs =+ let+ minP = map min_point bs+ maxP = map max_point bs+ in+ BBox3+ (minimum $ map v3x minP) (minimum $ map v3y minP) (minimum $ map v3z minP)+ (maximum $ map v3x maxP) (maximum $ map v3y maxP) (maximum $ map v3z maxP)
Data/BoundingBox/B4.hs view
@@ -1,93 +1,93 @@-{- | - This module provides the 'BBox4' type for 4-dimensional bounding boxes (bounding hyper-volumes\). --} - -module Data.BoundingBox.B4 where - -import Data.Vector.Class -import Data.Vector.V4 -import qualified Data.BoundingBox.Range as R - --- | A 'BBox4' is a 4D bounding box (aligned to the coordinate axies). -data BBox4 = BBox4 {minX, minY, minZ, minW, maxX, maxY, maxZ, maxW :: {-# UNPACK #-} !Scalar} deriving (Eq, Show) - --- | Return the X-range that this bounding box covers. -rangeX :: BBox4 -> R.Range -rangeX b = R.Range (minX b) (maxX b) - --- | Return the Y-range that this bounding box covers. -rangeY :: BBox4 -> R.Range -rangeY b = R.Range (minY b) (maxY b) - --- | Return the Z-range that this bounding box covers. -rangeZ :: BBox4 -> R.Range -rangeZ b = R.Range (minZ b) (maxZ b) - --- | Return the W-range (4th coordinate) that this bounding box covers. -rangeW :: BBox4 -> R.Range -rangeW b = R.Range (minW b) (maxW b) - --- | Given ranges for each coordinate axis, construct a bounding box. -rangeXYZW :: R.Range -> R.Range -> R.Range -> R.Range -> BBox4 -rangeXYZW (R.Range x0 x1) (R.Range y0 y1) (R.Range z0 z1) (R.Range w0 w1) = BBox4 x0 y0 z0 w0 x1 y1 z1 w1 - --- | Given a pair of corner points, construct a bounding box. (The points must be from opposite corners, but it doesn't matter /which/ corners nor which order they are given in.) -bound_corners :: Vector4 -> Vector4 -> BBox4 -bound_corners (Vector4 xa ya za wa) (Vector4 xb yb zb wb) = - BBox4 (min xa xb) (min ya yb) (min za zb) (min wa wb) (max xa xb) (max ya yb) (max za zb) (max wa wb) - --- | Find the bounds of a list of points. (Throws an exception if the list is empty.) -bound_points :: [Vector4] -> BBox4 -bound_points ps = - let - xs = map v4x ps - ys = map v4y ps - zs = map v4z ps - ws = map v4w ps - in BBox4 (minimum xs) (minimum ys) (minimum zs) (minimum ws) (maximum xs) (maximum ys) (maximum zs) (maximum ws) - --- | Test whether a given 4D vector is inside this bounding box. -within_bounds :: Vector4 -> BBox4 -> Bool -within_bounds (Vector4 x y z w) b = - x `R.within_bounds` (rangeX b) && - y `R.within_bounds` (rangeY b) && - z `R.within_bounds` (rangeZ b) && - w `R.within_bounds` (rangeW b) - --- | Return the minimum values for all coordinates. -min_point :: BBox4 -> Vector4 -min_point (BBox4 x0 y0 z0 w0 x1 y1 z1 w1) = Vector4 x0 y0 z0 w0 - --- | Return the maximum values for all coordinates. -max_point :: BBox4 -> Vector4 -max_point (BBox4 x0 y0 z0 w0 x1 y1 z1 w1) = Vector4 x1 y1 z1 w1 - --- | Take the union of two bounding boxes. The result is a new bounding box that contains all the points the original boxes contained, plus any extra space between them. -union :: BBox4 -> BBox4 -> BBox4 -union b0 b1 = - let - rx = (rangeX b0) `R.union` (rangeX b1) - ry = (rangeY b0) `R.union` (rangeY b1) - rz = (rangeZ b0) `R.union` (rangeZ b1) - rw = (rangeW b0) `R.union` (rangeW b1) - in rangeXYZW rx ry rz rw - --- | Take the intersection of two bounding boxes. If the boxes do not overlap, return 'Nothing'. Otherwise return a new bounding box containing only the points common to both argument boxes. -isect :: BBox4 -> BBox4 -> Maybe BBox4 -isect b0 b1 = do - rx <- (rangeX b0) `R.isect` (rangeX b1) - ry <- (rangeY b0) `R.isect` (rangeY b1) - rz <- (rangeZ b0) `R.isect` (rangeZ b1) - rw <- (rangeW b0) `R.isect` (rangeW b1) - return (rangeXYZW rx ry rz rw) - --- | Efficiently compute the union of a list of bounding boxes. -unions :: [BBox4] -> BBox4 -unions bs = - let - minP = map min_point bs - maxP = map max_point bs - in - BBox4 - (minimum $ map v4x minP) (minimum $ map v4y minP) (minimum $ map v4z minP) (minimum $ map v4w minP) - (maximum $ map v4x maxP) (maximum $ map v4y maxP) (maximum $ map v4z maxP) (maximum $ map v4w maxP) +{- |+ This module provides the 'BBox4' type for 4-dimensional bounding boxes (bounding hyper-volumes\).+-}++module Data.BoundingBox.B4 where++import Data.Vector.Class+import Data.Vector.V4+import qualified Data.BoundingBox.Range as R++-- | A 'BBox4' is a 4D bounding box (aligned to the coordinate axies).+data BBox4 = BBox4 {minX, minY, minZ, minW, maxX, maxY, maxZ, maxW :: {-# UNPACK #-} !Scalar} deriving (Eq, Show)++-- | Return the X-range that this bounding box covers.+rangeX :: BBox4 -> R.Range+rangeX b = R.Range (minX b) (maxX b)++-- | Return the Y-range that this bounding box covers.+rangeY :: BBox4 -> R.Range+rangeY b = R.Range (minY b) (maxY b)++-- | Return the Z-range that this bounding box covers.+rangeZ :: BBox4 -> R.Range+rangeZ b = R.Range (minZ b) (maxZ b)++-- | Return the W-range (4th coordinate) that this bounding box covers.+rangeW :: BBox4 -> R.Range+rangeW b = R.Range (minW b) (maxW b)++-- | Given ranges for each coordinate axis, construct a bounding box.+rangeXYZW :: R.Range -> R.Range -> R.Range -> R.Range -> BBox4+rangeXYZW (R.Range x0 x1) (R.Range y0 y1) (R.Range z0 z1) (R.Range w0 w1) = BBox4 x0 y0 z0 w0 x1 y1 z1 w1++-- | Given a pair of corner points, construct a bounding box. (The points must be from opposite corners, but it doesn't matter /which/ corners nor which order they are given in.)+bound_corners :: Vector4 -> Vector4 -> BBox4+bound_corners (Vector4 xa ya za wa) (Vector4 xb yb zb wb) =+ BBox4 (min xa xb) (min ya yb) (min za zb) (min wa wb) (max xa xb) (max ya yb) (max za zb) (max wa wb)++-- | Find the bounds of a list of points. (Throws an exception if the list is empty.)+bound_points :: [Vector4] -> BBox4+bound_points ps =+ let+ xs = map v4x ps+ ys = map v4y ps+ zs = map v4z ps+ ws = map v4w ps+ in BBox4 (minimum xs) (minimum ys) (minimum zs) (minimum ws) (maximum xs) (maximum ys) (maximum zs) (maximum ws)++-- | Test whether a given 4D vector is inside this bounding box.+within_bounds :: Vector4 -> BBox4 -> Bool+within_bounds (Vector4 x y z w) b =+ x `R.within_bounds` (rangeX b) &&+ y `R.within_bounds` (rangeY b) &&+ z `R.within_bounds` (rangeZ b) &&+ w `R.within_bounds` (rangeW b)++-- | Return the minimum values for all coordinates.+min_point :: BBox4 -> Vector4+min_point (BBox4 x0 y0 z0 w0 x1 y1 z1 w1) = Vector4 x0 y0 z0 w0++-- | Return the maximum values for all coordinates.+max_point :: BBox4 -> Vector4+max_point (BBox4 x0 y0 z0 w0 x1 y1 z1 w1) = Vector4 x1 y1 z1 w1++-- | Take the union of two bounding boxes. The result is a new bounding box that contains all the points the original boxes contained, plus any extra space between them.+union :: BBox4 -> BBox4 -> BBox4+union b0 b1 =+ let+ rx = (rangeX b0) `R.union` (rangeX b1)+ ry = (rangeY b0) `R.union` (rangeY b1)+ rz = (rangeZ b0) `R.union` (rangeZ b1)+ rw = (rangeW b0) `R.union` (rangeW b1)+ in rangeXYZW rx ry rz rw++-- | Take the intersection of two bounding boxes. If the boxes do not overlap, return 'Nothing'. Otherwise return a new bounding box containing only the points common to both argument boxes.+isect :: BBox4 -> BBox4 -> Maybe BBox4+isect b0 b1 = do+ rx <- (rangeX b0) `R.isect` (rangeX b1)+ ry <- (rangeY b0) `R.isect` (rangeY b1)+ rz <- (rangeZ b0) `R.isect` (rangeZ b1)+ rw <- (rangeW b0) `R.isect` (rangeW b1)+ return (rangeXYZW rx ry rz rw)++-- | Efficiently compute the union of a list of bounding boxes.+unions :: [BBox4] -> BBox4+unions bs =+ let+ minP = map min_point bs+ maxP = map max_point bs+ in+ BBox4+ (minimum $ map v4x minP) (minimum $ map v4y minP) (minimum $ map v4z minP) (minimum $ map v4w minP)+ (maximum $ map v4x maxP) (maximum $ map v4y maxP) (maximum $ map v4z maxP) (maximum $ map v4w maxP)
Data/BoundingBox/Range.hs view
@@ -1,40 +1,40 @@-{- | - This module provides the 'Range' type and several functions for working with ranges. --} - -module Data.BoundingBox.Range where - -import Data.Vector.Class - -{- | - A 'Range' represents a continuous interval between two 'Scalar' endpoints. --} -data Range = Range {min_point, max_point :: {-# UNPACK #-} !Scalar} deriving (Eq, Show) - --- | Given two 'Scalar's, construct a 'Range' (swapping the endpoints if necessary so that they are in the correct order. -bound_corners :: Scalar -> Scalar -> Range -bound_corners xa xb = Range (min xa xb) (max xa xb) - --- | Find the bounds of a list of points. (Throws an exception if the list is empty.) -bound_points :: [Scalar] -> Range -bound_points xs = Range (minimum xs) (maximum xs) - --- | Test whether a given 'Scalar' falls within a particular 'Range'. -within_bounds :: Scalar -> Range -> Bool -within_bounds x (Range x0 x1) = x0 <= x && x <= x1 - --- | Take the union of two ranges. The resulting 'Range' contains all points that the original ranges contained, plus any points between them (if the original ranges don't overlap). -union :: Range -> Range -> Range -union (Range ll lh) (Range rl rh) = Range (min ll rl) (max lh rh) - --- | Take the intersection of two ranges. If the ranges do not overlap, the intersection is empty, and 'Nothing' is returned. (This is a good way to check whether two ranges overlap or not.) Otherwise a new 'Range' is returned that contains only the points common to both ranges. -isect :: Range -> Range -> Maybe Range -isect (Range ll lh) (Range rl rh) = - let - nl = max ll rl - nh = min lh rh - in if nl > nh then Nothing else Just (Range nl nh) - --- | Efficiently compute the union of a list of ranges. -unions :: [Range] -> Range -unions rs = Range (minimum $ map min_point rs) (maximum $ map max_point rs) +{- |+ This module provides the 'Range' type and several functions for working with ranges.+-}++module Data.BoundingBox.Range where++import Data.Vector.Class++{- |+ A 'Range' represents a continuous interval between two 'Scalar' endpoints.+-}+data Range = Range {min_point, max_point :: {-# UNPACK #-} !Scalar} deriving (Eq, Show)++-- | Given two 'Scalar's, construct a 'Range' (swapping the endpoints if necessary so that they are in the correct order.+bound_corners :: Scalar -> Scalar -> Range+bound_corners xa xb = Range (min xa xb) (max xa xb)++-- | Find the bounds of a list of points. (Throws an exception if the list is empty.)+bound_points :: [Scalar] -> Range+bound_points xs = Range (minimum xs) (maximum xs)++-- | Test whether a given 'Scalar' falls within a particular 'Range'.+within_bounds :: Scalar -> Range -> Bool+within_bounds x (Range x0 x1) = x0 <= x && x <= x1++-- | Take the union of two ranges. The resulting 'Range' contains all points that the original ranges contained, plus any points between them (if the original ranges don't overlap).+union :: Range -> Range -> Range+union (Range ll lh) (Range rl rh) = Range (min ll rl) (max lh rh)++-- | Take the intersection of two ranges. If the ranges do not overlap, the intersection is empty, and 'Nothing' is returned. (This is a good way to check whether two ranges overlap or not.) Otherwise a new 'Range' is returned that contains only the points common to both ranges.+isect :: Range -> Range -> Maybe Range+isect (Range ll lh) (Range rl rh) =+ let+ nl = max ll rl+ nh = min lh rh+ in if nl > nh then Nothing else Just (Range nl nh)++-- | Efficiently compute the union of a list of ranges.+unions :: [Range] -> Range+unions rs = Range (minimum $ map min_point rs) (maximum $ map max_point rs)
Data/Vector/Class.hs view
@@ -1,98 +1,98 @@-{- | - General functions applicable to all vector types. --} - -module Data.Vector.Class where - --- | The type of vector field values. -type Scalar = Double - -{- | - All vector types belong to this class. Aside from 'vpack' and 'vunpack', these methods aren't especially useful to end-users; they're used internally by the vector arithmetic implementations. --} -class BasicVector v where - -- | Apply a function to all vector fields. - vmap :: (Scalar -> Scalar) -> (v -> v) - - -- | Zip two vectors together field-by-field using the supplied function (in the style of @Data.List.zipWith@). - vzip :: (Scalar -> Scalar -> Scalar) -> (v -> v -> v) - - -- | Reduce a vector down to a single value using the supplied binary operator. The ordering in which this happens isn't guaranteed, so the operator should probably be associative and commutative. - vfold :: (Scalar -> Scalar -> Scalar) -> (v -> Scalar) - - -- | Pack a list of values into a vector. Extra values are ignored, too few values yields @Nothing@. - vpack :: [Scalar] -> Maybe v - - -- | Unpack a vector into a list of values. (Always succeeds.) - vunpack :: v -> [Scalar] - - -- | Convert a 'Scalar' to a vector (with all components the same). - vpromote :: Scalar -> v - -{- | - Dummy class that enables you to request a vector in a type signature without needing to explicitly list 'Num' or 'Fractional' as well. --} -class (BasicVector v, Num v, Fractional v) => Vector v where - -{- | - Scale a vector (i.e., change its length but not its direction). This operator has the same precedence as the usual @(*)@ operator. - - The @(*|)@ and @(|*)@ operators are identical, but with their argument flipped. Just remember that the \'@|@\' denotes the scalar part. --} -(*|) :: Vector v => Scalar -> v -> v -k *| v = vmap (k*) v - -{- | - Scale a vector (i.e., change its length but not its direction). This operator has the same precedence as the usual @(*)@ operator. - - The @(*|)@ and @(|*)@ operators are identical, but with their argument flipped. Just remember that the \'@|@\' denotes the scalar part. --} -(|*) :: Vector v => v -> Scalar -> v -v |* k = vmap (k*) v - -{- | - Scale a vector (i.e., change its length but not its direction). This operator has the same precedence as the usual @(/)@ operator. - - The @(/|)@ and @(|/)@ operators are identical, but with their argument flipped. Just remember that the \'@|@\' denotes the scalar part. --} -(|/) :: Vector v => v -> Scalar -> v -v |/ k = v |* (1/k) - -{- | - Scale a vector (i.e., change its length but not its direction). This operator has the same precedence as the usual @(/)@ operator. - - The @(/|)@ and @(|/)@ operators are identical, but with their argument flipped. Just remember that the \'@|@\' denotes the scalar part. --} -(/|) :: Vector v => Scalar -> v -> v -k /| v = (1/k) *| v - -infixl 7 *| -infixl 7 |* -infixl 7 /| -infixl 7 |/ - --- | Take the /dot product/ of two vectors. This is a scalar equal to the cosine of the angle between the two vectors multiplied by the length of each vectors. -vdot :: Vector v => v -> v -> Scalar -v1 `vdot` v2 = vfold (+) $ vzip (*) v1 v2 - --- | Return the length or /magnitude/ of a vector. (Note that this involves a slow square root operation.) -vmag :: Vector v => v -> Scalar -vmag v = sqrt (v `vdot` v) - --- | Normalise a vector. In order words, return a new vector with the same direction, but a length of exactly one. (If the vector's length is zero or very near to zero, the vector is returned unchanged.) -vnormalise :: Vector v => v -> v -vnormalise v = - let m = vmag v - in if m < 1e-16 then v else v |* (1/m) - -{- | - Linearly interpolate between two points in space. - - * @vlinear 0 a b = a@ - - * @vlinear 1 a b = b@ - - * @vlinear 0.5 a b@ would give a point exactly half way between @a@ and @b@ in a straight line. --} -vlinear :: (Vector v) => Scalar -> v -> v -> v -vlinear t a b = (1-t) *| a + t *| b +{- |+ General functions applicable to all vector types.+-}++module Data.Vector.Class where++-- | The type of vector field values.+type Scalar = Double++{- |+ All vector types belong to this class. Aside from 'vpack' and 'vunpack', these methods aren't especially useful to end-users; they're used internally by the vector arithmetic implementations.+-}+class BasicVector v where+ -- | Apply a function to all vector fields.+ vmap :: (Scalar -> Scalar) -> (v -> v)++ -- | Zip two vectors together field-by-field using the supplied function (in the style of @Data.List.zipWith@).+ vzip :: (Scalar -> Scalar -> Scalar) -> (v -> v -> v)++ -- | Reduce a vector down to a single value using the supplied binary operator. The ordering in which this happens isn't guaranteed, so the operator should probably be associative and commutative.+ vfold :: (Scalar -> Scalar -> Scalar) -> (v -> Scalar)++ -- | Pack a list of values into a vector. Extra values are ignored, too few values yields @Nothing@.+ vpack :: [Scalar] -> Maybe v++ -- | Unpack a vector into a list of values. (Always succeeds.)+ vunpack :: v -> [Scalar]++ -- | Convert a 'Scalar' to a vector (with all components the same).+ vpromote :: Scalar -> v++{- |+ Dummy class that enables you to request a vector in a type signature without needing to explicitly list 'Num' or 'Fractional' as well.+-}+class (BasicVector v, Num v, Fractional v) => Vector v where++{- |+ Scale a vector (i.e., change its length but not its direction). This operator has the same precedence as the usual @(*)@ operator.++ The @(*|)@ and @(|*)@ operators are identical, but with their argument flipped. Just remember that the \'@|@\' denotes the scalar part.+-}+(*|) :: Vector v => Scalar -> v -> v+k *| v = vmap (k*) v++{- |+ Scale a vector (i.e., change its length but not its direction). This operator has the same precedence as the usual @(*)@ operator.++ The @(*|)@ and @(|*)@ operators are identical, but with their argument flipped. Just remember that the \'@|@\' denotes the scalar part.+-}+(|*) :: Vector v => v -> Scalar -> v+v |* k = vmap (k*) v++{- |+ Scale a vector (i.e., change its length but not its direction). This operator has the same precedence as the usual @(/)@ operator.++ The @(/|)@ and @(|/)@ operators are identical, but with their argument flipped. Just remember that the \'@|@\' denotes the scalar part.+-}+(|/) :: Vector v => v -> Scalar -> v+v |/ k = v |* (1/k)++{- |+ Scale a vector (i.e., change its length but not its direction). This operator has the same precedence as the usual @(/)@ operator.++ The @(/|)@ and @(|/)@ operators are identical, but with their argument flipped. Just remember that the \'@|@\' denotes the scalar part.+-}+(/|) :: Vector v => Scalar -> v -> v+k /| v = (1/k) *| v++infixl 7 *|+infixl 7 |*+infixl 7 /|+infixl 7 |/++-- | Take the /dot product/ of two vectors. This is a scalar equal to the cosine of the angle between the two vectors multiplied by the length of each vectors.+vdot :: Vector v => v -> v -> Scalar+v1 `vdot` v2 = vfold (+) $ vzip (*) v1 v2++-- | Return the length or /magnitude/ of a vector. (Note that this involves a slow square root operation.)+vmag :: Vector v => v -> Scalar+vmag v = sqrt (v `vdot` v)++-- | Normalise a vector. In order words, return a new vector with the same direction, but a length of exactly one. (If the vector's length is zero or very near to zero, the vector is returned unchanged.)+vnormalise :: Vector v => v -> v+vnormalise v =+ let m = vmag v+ in if m < 1e-16 then v else v |* (1/m)++{- |+ Linearly interpolate between two points in space.++ * @vlinear 0 a b = a@++ * @vlinear 1 a b = b@++ * @vlinear 0.5 a b@ would give a point exactly half way between @a@ and @b@ in a straight line.+-}+vlinear :: (Vector v) => Scalar -> v -> v -> v+vlinear t a b = (1-t) *| a + t *| b
Data/Vector/Transform/T1.hs view
@@ -1,35 +1,38 @@-{- | - 1-dimensional linear transformations. --} - -module Data.Vector.Transform.T1 where - -import Data.Monoid - -import Data.Vector.Class -import Data.Vector.V1 - -{- | - The type of 1D linear transformations. Essentially, this is applying a linear function to a number. - - Note the @Monoid@ instance, which gives you access to the identity transform (@mempty@) and the ability to combine a series of transforms into a single transform (@mappend@). --} -data Transform1 = - Transform1 - { - t1_XX, t1_1X :: {-# UNPACK #-} !Scalar - } - deriving (Eq, Show) - -instance Monoid Transform1 where - mempty = Transform1 1 0 - mappend a b = - Transform1 - { - t1_XX = t1_XX a * t1_XX b, - t1_1X = t1_1X a * t1_XX b + t1_1X b - } - --- | Apply a 1D transformation to a 1D point, yielding a new 1D point. -transformP1 :: Transform1 -> Vector1 -> Vector1 -transformP1 a (Vector1 x) = Vector1 (t1_XX a * x + t1_1X a) +{- |+ 1-dimensional linear transformations.+-}++module Data.Vector.Transform.T1 where++import Data.Semigroup+import Data.Monoid++import Data.Vector.Class+import Data.Vector.V1++{- |+ The type of 1D linear transformations. Essentially, this is applying a linear function to a number.++ Note the @Monoid@ instance, which gives you access to the identity transform (@mempty@) and the ability to combine a series of transforms into a single transform (@mappend@).+-}+data Transform1 =+ Transform1+ {+ t1_XX, t1_1X :: {-# UNPACK #-} !Scalar+ }+ deriving (Eq, Show)++instance Monoid Transform1 where+ mempty = Transform1 1 0++instance Semigroup Transform1 where+ a <> b =+ Transform1+ {+ t1_XX = t1_XX a * t1_XX b,+ t1_1X = t1_1X a * t1_XX b + t1_1X b+ }++-- | Apply a 1D transformation to a 1D point, yielding a new 1D point.+transformP1 :: Transform1 -> Vector1 -> Vector1+transformP1 a (Vector1 x) = Vector1 (t1_XX a * x + t1_1X a)
Data/Vector/Transform/T2.hs view
@@ -1,46 +1,49 @@-{- | - 2-dimensional linear transformations. --} - -module Data.Vector.Transform.T2 where - -import Data.Monoid - -import Data.Vector.Class -import Data.Vector.V2 - -{- | - The type of 2D linear transformations. - - Note the @Monoid@ instance, which gives you access to the identity transform (@mempty@) and the ability to combine a series of transforms into a single transform (@mappend@). --} -data Transform2 = - Transform2 - { - t2_XX, t2_YX, t2_1X, - t2_XY, t2_YY, t2_1Y :: {-# UNPACK #-} !Scalar - } - deriving (Eq, Show) - -instance Monoid Transform2 where - mempty = Transform2 1 0 0 0 1 0 - mappend a b = - Transform2 - { - t2_XX = t2_XX a * t2_XX b + t2_XY a * t2_YX b, - t2_YX = t2_YX a * t2_XX b + t2_YY a * t2_YX b, - t2_1X = t2_1X a * t2_XX b + t2_1Y a * t2_YX b + t2_1X b, - - t2_XY = t2_XX a * t2_XY b + t2_XY a * t2_YY b, - t2_YY = t2_YX a * t2_XY b + t2_YY a * t2_YY b, - t2_1Y = t2_1X a * t2_XY b + t2_1Y a * t2_YY b + t2_1Y b - } - --- | Apply a 2D transformation to a 2D point, yielding a new 2D point. -transformP2 :: Transform2 -> Vector2 -> Vector2 -transformP2 a (Vector2 x y) = - Vector2 - { - v2x = t2_XX a * x + t2_YX a * y + t2_1X a, - v2y = t2_XY a * x + t2_YY a * y + t2_1Y a - } +{- |+ 2-dimensional linear transformations.+-}++module Data.Vector.Transform.T2 where++import Data.Semigroup+import Data.Monoid++import Data.Vector.Class+import Data.Vector.V2++{- |+ The type of 2D linear transformations.++ Note the @Monoid@ instance, which gives you access to the identity transform (@mempty@) and the ability to combine a series of transforms into a single transform (@mappend@).+-}+data Transform2 =+ Transform2+ {+ t2_XX, t2_YX, t2_1X,+ t2_XY, t2_YY, t2_1Y :: {-# UNPACK #-} !Scalar+ }+ deriving (Eq, Show)++instance Monoid Transform2 where+ mempty = Transform2 1 0 0 0 1 0++instance Semigroup Transform2 where+ a <> b =+ Transform2+ {+ t2_XX = t2_XX a * t2_XX b + t2_XY a * t2_YX b,+ t2_YX = t2_YX a * t2_XX b + t2_YY a * t2_YX b,+ t2_1X = t2_1X a * t2_XX b + t2_1Y a * t2_YX b + t2_1X b,++ t2_XY = t2_XX a * t2_XY b + t2_XY a * t2_YY b,+ t2_YY = t2_YX a * t2_XY b + t2_YY a * t2_YY b,+ t2_1Y = t2_1X a * t2_XY b + t2_1Y a * t2_YY b + t2_1Y b+ }++-- | Apply a 2D transformation to a 2D point, yielding a new 2D point.+transformP2 :: Transform2 -> Vector2 -> Vector2+transformP2 a (Vector2 x y) =+ Vector2+ {+ v2x = t2_XX a * x + t2_YX a * y + t2_1X a,+ v2y = t2_XY a * x + t2_YY a * y + t2_1Y a+ }
Data/Vector/Transform/T3.hs view
@@ -1,55 +1,58 @@-{- | - 3-dimensional linear transformations. --} - -module Data.Vector.Transform.T3 where - -import Data.Monoid - -import Data.Vector.Class -import Data.Vector.V3 - -{- | - The type of 3D linear transformations. - - Note the @Monoid@ instance, which gives you access to the identity transform (@mempty@) and the ability to combine a series of transforms into a single transform (@mappend@). --} -data Transform3 = - Transform3 - { - t3_XX, t3_YX, t3_ZX, t3_1X, - t3_XY, t3_YY, t3_ZY, t3_1Y, - t3_XZ, t3_YZ, t3_ZZ, t3_1Z :: {-# UNPACK #-} !Scalar - } - deriving (Eq, Show) - -instance Monoid Transform3 where - mempty = Transform3 1 0 0 0 0 1 0 0 0 0 1 0 - mappend a b = - Transform3 - { - t3_XX = t3_XX a * t3_XX b + t3_XY a * t3_YX b + t3_XZ a * t3_ZX b, - t3_YX = t3_YX a * t3_XX b + t3_YY a * t3_YX b + t3_YZ a * t3_ZX b, - t3_ZX = t3_ZX a * t3_XX b + t3_ZY a * t3_YX b + t3_ZZ a * t3_ZX b, - t3_1X = t3_1X a * t3_XX b + t3_1Y a * t3_YX b + t3_1Z a * t3_ZX b + t3_1X b, - - t3_XY = t3_XX a * t3_XY b + t3_XY a * t3_YY b + t3_XZ a * t3_ZY b, - t3_YY = t3_YX a * t3_XY b + t3_YY a * t3_YY b + t3_YZ a * t3_ZY b, - t3_ZY = t3_ZX a * t3_XY b + t3_ZY a * t3_YY b + t3_ZZ a * t3_ZY b, - t3_1Y = t3_1X a * t3_XY b + t3_1Y a * t3_YY b + t3_1Z a * t3_ZY b + t3_1Y b, - - t3_XZ = t3_XX a * t3_XZ b + t3_XY a * t3_YZ b + t3_XZ a * t3_ZZ b, - t3_YZ = t3_YX a * t3_XZ b + t3_YY a * t3_YZ b + t3_YZ a * t3_ZZ b, - t3_ZZ = t3_ZX a * t3_XZ b + t3_ZY a * t3_YZ b + t3_ZZ a * t3_ZZ b, - t3_1Z = t3_1X a * t3_XZ b + t3_1Y a * t3_YZ b + t3_1Z a * t3_ZZ b + t3_1Z b - } - --- | Apply a 3D transformation to a 3D point, yielding a new 3D point. -transformP3 :: Transform3 -> Vector3 -> Vector3 -transformP3 a (Vector3 x y z) = - Vector3 - { - v3x = t3_XX a * x + t3_YX a * y + t3_ZX a * z + t3_1X a, - v3y = t3_XY a * x + t3_YY a * y + t3_ZY a * z + t3_1Y a, - v3z = t3_XZ a * x + t3_YZ a * y + t3_ZZ a * z + t3_1Z a - } +{- |+ 3-dimensional linear transformations.+-}++module Data.Vector.Transform.T3 where++import Data.Semigroup+import Data.Monoid++import Data.Vector.Class+import Data.Vector.V3++{- |+ The type of 3D linear transformations.++ Note the @Monoid@ instance, which gives you access to the identity transform (@mempty@) and the ability to combine a series of transforms into a single transform (@mappend@).+-}+data Transform3 =+ Transform3+ {+ t3_XX, t3_YX, t3_ZX, t3_1X,+ t3_XY, t3_YY, t3_ZY, t3_1Y,+ t3_XZ, t3_YZ, t3_ZZ, t3_1Z :: {-# UNPACK #-} !Scalar+ }+ deriving (Eq, Show)++instance Monoid Transform3 where+ mempty = Transform3 1 0 0 0 0 1 0 0 0 0 1 0++instance Semigroup Transform3 where+ a <> b =+ Transform3+ {+ t3_XX = t3_XX a * t3_XX b + t3_XY a * t3_YX b + t3_XZ a * t3_ZX b,+ t3_YX = t3_YX a * t3_XX b + t3_YY a * t3_YX b + t3_YZ a * t3_ZX b,+ t3_ZX = t3_ZX a * t3_XX b + t3_ZY a * t3_YX b + t3_ZZ a * t3_ZX b,+ t3_1X = t3_1X a * t3_XX b + t3_1Y a * t3_YX b + t3_1Z a * t3_ZX b + t3_1X b,++ t3_XY = t3_XX a * t3_XY b + t3_XY a * t3_YY b + t3_XZ a * t3_ZY b,+ t3_YY = t3_YX a * t3_XY b + t3_YY a * t3_YY b + t3_YZ a * t3_ZY b,+ t3_ZY = t3_ZX a * t3_XY b + t3_ZY a * t3_YY b + t3_ZZ a * t3_ZY b,+ t3_1Y = t3_1X a * t3_XY b + t3_1Y a * t3_YY b + t3_1Z a * t3_ZY b + t3_1Y b,++ t3_XZ = t3_XX a * t3_XZ b + t3_XY a * t3_YZ b + t3_XZ a * t3_ZZ b,+ t3_YZ = t3_YX a * t3_XZ b + t3_YY a * t3_YZ b + t3_YZ a * t3_ZZ b,+ t3_ZZ = t3_ZX a * t3_XZ b + t3_ZY a * t3_YZ b + t3_ZZ a * t3_ZZ b,+ t3_1Z = t3_1X a * t3_XZ b + t3_1Y a * t3_YZ b + t3_1Z a * t3_ZZ b + t3_1Z b+ }++-- | Apply a 3D transformation to a 3D point, yielding a new 3D point.+transformP3 :: Transform3 -> Vector3 -> Vector3+transformP3 a (Vector3 x y z) =+ Vector3+ {+ v3x = t3_XX a * x + t3_YX a * y + t3_ZX a * z + t3_1X a,+ v3y = t3_XY a * x + t3_YY a * y + t3_ZY a * z + t3_1Y a,+ v3z = t3_XZ a * x + t3_YZ a * y + t3_ZZ a * z + t3_1Z a+ }
Data/Vector/Transform/T4.hs view
@@ -1,66 +1,69 @@-{- | - 4-dimensional linear transformations. --} - -module Data.Vector.Transform.T4 where - -import Data.Monoid - -import Data.Vector.Class -import Data.Vector.V4 - -{- | - The type of 4D linear transformations. - - Note the @Monoid@ instance, which gives you access to the identity transform (@mempty@) and the ability to combine a series of transforms into a single transform (@mappend@). --} -data Transform4 = - Transform4 - { - t4_XX, t4_YX, t4_ZX, t4_WX, t4_1X, - t4_XY, t4_YY, t4_ZY, t4_WY, t4_1Y, - t4_XZ, t4_YZ, t4_ZZ, t4_WZ, t4_1Z, - t4_XW, t4_YW, t4_ZW, t4_WW, t4_1W :: {-# UNPACK #-} !Scalar - } - deriving (Eq, Show) - -instance Monoid Transform4 where - mempty = Transform4 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 - mappend a b = - Transform4 - { - t4_XX = t4_XX a * t4_XX b + t4_XY a * t4_YX b + t4_XZ a * t4_ZX b + t4_XW a * t4_WX b, - t4_YX = t4_YX a * t4_XX b + t4_YY a * t4_YX b + t4_YZ a * t4_ZX b + t4_YW a * t4_WX b, - t4_ZX = t4_ZX a * t4_XX b + t4_ZY a * t4_YX b + t4_ZZ a * t4_ZX b + t4_ZW a * t4_WX b, - t4_WX = t4_WX a * t4_XX b + t4_WY a * t4_YX b + t4_WZ a * t4_ZX b + t4_WW a * t4_WX b, - t4_1X = t4_1X a * t4_XX b + t4_1Y a * t4_YX b + t4_1Z a * t4_ZX b + t4_1W a * t4_WX b + t4_1X b, - - t4_XY = t4_XX a * t4_XY b + t4_XY a * t4_YY b + t4_XZ a * t4_ZY b + t4_XW a * t4_WY b, - t4_YY = t4_YX a * t4_XY b + t4_YY a * t4_YY b + t4_YZ a * t4_ZY b + t4_YW a * t4_WY b, - t4_ZY = t4_ZX a * t4_XY b + t4_ZY a * t4_YY b + t4_ZZ a * t4_ZY b + t4_ZW a * t4_WY b, - t4_WY = t4_WX a * t4_XY b + t4_WY a * t4_YY b + t4_WZ a * t4_ZY b + t4_WW a * t4_WY b, - t4_1Y = t4_1X a * t4_XY b + t4_1Y a * t4_YY b + t4_1Z a * t4_ZY b + t4_1W a * t4_WY b + t4_1Y b, - - t4_XZ = t4_XX a * t4_XZ b + t4_XY a * t4_YZ b + t4_XZ a * t4_ZZ b + t4_XW a * t4_WZ b, - t4_YZ = t4_YX a * t4_XZ b + t4_YY a * t4_YZ b + t4_YZ a * t4_ZZ b + t4_YW a * t4_WZ b, - t4_ZZ = t4_ZX a * t4_XZ b + t4_ZY a * t4_YZ b + t4_ZZ a * t4_ZZ b + t4_ZW a * t4_WZ b, - t4_WZ = t4_WX a * t4_XZ b + t4_WY a * t4_YZ b + t4_WZ a * t4_ZZ b + t4_WW a * t4_WZ b, - t4_1Z = t4_1X a * t4_XZ b + t4_1Y a * t4_YZ b + t4_1Z a * t4_ZZ b + t4_1W a * t4_WZ b + t4_1Z b, - - t4_XW = t4_XX a * t4_XW b + t4_XY a * t4_YW b + t4_XZ a * t4_ZW b + t4_XW a * t4_WW b, - t4_YW = t4_YX a * t4_XW b + t4_YY a * t4_YW b + t4_YZ a * t4_ZW b + t4_YW a * t4_WW b, - t4_ZW = t4_ZX a * t4_XW b + t4_ZY a * t4_YW b + t4_ZZ a * t4_ZW b + t4_ZW a * t4_WW b, - t4_WW = t4_WX a * t4_XW b + t4_WY a * t4_YW b + t4_WZ a * t4_ZW b + t4_WW a * t4_WW b, - t4_1W = t4_1X a * t4_XW b + t4_1Y a * t4_YW b + t4_1Z a * t4_ZW b + t4_1W a * t4_WW b + t4_1W b - } - --- | Apply a 4D transformation to a 4D point, yielding a new 4D point. -transformP4 :: Transform4 -> Vector4 -> Vector4 -transformP4 a (Vector4 x y z w) = - Vector4 - { - v4x = t4_XX a * x + t4_YX a * y + t4_ZX a * z + t4_WX a * w + t4_1X a, - v4y = t4_XY a * x + t4_YY a * y + t4_ZY a * z + t4_WY a * w + t4_1Y a, - v4z = t4_XZ a * x + t4_YZ a * y + t4_ZZ a * z + t4_WZ a * w + t4_1Z a, - v4w = t4_XW a * x + t4_YW a * y + t4_ZW a * z + t4_WW a * w + t4_1W a - } +{- |+ 4-dimensional linear transformations.+-}++module Data.Vector.Transform.T4 where++import Data.Semigroup+import Data.Monoid++import Data.Vector.Class+import Data.Vector.V4++{- |+ The type of 4D linear transformations.++ Note the @Monoid@ instance, which gives you access to the identity transform (@mempty@) and the ability to combine a series of transforms into a single transform (@mappend@).+-}+data Transform4 =+ Transform4+ {+ t4_XX, t4_YX, t4_ZX, t4_WX, t4_1X,+ t4_XY, t4_YY, t4_ZY, t4_WY, t4_1Y,+ t4_XZ, t4_YZ, t4_ZZ, t4_WZ, t4_1Z,+ t4_XW, t4_YW, t4_ZW, t4_WW, t4_1W :: {-# UNPACK #-} !Scalar+ }+ deriving (Eq, Show)++instance Monoid Transform4 where+ mempty = Transform4 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0++instance Semigroup Transform4 where+ a <> b =+ Transform4+ {+ t4_XX = t4_XX a * t4_XX b + t4_XY a * t4_YX b + t4_XZ a * t4_ZX b + t4_XW a * t4_WX b,+ t4_YX = t4_YX a * t4_XX b + t4_YY a * t4_YX b + t4_YZ a * t4_ZX b + t4_YW a * t4_WX b,+ t4_ZX = t4_ZX a * t4_XX b + t4_ZY a * t4_YX b + t4_ZZ a * t4_ZX b + t4_ZW a * t4_WX b,+ t4_WX = t4_WX a * t4_XX b + t4_WY a * t4_YX b + t4_WZ a * t4_ZX b + t4_WW a * t4_WX b,+ t4_1X = t4_1X a * t4_XX b + t4_1Y a * t4_YX b + t4_1Z a * t4_ZX b + t4_1W a * t4_WX b + t4_1X b,++ t4_XY = t4_XX a * t4_XY b + t4_XY a * t4_YY b + t4_XZ a * t4_ZY b + t4_XW a * t4_WY b,+ t4_YY = t4_YX a * t4_XY b + t4_YY a * t4_YY b + t4_YZ a * t4_ZY b + t4_YW a * t4_WY b,+ t4_ZY = t4_ZX a * t4_XY b + t4_ZY a * t4_YY b + t4_ZZ a * t4_ZY b + t4_ZW a * t4_WY b,+ t4_WY = t4_WX a * t4_XY b + t4_WY a * t4_YY b + t4_WZ a * t4_ZY b + t4_WW a * t4_WY b,+ t4_1Y = t4_1X a * t4_XY b + t4_1Y a * t4_YY b + t4_1Z a * t4_ZY b + t4_1W a * t4_WY b + t4_1Y b,++ t4_XZ = t4_XX a * t4_XZ b + t4_XY a * t4_YZ b + t4_XZ a * t4_ZZ b + t4_XW a * t4_WZ b,+ t4_YZ = t4_YX a * t4_XZ b + t4_YY a * t4_YZ b + t4_YZ a * t4_ZZ b + t4_YW a * t4_WZ b,+ t4_ZZ = t4_ZX a * t4_XZ b + t4_ZY a * t4_YZ b + t4_ZZ a * t4_ZZ b + t4_ZW a * t4_WZ b,+ t4_WZ = t4_WX a * t4_XZ b + t4_WY a * t4_YZ b + t4_WZ a * t4_ZZ b + t4_WW a * t4_WZ b,+ t4_1Z = t4_1X a * t4_XZ b + t4_1Y a * t4_YZ b + t4_1Z a * t4_ZZ b + t4_1W a * t4_WZ b + t4_1Z b,++ t4_XW = t4_XX a * t4_XW b + t4_XY a * t4_YW b + t4_XZ a * t4_ZW b + t4_XW a * t4_WW b,+ t4_YW = t4_YX a * t4_XW b + t4_YY a * t4_YW b + t4_YZ a * t4_ZW b + t4_YW a * t4_WW b,+ t4_ZW = t4_ZX a * t4_XW b + t4_ZY a * t4_YW b + t4_ZZ a * t4_ZW b + t4_ZW a * t4_WW b,+ t4_WW = t4_WX a * t4_XW b + t4_WY a * t4_YW b + t4_WZ a * t4_ZW b + t4_WW a * t4_WW b,+ t4_1W = t4_1X a * t4_XW b + t4_1Y a * t4_YW b + t4_1Z a * t4_ZW b + t4_1W a * t4_WW b + t4_1W b+ }++-- | Apply a 4D transformation to a 4D point, yielding a new 4D point.+transformP4 :: Transform4 -> Vector4 -> Vector4+transformP4 a (Vector4 x y z w) =+ Vector4+ {+ v4x = t4_XX a * x + t4_YX a * y + t4_ZX a * z + t4_WX a * w + t4_1X a,+ v4y = t4_XY a * x + t4_YY a * y + t4_ZY a * z + t4_WY a * w + t4_1Y a,+ v4z = t4_XZ a * x + t4_YZ a * y + t4_ZZ a * z + t4_WZ a * w + t4_1Z a,+ v4w = t4_XW a * x + t4_YW a * y + t4_ZW a * z + t4_WW a * w + t4_1W a+ }
Data/Vector/V1.hs view
@@ -1,32 +1,32 @@-{- | - 1-dimensional vectors with vector arithmetic. - - This isn't especially useful. Usually if you want to calculate with scalars, you can just use the 'Scalar' type directly. However, this module provides a 'Vector1' newtype over 'Scalar' that allows a scalar to be treated as a sort of vector, which is very occasionally useful. --} - -{-# LANGUAGE GeneralizedNewtypeDeriving #-} - -module Data.Vector.V1 where - -import Data.Vector.Class - -{- | - The type of 1D vectors. - - Owing to its particularly simple structure, this type has more class instances than \'propper\' vectors have. Still, for the most part you'll probably want to just use 'Scalar' itself directly. --} -newtype Vector1 = Vector1 {v1x :: Scalar} deriving (Eq, Ord, Enum, Show, Num, Fractional) - -instance BasicVector Vector1 where - vmap f (Vector1 x ) = Vector1 (f x) - vzip f (Vector1 x1) (Vector1 x2) = Vector1 (f x1 x2) - vfold _ (Vector1 x ) = x - - vpack (x:_) = Just $ Vector1 x - vpack _ = Nothing - - vunpack (Vector1 x) = [x] - - vpromote x = Vector1 x - -instance Vector Vector1 where +{- |+ 1-dimensional vectors with vector arithmetic.++ This isn't especially useful. Usually if you want to calculate with scalars, you can just use the 'Scalar' type directly. However, this module provides a 'Vector1' newtype over 'Scalar' that allows a scalar to be treated as a sort of vector, which is very occasionally useful.+-}++{-# LANGUAGE GeneralizedNewtypeDeriving #-}++module Data.Vector.V1 where++import Data.Vector.Class++{- |+ The type of 1D vectors.++ Owing to its particularly simple structure, this type has more class instances than \'propper\' vectors have. Still, for the most part you'll probably want to just use 'Scalar' itself directly.+-}+newtype Vector1 = Vector1 {v1x :: Scalar} deriving (Eq, Ord, Enum, Show, Num, Fractional)++instance BasicVector Vector1 where+ vmap f (Vector1 x ) = Vector1 (f x)+ vzip f (Vector1 x1) (Vector1 x2) = Vector1 (f x1 x2)+ vfold _ (Vector1 x ) = x++ vpack (x:_) = Just $ Vector1 x+ vpack _ = Nothing++ vunpack (Vector1 x) = [x]++ vpromote x = Vector1 x++instance Vector Vector1 where
Data/Vector/V2.hs view
@@ -1,36 +1,36 @@-{- | - 2-dimensional vectors with vector arithmetic. --} - -module Data.Vector.V2 where - -import Data.Vector.Class - -data Vector2 = Vector2 {v2x, v2y :: {-# UNPACK #-} !Scalar} deriving (Eq, Show) - -instance BasicVector Vector2 where - vmap f (Vector2 x y ) = Vector2 (f x) (f y) - vzip f (Vector2 x1 y1) (Vector2 x2 y2) = Vector2 (f x1 x2) (f y1 y2) - vfold f (Vector2 x y ) = f x y - - vpack (x:y:_) = Just $ Vector2 x y - vpack _ = Nothing - - vunpack (Vector2 x y) = [x,y] - - vpromote x = Vector2 x x - -instance Num Vector2 where - (+) = vzip (+) - (-) = vzip (-) - (*) = vzip (*) - abs = vmap abs - signum = vmap signum - fromInteger = vpromote . fromInteger - -instance Fractional Vector2 where - (/) = vzip (/) - recip = vmap recip - fromRational = vpromote . fromRational - -instance Vector Vector2 where +{- |+ 2-dimensional vectors with vector arithmetic.+-}++module Data.Vector.V2 where++import Data.Vector.Class++data Vector2 = Vector2 {v2x, v2y :: {-# UNPACK #-} !Scalar} deriving (Eq, Show)++instance BasicVector Vector2 where+ vmap f (Vector2 x y ) = Vector2 (f x) (f y)+ vzip f (Vector2 x1 y1) (Vector2 x2 y2) = Vector2 (f x1 x2) (f y1 y2)+ vfold f (Vector2 x y ) = f x y++ vpack (x:y:_) = Just $ Vector2 x y+ vpack _ = Nothing++ vunpack (Vector2 x y) = [x,y]++ vpromote x = Vector2 x x++instance Num Vector2 where+ (+) = vzip (+)+ (-) = vzip (-)+ (*) = vzip (*)+ abs = vmap abs+ signum = vmap signum+ fromInteger = vpromote . fromInteger++instance Fractional Vector2 where+ (/) = vzip (/)+ recip = vmap recip+ fromRational = vpromote . fromRational++instance Vector Vector2 where
Data/Vector/V3.hs view
@@ -1,50 +1,50 @@-{- | - 3-dimensional vectors with vector arithmetic. --} - -module Data.Vector.V3 where - -import Data.Vector.Class - -data Vector3 = Vector3 {v3x, v3y, v3z :: {-# UNPACK #-} !Scalar} deriving (Eq, Show) - -instance BasicVector Vector3 where - vmap f (Vector3 x y z ) = Vector3 (f x) (f y) (f z) - vzip f (Vector3 x1 y1 z1) (Vector3 x2 y2 z2) = Vector3 (f x1 x2) (f y1 y2) (f z1 z2) - vfold f (Vector3 x y z ) = f x (f y z) - - vpack (x:y:z:_) = Just $ Vector3 x y z - vpack _ = Nothing - - vunpack (Vector3 x y z) = [x,y,z] - - vpromote x = Vector3 x x x - -instance Num Vector3 where - (+) = vzip (+) - (-) = vzip (-) - (*) = vzip (*) - abs = vmap abs - signum = vmap signum - fromInteger = vpromote . fromInteger - -instance Fractional Vector3 where - (/) = vzip (/) - recip = vmap recip - fromRational = vpromote . fromRational - -instance Vector Vector3 where - -{- | - Take the /cross product/ of two 3D vectors. This produces a new 3D vector that is perpendicular to the plane of the first two vectors, and who's length is equal to the sine of the angle between those vectors multiplied by their lengths. - - Note that @a \`vcross\` b = negate (b \`vcross\` a)@. --} -vcross :: Vector3 -> Vector3 -> Vector3 -vcross (Vector3 x1 y1 z1) (Vector3 x2 y2 z2) = - Vector3 - { - v3x = y1 * z2 - y2 * z1, - v3y = z1 * x2 - z2 * x1, - v3z = x1 * y2 - x2 * y1 - } +{- |+ 3-dimensional vectors with vector arithmetic.+-}++module Data.Vector.V3 where++import Data.Vector.Class++data Vector3 = Vector3 {v3x, v3y, v3z :: {-# UNPACK #-} !Scalar} deriving (Eq, Show)++instance BasicVector Vector3 where+ vmap f (Vector3 x y z ) = Vector3 (f x) (f y) (f z)+ vzip f (Vector3 x1 y1 z1) (Vector3 x2 y2 z2) = Vector3 (f x1 x2) (f y1 y2) (f z1 z2)+ vfold f (Vector3 x y z ) = f x (f y z)++ vpack (x:y:z:_) = Just $ Vector3 x y z+ vpack _ = Nothing++ vunpack (Vector3 x y z) = [x,y,z]++ vpromote x = Vector3 x x x++instance Num Vector3 where+ (+) = vzip (+)+ (-) = vzip (-)+ (*) = vzip (*)+ abs = vmap abs+ signum = vmap signum+ fromInteger = vpromote . fromInteger++instance Fractional Vector3 where+ (/) = vzip (/)+ recip = vmap recip+ fromRational = vpromote . fromRational++instance Vector Vector3 where++{- |+ Take the /cross product/ of two 3D vectors. This produces a new 3D vector that is perpendicular to the plane of the first two vectors, and who's length is equal to the sine of the angle between those vectors multiplied by their lengths.++ Note that @a \`vcross\` b = negate (b \`vcross\` a)@.+-}+vcross :: Vector3 -> Vector3 -> Vector3+vcross (Vector3 x1 y1 z1) (Vector3 x2 y2 z2) =+ Vector3+ {+ v3x = y1 * z2 - y2 * z1,+ v3y = z1 * x2 - z2 * x1,+ v3z = x1 * y2 - x2 * y1+ }
Data/Vector/V4.hs view
@@ -1,36 +1,36 @@-{- | - 4-dimensional vectors with vector arithmetic. --} - -module Data.Vector.V4 where - -import Data.Vector.Class - -data Vector4 = Vector4 {v4x, v4y, v4z, v4w :: {-# UNPACK #-} !Scalar} deriving (Eq, Show) - -instance BasicVector Vector4 where - vmap f (Vector4 x y z w ) = Vector4 (f x) (f y) (f z) (f w) - vzip f (Vector4 x1 y1 z1 w1) (Vector4 x2 y2 z2 w2) = Vector4 (f x1 x2) (f y1 y2) (f z1 z2) (f w1 w2) - vfold f (Vector4 x y z w ) = f (f x y) (f z w) - - vpack (x:y:z:w:_) = Just $ Vector4 x y z w - vpack _ = Nothing - - vunpack (Vector4 x y z w) = [x,y,z,w] - - vpromote x = Vector4 x x x x - -instance Num Vector4 where - (+) = vzip (+) - (-) = vzip (-) - (*) = vzip (*) - abs = vmap abs - signum = vmap signum - fromInteger = vpromote . fromInteger - -instance Fractional Vector4 where - (/) = vzip (/) - recip = vmap recip - fromRational = vpromote . fromRational - -instance Vector Vector4 where +{- |+ 4-dimensional vectors with vector arithmetic.+-}++module Data.Vector.V4 where++import Data.Vector.Class++data Vector4 = Vector4 {v4x, v4y, v4z, v4w :: {-# UNPACK #-} !Scalar} deriving (Eq, Show)++instance BasicVector Vector4 where+ vmap f (Vector4 x y z w ) = Vector4 (f x) (f y) (f z) (f w)+ vzip f (Vector4 x1 y1 z1 w1) (Vector4 x2 y2 z2 w2) = Vector4 (f x1 x2) (f y1 y2) (f z1 z2) (f w1 w2)+ vfold f (Vector4 x y z w ) = f (f x y) (f z w)++ vpack (x:y:z:w:_) = Just $ Vector4 x y z w+ vpack _ = Nothing++ vunpack (Vector4 x y z w) = [x,y,z,w]++ vpromote x = Vector4 x x x x++instance Num Vector4 where+ (+) = vzip (+)+ (-) = vzip (-)+ (*) = vzip (*)+ abs = vmap abs+ signum = vmap signum+ fromInteger = vpromote . fromInteger++instance Fractional Vector4 where+ (/) = vzip (/)+ recip = vmap recip+ fromRational = vpromote . fromRational++instance Vector Vector4 where
License.txt view
@@ -1,10 +1,10 @@-Copyright (c) 2009, Andrew Coppin -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Andrew Coppin nor the names of the contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +Copyright (c) 2009, Andrew Coppin+All rights reserved.++Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.+ * Neither the name of Andrew Coppin nor the names of the contributors may be used to endorse or promote products derived from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Setup.hs view
@@ -1,2 +1,2 @@-import Distribution.Simple -main = defaultMain +import Distribution.Simple+main = defaultMain