0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-10 09:08:31 -05:00

Improve matrix transformation helpers.

This commit is contained in:
Andrey Antukh 2016-12-20 17:03:40 +01:00
parent 5acb699955
commit aed1b8cd26
No known key found for this signature in database
GPG key ID: 4DFEBCB8316A8B95

View file

@ -44,63 +44,7 @@
(let [[a b c d tx ty] v]
(Matrix. a b c d tx ty))))
(defn ^boolean matrix?
"Return true if `v` is Matrix instance."
[v]
(instance? Matrix v))
(defn matrix
"Create a new matrix instance."
([]
(Matrix. 1 0 0 1 0 0))
([v]
(-matrix v))
([a b c d tx ty]
(Matrix. a b c d tx ty)))
(defn rotate
"Apply rotation transformation to the matrix."
([m angle]
(let [center (gpt/point 0 0)]
(rotate m angle center)))
([m angle center]
(let [angle (mth/radians angle)
x (:x center)
y (:y center)
cos (mth/cos angle)
sin (mth/sin angle)
nsin (- sin)
tx (- x (+ (* x cos)) (* y sin))
ty (- y (- (* x sin)) (* y cos))
a (+ (* cos (:a m)) (* sin (:b m)))
b (+ (* nsin (:a m)) (* cos (:b m)))
c (+ (* cos (:c m)) (* sin (:d m)))
d (+ (* nsin (:c m)) (* cos (:d m)))
tx' (+ (:tx m) (* tx (:a m)) (* ty (:b m)))
ty' (+ (:ty m) (* tx (:c m)) (* ty (:d m)))]
(Matrix. a b c d tx' ty'))))
(defn scale
"Apply scale transformation to the matrix."
([m v] (scale m v v))
([m x y]
(assoc m
:a (* (:a m) x)
:c (* (:c m) x)
:b (* (:b m) y)
:d (* (:d m) y))))
(defn translate
"Apply translate transformation to the matrix."
([m pt]
(let [pt (gpt/-point pt)]
(assoc m
:tx (+ (:tx m) (* (:x pt) (:a m)) (* (:y pt) (:b m)))
:ty (+ (:ty m) (* (:x pt) (:c m)) (* (:y pt) (:d m))))))
([m x y]
(translate m (gpt/point x y))))
(defn append
(defn multiply
([m om]
(let [a1 (:a m)
b1 (:b m)
@ -122,7 +66,101 @@
(+ tx1 (* tx2 a1) (* ty2 b1))
(+ ty1 (* tx2 c1) (* ty2 d1)))))
([m om & others]
(reduce append (append m om) others)))
(reduce multiply (multiply m om) others)))
(defn ^boolean matrix?
"Return true if `v` is Matrix instance."
[v]
(instance? Matrix v))
(defn matrix
"Create a new matrix instance."
([]
(Matrix. 1 0 0 1 0 0))
([v]
(-matrix v))
([a b c d tx ty]
(Matrix. a b c d tx ty)))
(defn translate-matrix
([pt]
(let [pt (gpt/-point pt)]
(Matrix. 1 0 0 1 (:x pt) (:y pt))))
([x y]
(translate-matrix (gpt/point x y))))
(defn scale-matrix
([s]
(Matrix. s 0 0 s 0 0))
([sx sy]
(Matrix. sx 0 0 sy 0 0)))
(defn rotate-matrix
[a]
(let [a (mth/radians a)]
(Matrix. (mth/cos a)
(mth/sin a)
(- (mth/sin a))
(mth/cos a)
0 0)))
(defn rotate
"Apply rotation transformation to the matrix."
([m angle]
(multiply m (rotate-matrix angle)))
([m angle center]
(multiply m
(translate-matrix center)
(rotate-matrix angle)
(translate-matrix (gpt/negate center)))))
;; ([m angle]
;; (let [center (gpt/point 0 0)]
;; (rotate m angle center)))
;; ([m angle center]
;; (let [angle (mth/radians angle)
;; x (:x center)
;; y (:y center)
;; cos (mth/cos angle)
;; sin (mth/sin angle)
;; nsin (- sin)
;; tx (- x (+ (* x cos)) (* y sin))
;; ty (- y (- (* x sin)) (* y cos))
;; a (+ (* cos (:a m)) (* sin (:b m)))
;; b (+ (* nsin (:a m)) (* cos (:b m)))
;; c (+ (* cos (:c m)) (* sin (:d m)))
;; d (+ (* nsin (:c m)) (* cos (:d m)))
;; tx' (+ (:tx m) (* tx (:a m)) (* ty (:b m)))
;; ty' (+ (:ty m) (* tx (:c m)) (* ty (:d m)))]
;; (Matrix. a b c d tx' ty'))))
(defn scale
"Apply scale transformation to the matrix."
([m v] (scale m v v))
([m vx vy] (multiply m (scale-matrix vx vy))))
;; ([m v] (scale m v v))
;; ([m x y]
;; (assoc m
;; :a (* (:a m) x)
;; :c (* (:c m) x)
;; :b (* (:b m) y)
;; :d (* (:d m) y))))
(defn translate
"Apply translate transformation to the matrix."
([m pt]
(multiply m (translate-matrix pt)))
([m x y]
(translate m (gpt/point x y))))
;; ([m pt]
;; (let [pt (gpt/-point pt)]
;; (assoc m
;; :tx (+ (:tx m) (* (:x pt) (:a m)) (* (:y pt) (:b m)))
;; :ty (+ (:ty m) (* (:x pt) (:c m)) (* (:y pt) (:d m))))))
;; ([m x y]
;; (translate m (gpt/point x y))))
(defn ^boolean invertible?
[{:keys [a b c d tx ty] :as m}]