{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ViewPatterns #-}
{-# OPTIONS_GHC -fno-warn-unused-imports #-}
module Diagrams.ThreeD.Transform
( T3
, aboutX, aboutY, aboutZ
, rotationAbout, rotateAbout
, pointAt, pointAt'
, scalingX, scalingY, scalingZ
, scaleX, scaleY, scaleZ
, scaling, scale
, translationX, translateX
, translationY, translateY
, translationZ, translateZ
, translation, translate
, reflectionX, reflectX
, reflectionY, reflectY
, reflectionZ, reflectZ
, reflectionAcross, reflectAcross
) where
import Diagrams.Core
import Diagrams.Core.Transform
import Diagrams.Angle
import Diagrams.Direction
import Diagrams.Points
import Diagrams.ThreeD.Types
import Diagrams.Transform
import Control.Lens (view, (&), (*~), (.~), (//~))
import Data.Semigroup
import Diagrams.TwoD.Transform
import Linear.Affine
import Linear.Metric
import Linear.V3 (cross)
import Linear.Vector
aboutZ :: Floating n => Angle n -> Transformation V3 n
aboutZ :: Angle n -> Transformation V3 n
aboutZ (Getting n (Angle n) n -> Angle n -> n
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting n (Angle n) n
forall n. Iso' (Angle n) n
rad -> n
a) = (V3 n :-: V3 n) -> Transformation V3 n
forall (v :: * -> *) n.
(Additive v, Num n) =>
(v n :-: v n) -> Transformation v n
fromOrthogonal V3 n :-: V3 n
r where
r :: V3 n :-: V3 n
r = n -> V3 n -> V3 n
forall a. Floating a => a -> V3 a -> V3 a
rot n
a (V3 n -> V3 n) -> (V3 n -> V3 n) -> V3 n :-: V3 n
forall u v. (u -> v) -> (v -> u) -> u :-: v
<-> n -> V3 n -> V3 n
forall a. Floating a => a -> V3 a -> V3 a
rot (-n
a)
rot :: a -> V3 a -> V3 a
rot a
θ (V3 a
x a
y a
z) = a -> a -> a -> V3 a
forall a. a -> a -> a -> V3 a
V3 (a -> a
forall a. Floating a => a -> a
cos a
θ a -> a -> a
forall a. Num a => a -> a -> a
* a
x a -> a -> a
forall a. Num a => a -> a -> a
- a -> a
forall a. Floating a => a -> a
sin a
θ a -> a -> a
forall a. Num a => a -> a -> a
* a
y)
(a -> a
forall a. Floating a => a -> a
sin a
θ a -> a -> a
forall a. Num a => a -> a -> a
* a
x a -> a -> a
forall a. Num a => a -> a -> a
+ a -> a
forall a. Floating a => a -> a
cos a
θ a -> a -> a
forall a. Num a => a -> a -> a
* a
y)
a
z
aboutX :: Floating n => Angle n -> Transformation V3 n
aboutX :: Angle n -> Transformation V3 n
aboutX (Getting n (Angle n) n -> Angle n -> n
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting n (Angle n) n
forall n. Iso' (Angle n) n
rad -> n
a) = (V3 n :-: V3 n) -> Transformation V3 n
forall (v :: * -> *) n.
(Additive v, Num n) =>
(v n :-: v n) -> Transformation v n
fromOrthogonal V3 n :-: V3 n
r where
r :: V3 n :-: V3 n
r = n -> V3 n -> V3 n
forall a. Floating a => a -> V3 a -> V3 a
rot n
a (V3 n -> V3 n) -> (V3 n -> V3 n) -> V3 n :-: V3 n
forall u v. (u -> v) -> (v -> u) -> u :-: v
<-> n -> V3 n -> V3 n
forall a. Floating a => a -> V3 a -> V3 a
rot (-n
a)
rot :: a -> V3 a -> V3 a
rot a
θ (V3 a
x a
y a
z) = a -> a -> a -> V3 a
forall a. a -> a -> a -> V3 a
V3 a
x
(a -> a
forall a. Floating a => a -> a
cos a
θ a -> a -> a
forall a. Num a => a -> a -> a
* a
y a -> a -> a
forall a. Num a => a -> a -> a
- a -> a
forall a. Floating a => a -> a
sin a
θ a -> a -> a
forall a. Num a => a -> a -> a
* a
z)
(a -> a
forall a. Floating a => a -> a
sin a
θ a -> a -> a
forall a. Num a => a -> a -> a
* a
y a -> a -> a
forall a. Num a => a -> a -> a
+ a -> a
forall a. Floating a => a -> a
cos a
θ a -> a -> a
forall a. Num a => a -> a -> a
* a
z)
aboutY :: Floating n => Angle n -> Transformation V3 n
aboutY :: Angle n -> Transformation V3 n
aboutY (Getting n (Angle n) n -> Angle n -> n
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting n (Angle n) n
forall n. Iso' (Angle n) n
rad -> n
a) = (V3 n :-: V3 n) -> Transformation V3 n
forall (v :: * -> *) n.
(Additive v, Num n) =>
(v n :-: v n) -> Transformation v n
fromOrthogonal V3 n :-: V3 n
r where
r :: V3 n :-: V3 n
r = n -> V3 n -> V3 n
forall a. Floating a => a -> V3 a -> V3 a
rot n
a (V3 n -> V3 n) -> (V3 n -> V3 n) -> V3 n :-: V3 n
forall u v. (u -> v) -> (v -> u) -> u :-: v
<-> n -> V3 n -> V3 n
forall a. Floating a => a -> V3 a -> V3 a
rot (-n
a)
rot :: a -> V3 a -> V3 a
rot a
θ (V3 a
x a
y a
z) = a -> a -> a -> V3 a
forall a. a -> a -> a -> V3 a
V3 (a -> a
forall a. Floating a => a -> a
cos a
θ a -> a -> a
forall a. Num a => a -> a -> a
* a
x a -> a -> a
forall a. Num a => a -> a -> a
+ a -> a
forall a. Floating a => a -> a
sin a
θ a -> a -> a
forall a. Num a => a -> a -> a
* a
z)
a
y
(-a -> a
forall a. Floating a => a -> a
sin a
θ a -> a -> a
forall a. Num a => a -> a -> a
* a
x a -> a -> a
forall a. Num a => a -> a -> a
+ a -> a
forall a. Floating a => a -> a
cos a
θ a -> a -> a
forall a. Num a => a -> a -> a
* a
z)
rotationAbout
:: Floating n
=> Point V3 n
-> Direction V3 n
-> Angle n
-> Transformation V3 n
rotationAbout :: Point V3 n -> Direction V3 n -> Angle n -> Transformation V3 n
rotationAbout (P V3 n
t) Direction V3 n
d (Getting n (Angle n) n -> Angle n -> n
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting n (Angle n) n
forall n. Iso' (Angle n) n
rad -> n
a)
= [Transformation V3 n] -> Transformation V3 n
forall a. Monoid a => [a] -> a
mconcat [V3 n -> Transformation V3 n
forall (v :: * -> *) n. v n -> Transformation v n
translation (V3 n -> V3 n
forall (f :: * -> *) a. (Functor f, Num a) => f a -> f a
negated V3 n
t),
(V3 n :-: V3 n) -> Transformation V3 n
forall (v :: * -> *) n.
(Additive v, Num n) =>
(v n :-: v n) -> Transformation v n
fromOrthogonal V3 n :-: V3 n
r,
V3 n -> Transformation V3 n
forall (v :: * -> *) n. v n -> Transformation v n
translation V3 n
t] where
r :: V3 n :-: V3 n
r = n -> V3 n -> V3 n
rot n
a (V3 n -> V3 n) -> (V3 n -> V3 n) -> V3 n :-: V3 n
forall u v. (u -> v) -> (v -> u) -> u :-: v
<-> n -> V3 n -> V3 n
rot (-n
a)
w :: V3 n
w = Direction V3 n -> V3 n
forall (v :: * -> *) n.
(Metric v, Floating n) =>
Direction v n -> v n
fromDirection Direction V3 n
d
rot :: n -> V3 n -> V3 n
rot n
θ V3 n
v = V3 n
v V3 n -> n -> V3 n
forall (f :: * -> *) a. (Functor f, Num a) => f a -> a -> f a
^* n -> n
forall a. Floating a => a -> a
cos n
θ
V3 n -> V3 n -> V3 n
forall (f :: * -> *) a. (Additive f, Num a) => f a -> f a -> f a
^+^ V3 n -> V3 n -> V3 n
forall a. Num a => V3 a -> V3 a -> V3 a
cross V3 n
w V3 n
v V3 n -> n -> V3 n
forall (f :: * -> *) a. (Functor f, Num a) => f a -> a -> f a
^* n -> n
forall a. Floating a => a -> a
sin n
θ
V3 n -> V3 n -> V3 n
forall (f :: * -> *) a. (Additive f, Num a) => f a -> f a -> f a
^+^ V3 n
w V3 n -> n -> V3 n
forall (f :: * -> *) a. (Functor f, Num a) => f a -> a -> f a
^* ((V3 n
w V3 n -> V3 n -> n
forall (f :: * -> *) a. (Metric f, Num a) => f a -> f a -> a
`dot` V3 n
v) n -> n -> n
forall a. Num a => a -> a -> a
* (n
1 n -> n -> n
forall a. Num a => a -> a -> a
- n -> n
forall a. Floating a => a -> a
cos n
θ))
rotateAbout
:: (InSpace V3 n t, Floating n, Transformable t)
=> Point V3 n
-> Direction V3 n
-> Angle n
-> t -> t
rotateAbout :: Point V3 n -> Direction V3 n -> Angle n -> t -> t
rotateAbout Point V3 n
p Direction V3 n
d Angle n
theta = Transformation (V t) (N t) -> t -> t
forall t. Transformable t => Transformation (V t) (N t) -> t -> t
transform (Point V3 n -> Direction V3 n -> Angle n -> Transformation V3 n
forall n.
Floating n =>
Point V3 n -> Direction V3 n -> Angle n -> Transformation V3 n
rotationAbout Point V3 n
p Direction V3 n
d Angle n
theta)
pointAt :: (Floating n, Ord n)
=> Direction V3 n -> Direction V3 n -> Direction V3 n
-> Transformation V3 n
pointAt :: Direction V3 n
-> Direction V3 n -> Direction V3 n -> Transformation V3 n
pointAt Direction V3 n
a Direction V3 n
i Direction V3 n
f = V3 n -> V3 n -> V3 n -> Transformation V3 n
forall n.
(Floating n, Ord n) =>
V3 n -> V3 n -> V3 n -> Transformation V3 n
pointAt' (Direction V3 n -> V3 n
forall (v :: * -> *) n.
(Metric v, Floating n) =>
Direction v n -> v n
fromDirection Direction V3 n
a) (Direction V3 n -> V3 n
forall (v :: * -> *) n.
(Metric v, Floating n) =>
Direction v n -> v n
fromDirection Direction V3 n
i) (Direction V3 n -> V3 n
forall (v :: * -> *) n.
(Metric v, Floating n) =>
Direction v n -> v n
fromDirection Direction V3 n
f)
pointAt' :: (Floating n, Ord n) => V3 n -> V3 n -> V3 n -> Transformation V3 n
pointAt' :: V3 n -> V3 n -> V3 n -> Transformation V3 n
pointAt' V3 n
about V3 n
initial V3 n
final = V3 n -> V3 n -> V3 n -> Transformation V3 n
forall n.
(Floating n, Ord n) =>
V3 n -> V3 n -> V3 n -> Transformation V3 n
pointAtUnit (V3 n -> V3 n
forall (f :: * -> *) a. (Metric f, Floating a) => f a -> f a
signorm V3 n
about) (V3 n -> V3 n
forall (f :: * -> *) a. (Metric f, Floating a) => f a -> f a
signorm V3 n
initial) (V3 n -> V3 n
forall (f :: * -> *) a. (Metric f, Floating a) => f a -> f a
signorm V3 n
final)
pointAtUnit :: (Floating n, Ord n) => V3 n -> V3 n -> V3 n -> Transformation V3 n
pointAtUnit :: V3 n -> V3 n -> V3 n -> Transformation V3 n
pointAtUnit V3 n
about V3 n
initial V3 n
final = Transformation V3 n
tilt Transformation V3 n -> Transformation V3 n -> Transformation V3 n
forall a. Semigroup a => a -> a -> a
<> Transformation V3 n
pan where
signedAngle :: V3 n -> V3 n -> V3 n -> Angle n
signedAngle V3 n
rel V3 n
u V3 n
v = n -> n
forall a. Num a => a -> a
signum (V3 n -> V3 n -> V3 n
forall a. Num a => V3 a -> V3 a -> V3 a
cross V3 n
u V3 n
v V3 n -> V3 n -> n
forall (f :: * -> *) a. (Metric f, Num a) => f a -> f a -> a
`dot` V3 n
rel) n -> Angle n -> Angle n
forall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ V3 n -> V3 n -> Angle n
forall (v :: * -> *) n.
(Metric v, Floating n, Ord n) =>
v n -> v n -> Angle n
angleBetween V3 n
u V3 n
v
inPanPlaneF :: V3 n
inPanPlaneF = V3 n
final V3 n -> V3 n -> V3 n
forall (f :: * -> *) a. (Additive f, Num a) => f a -> f a -> f a
^-^ V3 n -> V3 n -> V3 n
forall (v :: * -> *) a.
(Metric v, Fractional a) =>
v a -> v a -> v a
project V3 n
about V3 n
final
inPanPlaneI :: V3 n
inPanPlaneI = V3 n
initial V3 n -> V3 n -> V3 n
forall (f :: * -> *) a. (Additive f, Num a) => f a -> f a -> f a
^-^ V3 n -> V3 n -> V3 n
forall (v :: * -> *) a.
(Metric v, Fractional a) =>
v a -> v a -> v a
project V3 n
about V3 n
initial
panAngle :: Angle n
panAngle = V3 n -> V3 n -> V3 n -> Angle n
forall n. (Floating n, Ord n) => V3 n -> V3 n -> V3 n -> Angle n
signedAngle V3 n
about V3 n
inPanPlaneI V3 n
inPanPlaneF
pan :: Transformation V3 n
pan = Point V3 n -> Direction V3 n -> Angle n -> Transformation V3 n
forall n.
Floating n =>
Point V3 n -> Direction V3 n -> Angle n -> Transformation V3 n
rotationAbout Point V3 n
forall (f :: * -> *) a. (Additive f, Num a) => Point f a
origin (V3 n -> Direction V3 n
forall (v :: * -> *) n. v n -> Direction v n
direction V3 n
about) Angle n
panAngle
tiltAngle :: Angle n
tiltAngle = V3 n -> V3 n -> V3 n -> Angle n
forall n. (Floating n, Ord n) => V3 n -> V3 n -> V3 n -> Angle n
signedAngle V3 n
tiltAxis (Transformation (V (V3 n)) (N (V3 n)) -> V3 n -> V3 n
forall t. Transformable t => Transformation (V t) (N t) -> t -> t
transform Transformation (V (V3 n)) (N (V3 n))
Transformation V3 n
pan V3 n
initial) V3 n
final
tiltAxis :: V3 n
tiltAxis = V3 n -> V3 n -> V3 n
forall a. Num a => V3 a -> V3 a -> V3 a
cross V3 n
final V3 n
about
tilt :: Transformation V3 n
tilt = Point V3 n -> Direction V3 n -> Angle n -> Transformation V3 n
forall n.
Floating n =>
Point V3 n -> Direction V3 n -> Angle n -> Transformation V3 n
rotationAbout Point V3 n
forall (f :: * -> *) a. (Additive f, Num a) => Point f a
origin (V3 n -> Direction V3 n
forall (v :: * -> *) n. v n -> Direction v n
direction V3 n
tiltAxis) Angle n
tiltAngle
scalingZ :: (Additive v, R3 v, Fractional n) => n -> Transformation v n
scalingZ :: n -> Transformation v n
scalingZ n
c = (v n :-: v n) -> Transformation v n
forall (v :: * -> *) n.
(Additive v, Num n) =>
(v n :-: v n) -> Transformation v n
fromSymmetric ((v n :-: v n) -> Transformation v n)
-> (v n :-: v n) -> Transformation v n
forall a b. (a -> b) -> a -> b
$ ((n -> Identity n) -> v n -> Identity (v n)
forall (t :: * -> *) a. R3 t => Lens' (t a) a
_z ((n -> Identity n) -> v n -> Identity (v n)) -> n -> v n -> v n
forall a s t. Num a => ASetter s t a a -> a -> s -> t
*~ n
c) (v n -> v n) -> (v n -> v n) -> v n :-: v n
forall u v. (u -> v) -> (v -> u) -> u :-: v
<-> ((n -> Identity n) -> v n -> Identity (v n)
forall (t :: * -> *) a. R3 t => Lens' (t a) a
_z ((n -> Identity n) -> v n -> Identity (v n)) -> n -> v n -> v n
forall a s t. Fractional a => ASetter s t a a -> a -> s -> t
//~ n
c)
scaleZ :: (InSpace v n t, R3 v, Fractional n, Transformable t) => n -> t -> t
scaleZ :: n -> t -> t
scaleZ = Transformation v n -> t -> t
forall t. Transformable t => Transformation (V t) (N t) -> t -> t
transform (Transformation v n -> t -> t)
-> (n -> Transformation v n) -> n -> t -> t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. n -> Transformation v n
forall (v :: * -> *) n.
(Additive v, R3 v, Fractional n) =>
n -> Transformation v n
scalingZ
translationZ :: (Additive v, R3 v, Num n) => n -> Transformation v n
translationZ :: n -> Transformation v n
translationZ n
z = v n -> Transformation v n
forall (v :: * -> *) n. v n -> Transformation v n
translation (v n
forall (f :: * -> *) a. (Additive f, Num a) => f a
zero v n -> (v n -> v n) -> v n
forall a b. a -> (a -> b) -> b
& (n -> Identity n) -> v n -> Identity (v n)
forall (t :: * -> *) a. R3 t => Lens' (t a) a
_z ((n -> Identity n) -> v n -> Identity (v n)) -> n -> v n -> v n
forall s t a b. ASetter s t a b -> b -> s -> t
.~ n
z)
translateZ :: (InSpace v n t, R3 v, Transformable t) => n -> t -> t
translateZ :: n -> t -> t
translateZ = Transformation v n -> t -> t
forall t. Transformable t => Transformation (V t) (N t) -> t -> t
transform (Transformation v n -> t -> t)
-> (n -> Transformation v n) -> n -> t -> t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. n -> Transformation v n
forall (v :: * -> *) n.
(Additive v, R3 v, Num n) =>
n -> Transformation v n
translationZ
reflectionZ :: (Additive v, R3 v, Num n) => Transformation v n
reflectionZ :: Transformation v n
reflectionZ = (v n :-: v n) -> Transformation v n
forall (v :: * -> *) n.
(Additive v, Num n) =>
(v n :-: v n) -> Transformation v n
fromSymmetric ((v n :-: v n) -> Transformation v n)
-> (v n :-: v n) -> Transformation v n
forall a b. (a -> b) -> a -> b
$ ((n -> Identity n) -> v n -> Identity (v n)
forall (t :: * -> *) a. R3 t => Lens' (t a) a
_z ((n -> Identity n) -> v n -> Identity (v n)) -> n -> v n -> v n
forall a s t. Num a => ASetter s t a a -> a -> s -> t
*~ (-n
1)) (v n -> v n) -> (v n -> v n) -> v n :-: v n
forall u v. (u -> v) -> (v -> u) -> u :-: v
<-> ((n -> Identity n) -> v n -> Identity (v n)
forall (t :: * -> *) a. R3 t => Lens' (t a) a
_z ((n -> Identity n) -> v n -> Identity (v n)) -> n -> v n -> v n
forall a s t. Num a => ASetter s t a a -> a -> s -> t
*~ (-n
1))
reflectZ :: (InSpace v n t, R3 v, Transformable t) => t -> t
reflectZ :: t -> t
reflectZ = Transformation (V t) (N t) -> t -> t
forall t. Transformable t => Transformation (V t) (N t) -> t -> t
transform Transformation (V t) (N t)
forall (v :: * -> *) n.
(Additive v, R3 v, Num n) =>
Transformation v n
reflectionZ
reflectionAcross :: (Metric v, Fractional n)
=> Point v n -> v n -> Transformation v n
reflectionAcross :: Point v n -> v n -> Transformation v n
reflectionAcross Point v n
p v n
v =
Transformation v n -> Transformation v n -> Transformation v n
forall (v :: * -> *) n.
(Additive v, Num n) =>
Transformation v n -> Transformation v n -> Transformation v n
conjugate (v n -> Transformation v n
forall (v :: * -> *) n. v n -> Transformation v n
translation (Point v n
forall (f :: * -> *) a. (Additive f, Num a) => Point f a
origin Point v n -> Point v n -> Diff (Point v) n
forall (p :: * -> *) a. (Affine p, Num a) => p a -> p a -> Diff p a
.-. Point v n
p)) Transformation v n
reflect
where
reflect :: Transformation v n
reflect = (v n :-: v n) -> (v n :-: v n) -> Transformation v n
forall (v :: * -> *) n.
(Additive v, Num n) =>
(v n :-: v n) -> (v n :-: v n) -> Transformation v n
fromLinear v n :-: v n
t ((v n :-: v n) -> v n :-: v n
forall u v. (u :-: v) -> v :-: u
linv v n :-: v n
t)
t :: v n :-: v n
t = v n -> v n -> v n
forall (v :: * -> *) a.
(Metric v, Fractional a) =>
v a -> v a -> v a
f v n
v (v n -> v n) -> (v n -> v n) -> v n :-: v n
forall u v. (u -> v) -> (v -> u) -> u :-: v
<-> v n -> v n -> v n
forall (v :: * -> *) a.
(Metric v, Fractional a) =>
v a -> v a -> v a
f (v n -> v n
forall (f :: * -> *) a. (Functor f, Num a) => f a -> f a
negated v n
v)
f :: f a -> f a -> f a
f f a
u f a
w = f a
w f a -> f a -> f a
forall (f :: * -> *) a. (Additive f, Num a) => f a -> f a -> f a
^-^ a
2 a -> f a -> f a
forall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ f a -> f a -> f a
forall (v :: * -> *) a.
(Metric v, Fractional a) =>
v a -> v a -> v a
project f a
u f a
w
reflectAcross :: (InSpace v n t, Metric v, Fractional n, Transformable t)
=> Point v n -> v n -> t -> t
reflectAcross :: Point v n -> v n -> t -> t
reflectAcross Point v n
p v n
v = Transformation (V t) (N t) -> t -> t
forall t. Transformable t => Transformation (V t) (N t) -> t -> t
transform (Point v n -> v n -> Transformation v n
forall (v :: * -> *) n.
(Metric v, Fractional n) =>
Point v n -> v n -> Transformation v n
reflectionAcross Point v n
p v n
v)