mirror of
https://github.com/penpot/penpot.git
synced 2025-04-08 21:11:22 -05:00
⚡ Performance improvements.
This commit is contained in:
parent
3ab5e11d5f
commit
76e19a4b41
9 changed files with 134 additions and 349 deletions
|
@ -434,10 +434,10 @@
|
|||
(defn shapes->rect-shape
|
||||
[shapes]
|
||||
(let [shapes (mapv shape->rect-shape shapes)
|
||||
minx (apply js/Math.min (mapv :x1 shapes))
|
||||
miny (apply js/Math.min (mapv :y1 shapes))
|
||||
maxx (apply js/Math.max (mapv :x2 shapes))
|
||||
maxy (apply js/Math.max (mapv :y2 shapes))]
|
||||
minx (transduce (map :x1) min shapes)
|
||||
miny (transduce (map :y1) min shapes)
|
||||
maxx (transduce (map :x2) max shapes)
|
||||
maxy (transduce (map :y2) max shapes)]
|
||||
{:x1 minx
|
||||
:y1 miny
|
||||
:x2 maxx
|
||||
|
@ -509,10 +509,10 @@
|
|||
|
||||
(defn- transform-rect
|
||||
[{:keys [x y width height] :as shape} mx]
|
||||
(let [tl (gpt/transform [x y] mx)
|
||||
tr (gpt/transform [(+ x width) y] mx)
|
||||
bl (gpt/transform [x (+ y height)] mx)
|
||||
br (gpt/transform [(+ x width) (+ y height)] mx)
|
||||
(let [tl (gpt/transform (gpt/point x y) mx)
|
||||
tr (gpt/transform (gpt/point (+ x width) y) mx)
|
||||
bl (gpt/transform (gpt/point x (+ y height)) mx)
|
||||
br (gpt/transform (gpt/point (+ x width) (+ y height)) mx)
|
||||
;; TODO: replace apply with transduce (performance)
|
||||
minx (apply min (map :x [tl tr bl br]))
|
||||
maxx (apply max (map :x [tl tr bl br]))
|
||||
|
@ -527,10 +527,10 @@
|
|||
(defn- transform-circle
|
||||
[{:keys [cx cy rx ry] :as shape} xfmt]
|
||||
(let [{:keys [x1 y1 x2 y2]} (shape->rect-shape shape)
|
||||
tl (gpt/transform [x1 y1] xfmt)
|
||||
tr (gpt/transform [x2 y1] xfmt)
|
||||
bl (gpt/transform [x1 y2] xfmt)
|
||||
br (gpt/transform [x2 y2] xfmt)
|
||||
tl (gpt/transform (gpt/point x1 y1) xfmt)
|
||||
tr (gpt/transform (gpt/point x2 y1) xfmt)
|
||||
bl (gpt/transform (gpt/point x1 y2) xfmt)
|
||||
br (gpt/transform (gpt/point x2 y2) xfmt)
|
||||
|
||||
;; TODO: replace apply with transduce (performance)
|
||||
x (apply min (map :x [tl tr bl br]))
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
[current]
|
||||
(->> (rx/concat (rx/of current)
|
||||
(rx/sample 10 mouse-position))
|
||||
(rx/map #(gpt/divide % @refs/selected-zoom))
|
||||
(rx/map #(gpt/divide % (gpt/point @refs/selected-zoom)))
|
||||
(rx/mapcat (fn [point]
|
||||
(if @refs/selected-alignment
|
||||
(uwrk/align-point point)
|
||||
|
|
|
@ -135,7 +135,7 @@
|
|||
|
||||
mouse (->> ms/mouse-position
|
||||
(rx/mapcat #(conditional-align % align?))
|
||||
(rx/map #(gpt/divide % zoom)))]
|
||||
(rx/map #(gpt/divide % (gpt/point zoom))))]
|
||||
(rx/concat
|
||||
(->> mouse
|
||||
(rx/take 1)
|
||||
|
@ -179,14 +179,14 @@
|
|||
(let [{:keys [zoom flags]} (:workspace-local state)
|
||||
|
||||
align? (refs/alignment-activated? flags)
|
||||
last-point (volatile! (gpt/divide @ms/mouse-position zoom))
|
||||
last-point (volatile! (gpt/divide @ms/mouse-position (gpt/point zoom)))
|
||||
|
||||
stoper (->> (rx/filter stoper-event? stream)
|
||||
(rx/share))
|
||||
|
||||
mouse (->> (rx/sample 10 ms/mouse-position)
|
||||
(rx/mapcat #(conditional-align % align?))
|
||||
(rx/map #(gpt/divide % zoom)))
|
||||
(rx/map #(gpt/divide % (gpt/point zoom))))
|
||||
|
||||
points (->> stream
|
||||
(rx/filter ms/mouse-click?)
|
||||
|
@ -255,7 +255,7 @@
|
|||
stoper (rx/filter stoper-event? stream)
|
||||
mouse (->> (rx/sample 10 ms/mouse-position)
|
||||
(rx/mapcat #(conditional-align % align?))
|
||||
(rx/map #(gpt/divide % zoom)))]
|
||||
(rx/map #(gpt/divide % (gpt/point zoom))))]
|
||||
(rx/concat
|
||||
(rx/of initialize-drawing)
|
||||
(->> mouse
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
(defn- apply-zoom
|
||||
[point]
|
||||
(gpt/divide point @refs/selected-zoom))
|
||||
(gpt/divide point (gpt/point @refs/selected-zoom)))
|
||||
|
||||
;; --- Resize & Rotate
|
||||
|
||||
|
@ -115,8 +115,8 @@
|
|||
:style {:fillOpacity "1"
|
||||
:strokeWidth "2px"
|
||||
:vectorEffect "non-scaling-stroke"}
|
||||
:fill "rgba(49,239,184,.7)"
|
||||
:stroke "#31EFB8"
|
||||
:fill "rgba(49,239,184,.7)"
|
||||
:stroke "#31EFB8"
|
||||
:cx cx
|
||||
:cy cy}])
|
||||
|
||||
|
@ -232,7 +232,6 @@
|
|||
|
||||
;; TODO: add specs for clarity
|
||||
|
||||
|
||||
(mf/defc text-edition-selection-handlers
|
||||
[{:keys [shape zoom] :as props}]
|
||||
(let [{:keys [x y width height] :as shape} shape]
|
||||
|
@ -257,7 +256,6 @@
|
|||
|
||||
(mf/defc single-selection-handlers
|
||||
[{:keys [shape zoom] :as props}]
|
||||
(prn "single-selection-handlers" shape)
|
||||
(let [on-resize #(do (dom/stop-propagation %2)
|
||||
(st/emit! (start-resize %1 #{(:id shape)} shape)))
|
||||
on-rotate #(do (dom/stop-propagation %)
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
(mf/defc coordinates
|
||||
[{:keys [zoom] :as props}]
|
||||
(let [coords (some-> (use-rxsub ms/mouse-position)
|
||||
(gpt/divide zoom)
|
||||
(gpt/divide (gpt/point zoom zoom))
|
||||
(gpt/round 0))]
|
||||
[:ul.coordinates
|
||||
[:span {:alt "x"}
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) 2015-2016 Andrey Antukh <niwi@niwi.nz>
|
||||
;; Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||
;; This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
;; defined by the Mozilla Public License, v. 2.0.
|
||||
;;
|
||||
;; Copyright (c) 2015-2020 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.util.geom.matrix
|
||||
(:require [cuerdas.core :as str]
|
||||
|
@ -13,50 +15,21 @@
|
|||
|
||||
;; --- Matrix Impl
|
||||
|
||||
(defrecord Matrix [a b c d e f])
|
||||
|
||||
(defprotocol ICoerce
|
||||
"Matrix coersion protocol."
|
||||
(-matrix [v] "Return a matrix instance."))
|
||||
|
||||
(extend-type Matrix
|
||||
cljs.core/IDeref
|
||||
(-deref [v]
|
||||
(mapv #(get v %) [:a :b :c :d :e :f]))
|
||||
|
||||
(defrecord Matrix [a b c d e f]
|
||||
Object
|
||||
(toString [v]
|
||||
(->> (str/join "," @v)
|
||||
(str/format "matrix(%s)"))))
|
||||
|
||||
(extend-protocol ICoerce
|
||||
nil
|
||||
(-matrix [_]
|
||||
(Matrix. 1 0 0 1 0 0))
|
||||
|
||||
Matrix
|
||||
(-matrix [v] v)
|
||||
|
||||
cljs.core/PersistentVector
|
||||
(-matrix [v]
|
||||
(let [[a b c d e f] v]
|
||||
(Matrix. a b c d e f)))
|
||||
|
||||
cljs.core/IndexedSeq
|
||||
(-matrix [v]
|
||||
(let [[a b c d e f] v]
|
||||
(Matrix. a b c d e f))))
|
||||
(toString [_]
|
||||
(str "matrix(" a "," b "," c "," d "," e "," f ")")))
|
||||
|
||||
(defn multiply
|
||||
([m1 m2]
|
||||
([{m1a :a m1b :b m1c :c m1d :d m1e :e m1f :f :as m1}
|
||||
{m2a :a m2b :b m2c :c m2d :d m2e :e m2f :f :as m2}]
|
||||
(Matrix.
|
||||
(+ (* (:a m1) (:a m2)) (* (:c m1) (:b m2)))
|
||||
(+ (* (:b m1) (:a m2)) (* (:d m1) (:b m2)))
|
||||
(+ (* (:a m1) (:c m2)) (* (:c m1) (:d m2)))
|
||||
(+ (* (:b m1) (:c m2)) (* (:d m1) (:d m2)))
|
||||
(+ (* (:a m1) (:e m2)) (* (:c m1) (:f m2)) (:e m1))
|
||||
(+ (* (:b m1) (:e m2)) (* (:d m1) (:f m2)) (:f m1))))
|
||||
|
||||
(+ (* m1a m2a) (* m1c m2b))
|
||||
(+ (* m1b m2a) (* m1d m2b))
|
||||
(+ (* m1a m2c) (* m1c m2d))
|
||||
(+ (* m1b m2c) (* m1d m2d))
|
||||
(+ (* m1a m2e) (* m1c m2f) m1e)
|
||||
(+ (* m1b m2e) (* m1d m2f) m1f)))
|
||||
([m1 m2 & others]
|
||||
(reduce multiply (multiply m1 m2) others)))
|
||||
|
||||
|
@ -69,100 +42,28 @@
|
|||
"Create a new matrix instance."
|
||||
([]
|
||||
(Matrix. 1 0 0 1 0 0))
|
||||
([v]
|
||||
(-matrix v))
|
||||
([a b c d e f]
|
||||
(Matrix. a b c d e f)))
|
||||
|
||||
(defn translate-matrix
|
||||
[pt]
|
||||
(let [pt (gpt/point pt)]
|
||||
(Matrix. 1 0 0 1 (:x pt) (:y pt))))
|
||||
[{x :x y :y :as pt}]
|
||||
(assert (gpt/point? pt))
|
||||
(Matrix. 1 0 0 1 x y))
|
||||
|
||||
(defn scale-matrix
|
||||
[s]
|
||||
(let [pt (gpt/point s)]
|
||||
(Matrix. (:x pt) 0 0 (:y pt) 0 0)))
|
||||
[{x :x y :y :as pt}]
|
||||
(assert (gpt/point? pt))
|
||||
(Matrix. x 0 0 y 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)))
|
||||
|
||||
;; OLD
|
||||
;; (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)))))
|
||||
|
||||
;; -- ROTATE
|
||||
;; r = radians(r)
|
||||
;; const cos = Math.cos(r)
|
||||
;; const sin = Math.sin(r)
|
||||
;;
|
||||
;; const { a, b, c, d, e, f } = this
|
||||
;;
|
||||
;; this.a = a * cos - b * sin
|
||||
;; this.b = b * cos + a * sin
|
||||
;; this.c = c * cos - d * sin
|
||||
;; this.d = d * cos + c * sin
|
||||
;; this.e = e * cos - f * sin + cy * sin - cx * cos + cx
|
||||
;; this.f = f * cos + e * sin - cx * sin - cy * cos + cy
|
||||
|
||||
;; (defn rotate
|
||||
;; ([m angle] (rotate m angle (gpt/point 0 0)))
|
||||
;; ([m angle center]
|
||||
;; (let [{:keys [a b c d e f]} m
|
||||
;; {cx :x cy :y} center
|
||||
;; r (mth/radians angle)
|
||||
;; cos (mth/cos r)
|
||||
;; sin (mth/sin r)
|
||||
;; a' (- (* a cos) (* b sin))
|
||||
;; b' (+ (* b cos) (* a sin))
|
||||
;; c' (- (* c cos) (* d sin))
|
||||
;; d' (+ (* d cos) (* c sin))
|
||||
;; e' (+ (- (* e cos) (* f sin))
|
||||
;; (- (* cy sin) (* cx cos))
|
||||
;; cx)
|
||||
;; f' (+ (- (+ (* f cos) (* e sin))
|
||||
;; (* cx sin)
|
||||
;; (* cy cos))
|
||||
;; cy)]
|
||||
;; (Matrix. a' b' c' d' e' f'))))
|
||||
|
||||
|
||||
;; export function rotate (angle, cx, cy) {
|
||||
;; const cosAngle = cos(angle)
|
||||
;; const sinAngle = sin(angle)
|
||||
;; const rotationMatrix = {
|
||||
;; a: cosAngle,
|
||||
;; c: -sinAngle,
|
||||
;; e: 0,
|
||||
;; b: sinAngle,
|
||||
;; d: cosAngle,
|
||||
;; f: 0
|
||||
;; }
|
||||
;; if (isUndefined(cx) || isUndefined(cy)) {
|
||||
;; return rotationMatrix
|
||||
;; }
|
||||
|
||||
;; return transform([
|
||||
;; translate(cx, cy),
|
||||
;; rotationMatrix,
|
||||
;; translate(-cx, -cy)
|
||||
;; ])
|
||||
;; }
|
||||
(Matrix. (mth/cos a)
|
||||
(mth/sin a)
|
||||
(- (mth/sin a))
|
||||
(mth/cos a)
|
||||
0
|
||||
0)))
|
||||
|
||||
(defn rotate
|
||||
"Apply rotation transformation to the matrix."
|
||||
|
@ -177,85 +78,19 @@
|
|||
;; TODO: temporal backward compatibility
|
||||
(def rotate* rotate)
|
||||
|
||||
;; ([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))))
|
||||
|
||||
|
||||
|
||||
;; scaleO (x, y = x, cx = 0, cy = 0) {
|
||||
;; // Support uniform scaling
|
||||
;; if (arguments.length === 3) {
|
||||
;; cy = cx
|
||||
;; cx = y
|
||||
;; y = x
|
||||
;; }
|
||||
|
||||
;; const { a, b, c, d, e, f } = this
|
||||
|
||||
;; this.a = a * x
|
||||
;; this.b = b * y
|
||||
;; this.c = c * x
|
||||
;; this.d = d * y
|
||||
;; this.e = e * x - cx * x + cx
|
||||
;; this.f = f * y - cy * y + cy
|
||||
|
||||
;; return this
|
||||
;; }
|
||||
|
||||
;; (defn scale
|
||||
;; "Apply scale transformation to the matrix."
|
||||
;; ([m x] (scale m x x))
|
||||
;; ([m x y]
|
||||
;; (let [{:keys [a b c d e f]} m
|
||||
;; cx 0
|
||||
;; cy 0
|
||||
;; a' (* a x)
|
||||
;; b' (* b y)
|
||||
;; c' (* c x)
|
||||
;; d' (* d y)
|
||||
;; e' (+ cx (- (* e x)
|
||||
;; (* cx x)))
|
||||
;; f' (+ cy (- (* f y)
|
||||
;; (* cy y)))]
|
||||
;; (Matrix. a' b' c' d' e f))))
|
||||
|
||||
(defn scale
|
||||
"Apply scale transformation to the matrix."
|
||||
([m s] (multiply m (scale-matrix s)))
|
||||
([m s c]
|
||||
([m scale] (multiply m (scale-matrix scale)))
|
||||
([m scale center]
|
||||
(multiply m
|
||||
(translate-matrix c)
|
||||
(scale-matrix s)
|
||||
(translate-matrix (gpt/negate c)))))
|
||||
(translate-matrix center)
|
||||
(scale-matrix scale)
|
||||
(translate-matrix (gpt/negate center)))))
|
||||
|
||||
(defn translate
|
||||
"Apply translate transformation to the matrix."
|
||||
[m pt]
|
||||
(let [pt (gpt/point pt)]
|
||||
(multiply m (translate-matrix pt))))
|
||||
|
||||
(defn ^boolean invertible?
|
||||
[{:keys [a b c d e f] :as m}]
|
||||
(let [det (- (* a d) (* c b))]
|
||||
(and (not (mth/nan? det))
|
||||
(mth/finite? e)
|
||||
(mth/finite? f))))
|
||||
|
||||
(defn invert
|
||||
[{:keys [a b c d e f] :as m}]
|
||||
(when (invertible? m)
|
||||
(let [det (- (* a d) (* c b))]
|
||||
(Matrix. (/ d det)
|
||||
(/ (- b) det)
|
||||
(/ (- c) det)
|
||||
(/ a det)
|
||||
(/ (- (* c f) (* d e)) det)
|
||||
(/ (- (* b e) (* a f)) det)))))
|
||||
(multiply m (translate-matrix pt)))
|
||||
|
||||
;; --- Transit Adapter
|
||||
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
;; defined by the Mozilla Public License, v. 2.0.
|
||||
;;
|
||||
;; Copyright (c) 2016-2017 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.util.geom.path
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) 2015-2017 Andrey Antukh <niwi@niwi.nz>
|
||||
;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||
;; This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
;; defined by the Mozilla Public License, v. 2.0.
|
||||
;;
|
||||
;; Copyright (c) 2015-2020 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.util.geom.point
|
||||
(:refer-clojure :exclude [divide])
|
||||
|
@ -27,13 +29,6 @@
|
|||
(point? v)
|
||||
v
|
||||
|
||||
(or (vector? v)
|
||||
(seq? v))
|
||||
(Point. (first v) (second v))
|
||||
|
||||
(map? v)
|
||||
(Point. (:x v) (:y v))
|
||||
|
||||
(number? v)
|
||||
(Point. v v)
|
||||
|
||||
|
@ -41,105 +36,87 @@
|
|||
(throw (ex-info "Invalid arguments" {:v v}))))
|
||||
([x y] (Point. x y)))
|
||||
|
||||
(defn rotate
|
||||
"Apply rotation transformation to the point."
|
||||
[p angle]
|
||||
{:pre [(point? p)]}
|
||||
(let [angle (mth/radians angle)
|
||||
sin (mth/sin angle)
|
||||
cos (mth/cos angle)]
|
||||
(Point.
|
||||
(-> (- (* (:x p) cos) (* (:y p) sin))
|
||||
(mth/precision 6))
|
||||
(-> (+ (* (:x p) sin) (* (:y p) cos))
|
||||
(mth/precision 6)))))
|
||||
|
||||
(defn add
|
||||
"Returns the addition of the supplied value to both
|
||||
coordinates of the point as a new point."
|
||||
[p other]
|
||||
{:pre [(point? p)]}
|
||||
(let [other (point other)]
|
||||
(Point. (+ (:x p) (:x other))
|
||||
(+ (:y p) (:y other)))))
|
||||
[{x :x y :y :as p} {ox :x oy :y :as other}]
|
||||
(assert (point? p))
|
||||
(assert (point? other))
|
||||
(Point. (+ x ox) (+ y oy)))
|
||||
|
||||
(defn subtract
|
||||
"Returns the subtraction of the supplied value to both
|
||||
coordinates of the point as a new point."
|
||||
[p other]
|
||||
{:pre [(point? p)]}
|
||||
(let [other (point other)]
|
||||
(Point. (- (:x p) (:x other))
|
||||
(- (:y p) (:y other)))))
|
||||
|
||||
[{x :x y :y :as p} {ox :x oy :y :as other}]
|
||||
(assert (point? p))
|
||||
(assert (point? other))
|
||||
(Point. (- x ox) (- y oy)))
|
||||
|
||||
(defn multiply
|
||||
"Returns the subtraction of the supplied value to both
|
||||
coordinates of the point as a new point."
|
||||
[p other]
|
||||
{:pre [(point? p)]}
|
||||
(let [other (point other)]
|
||||
(Point. (* (:x p) (:x other))
|
||||
(* (:y p) (:y other)))))
|
||||
[{x :x y :y :as p} {ox :x oy :y :as other}]
|
||||
(assert (point? p))
|
||||
(assert (point? other))
|
||||
(Point. (* x ox) (* y oy)))
|
||||
|
||||
(defn divide
|
||||
[p other]
|
||||
{:pre [(point? p)]}
|
||||
(let [other (point other)]
|
||||
(Point. (/ (:x p) (:x other))
|
||||
(/ (:y p) (:y other)))))
|
||||
[{x :x y :y :as p} {ox :x oy :y :as other}]
|
||||
(assert (point? p))
|
||||
(assert (point? other))
|
||||
(Point. (/ x ox) (/ y oy)))
|
||||
|
||||
(defn negate
|
||||
[p]
|
||||
{:pre [(point? p)]}
|
||||
(let [{:keys [x y]} (point p)]
|
||||
(Point. (- x) (- y))))
|
||||
[{x :x y :y :as p}]
|
||||
(assert (point? p))
|
||||
(Point. (- x) (- y)))
|
||||
|
||||
(defn distance
|
||||
"Calculate the distance between two points."
|
||||
[p other]
|
||||
(let [other (point other)
|
||||
dx (- (:x p) (:x other))
|
||||
dy (- (:y p) (:y other))]
|
||||
[{x :x y :y :as p} {ox :x oy :y :as other}]
|
||||
(assert (point? p))
|
||||
(assert (point? other))
|
||||
(let [dx (- x ox)
|
||||
dy (- y oy)]
|
||||
(-> (mth/sqrt (+ (mth/pow dx 2)
|
||||
(mth/pow dy 2)))
|
||||
(mth/precision 6))))
|
||||
|
||||
(defn length
|
||||
[p]
|
||||
{:pre [(point? p)]}
|
||||
(mth/sqrt (+ (mth/pow (:x p) 2)
|
||||
(mth/pow (:y p) 2))))
|
||||
[{x :x y :y :as p}]
|
||||
(assert (point? p))
|
||||
(mth/sqrt (+ (mth/pow x 2)
|
||||
(mth/pow y 2))))
|
||||
|
||||
(defn angle
|
||||
"Returns the smaller angle between two vectors.
|
||||
If the second vector is not provided, the angle
|
||||
will be measured from x-axis."
|
||||
([p]
|
||||
(-> (mth/atan2 (:y p) (:x p))
|
||||
([{x :x y :y :as p}]
|
||||
(-> (mth/atan2 y x)
|
||||
(mth/degrees)))
|
||||
([p center]
|
||||
(let [center (point center)]
|
||||
(angle (subtract p center)))))
|
||||
(angle (subtract p center))))
|
||||
|
||||
(defn angle-with-other
|
||||
"Consider point as vector and calculate
|
||||
the angle between two vectors."
|
||||
[p other]
|
||||
{:pre [(point? p)]}
|
||||
(let [other (point other)
|
||||
a (/ (+ (* (:x p) (:x other))
|
||||
(* (:y p) (:y other)))
|
||||
(* (length p) (length other)))
|
||||
a (mth/acos (if (< a -1)
|
||||
-1
|
||||
(if (> a 1) 1 a)))]
|
||||
[{x :x y :y :as p} {ox :x oy :y :as other}]
|
||||
(assert (point? p))
|
||||
(assert (point? other))
|
||||
(let [a (/ (+ (* x ox)
|
||||
(* y oy))
|
||||
(* (length p)
|
||||
(length other)))
|
||||
a (mth/acos (if (< a -1) -1 (if (> a 1) 1 a)))]
|
||||
(-> (mth/degrees a)
|
||||
(mth/precision 6))))
|
||||
|
||||
(defn update-angle
|
||||
"Update the angle of the point."
|
||||
[p angle]
|
||||
(assert (point? p))
|
||||
(assert (number? angle))
|
||||
(let [len (length p)
|
||||
angle (mth/radians angle)]
|
||||
(Point. (* (mth/cos angle) len)
|
||||
|
@ -148,24 +125,25 @@
|
|||
(defn quadrant
|
||||
"Return the quadrant of the angle of the point."
|
||||
[{:keys [x y] :as p}]
|
||||
{:pre [(point? p)]}
|
||||
(assert (point? p))
|
||||
(if (>= x 0)
|
||||
(if (>= y 0) 1 4)
|
||||
(if (>= y 0) 2 3)))
|
||||
|
||||
(defn round
|
||||
"Change the precision of the point coordinates."
|
||||
[{:keys [x y]} decimanls]
|
||||
[{:keys [x y] :as p} decimanls]
|
||||
(assert (point? p))
|
||||
(assert (number? decimanls))
|
||||
(Point. (mth/precision x decimanls)
|
||||
(mth/precision y decimanls)))
|
||||
|
||||
(defn transform
|
||||
"Transform a point applying a matrix transfomation."
|
||||
[pt {:keys [a b c d e f] :as m}]
|
||||
(let [{:keys [x y]} (point pt)]
|
||||
(Point. (+ (* x a) (* y c) e)
|
||||
(+ (* x b) (* y d) f))))
|
||||
|
||||
[{:keys [x y] :as p} {:keys [a b c d e f] :as m}]
|
||||
(assert (point? p))
|
||||
(Point. (+ (* x a) (* y c) e)
|
||||
(+ (* x b) (* y d) f)))
|
||||
|
||||
;; --- Transit Adapter
|
||||
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
(ns uxbox.tests.test-util-geom
|
||||
(:require [cljs.test :as t :include-macros true]
|
||||
[cljs.pprint :refer [pprint]]
|
||||
;; [uxbox.util.geom.point-impl :as gpt2]
|
||||
;; [uxbox.util.geom.matrix-impl :as gmt2]
|
||||
[uxbox.util.geom.point :as gpt]
|
||||
[uxbox.util.geom.matrix :as gmt]))
|
||||
|
||||
(t/deftest point-constructors-test
|
||||
(let [p (gpt/point 1 2)]
|
||||
(t/is (= (:x p) 1))
|
||||
(t/is (= (:y p) 2))
|
||||
(t/is (gpt/point? p)))
|
||||
(t/is (= (:y p) 2)))
|
||||
|
||||
(let [p (gpt/point 1)]
|
||||
(t/is (= (:x p) 1))
|
||||
|
@ -16,34 +17,27 @@
|
|||
|
||||
(let [p (gpt/point)]
|
||||
(t/is (= (:x p) 0))
|
||||
(t/is (= (:y p) 0)))
|
||||
(t/is (= (:y p) 0))))
|
||||
|
||||
(let [p (gpt/point [1 2])]
|
||||
(t/is (= (:x p) 1))
|
||||
(t/is (= (:y p) 2))))
|
||||
|
||||
(t/deftest point-rotate-test
|
||||
(let [p1 (gpt/point 10 0)
|
||||
p2 (gpt/rotate p1 90)]
|
||||
(t/is (= (:x p2) 0))
|
||||
(t/is (= (:y p2) 10))
|
||||
(t/is (gpt/point? p2))))
|
||||
;; (t/deftest point-rotate-test
|
||||
;; (let [p1 (gpt/point 10 0)
|
||||
;; p2 (gpt/rotate p1 90)]
|
||||
;; (t/is (= (:x p2) 0))
|
||||
;; (t/is (= (:y p2) 10))))
|
||||
|
||||
(t/deftest point-add-test
|
||||
(let [p1 (gpt/point 1 1)
|
||||
p2 (gpt/point 2 2)
|
||||
p3 (gpt/add p1 p2)]
|
||||
(t/is (= (:x p3) 3))
|
||||
(t/is (= (:y p3) 3))
|
||||
(t/is (gpt/point? p3))))
|
||||
(t/is (= (:y p3) 3))))
|
||||
|
||||
(t/deftest point-subtract-test
|
||||
(let [p1 (gpt/point 3 3)
|
||||
p2 (gpt/point 2 2)
|
||||
p3 (gpt/subtract p1 p2)]
|
||||
(t/is (= (:x p3) 1))
|
||||
(t/is (= (:y p3) 1))
|
||||
(t/is (gpt/point? p3))))
|
||||
(t/is (= (:y p3) 1))))
|
||||
|
||||
(t/deftest point-distance-test
|
||||
(let [p1 (gpt/point 0 0)
|
||||
|
@ -69,46 +63,23 @@
|
|||
(t/is (number? angle))
|
||||
(t/is (= angle 45))))
|
||||
|
||||
(t/deftest point-quadrant-test
|
||||
(let [p1 (gpt/point 10 10)
|
||||
p2 (gpt/point -10 10)
|
||||
p3 (gpt/point -10 -10)
|
||||
p4 (gpt/point 10 -10)]
|
||||
|
||||
(t/is (= 1 (gpt/quadrant p1)))
|
||||
(t/is (= 2 (gpt/quadrant p2)))
|
||||
(t/is (= 3 (gpt/quadrant p3)))
|
||||
(t/is (= 4 (gpt/quadrant p4)))))
|
||||
|
||||
|
||||
(t/deftest matrix-constructors-test
|
||||
(let [m (gmt/matrix)]
|
||||
(t/is (= @m [1 0 0 1 0 0]))
|
||||
(t/is (gmt/matrix? m)))
|
||||
(t/is (= (str m) "matrix(1,0,0,1,0,0)")))
|
||||
(let [m (gmt/matrix 1 1 1 2 2 2)]
|
||||
(t/is (= @m [1 1 1 2 2 2]))
|
||||
(t/is (gmt/matrix? m)))
|
||||
(let [m (gmt/matrix [1 1 1 2 2 2])]
|
||||
(t/is (= @m [1 1 1 2 2 2]))
|
||||
(t/is (gmt/matrix? m))))
|
||||
(t/is (= (str m) "matrix(1,1,1,2,2,2)"))))
|
||||
|
||||
(t/deftest matrix-translate-test
|
||||
(let [m (-> (gmt/matrix)
|
||||
(gmt/translate (gpt/point 2 10)))]
|
||||
(t/is (str m) "matrix(1,0,0,1,2,10)")))
|
||||
|
||||
(t/deftest matrix-scale-test
|
||||
(let [m (-> (gmt/matrix)
|
||||
(gmt/scale (gpt/point 2)))]
|
||||
(t/is (str m) "matrix(2,0,0,2,0,0)")))
|
||||
|
||||
(t/deftest matrix-rotate-test
|
||||
(let [m (-> (gmt/matrix)
|
||||
(gmt/rotate 10))]
|
||||
|
||||
(t/is (= @m [0.984807753012208
|
||||
0.17364817766693033
|
||||
-0.17364817766693033
|
||||
0.984807753012208
|
||||
0 0]))))
|
||||
|
||||
(t/deftest matrix-scale-test
|
||||
(let [m (-> (gmt/matrix)
|
||||
(gmt/scale 2))]
|
||||
(t/is (= @m [2 0 0 2 0 0]))))
|
||||
|
||||
(t/deftest matrix-translate-test
|
||||
(let [m (-> (gmt/matrix)
|
||||
(gmt/translate 2 10))]
|
||||
(t/is (= @m [1 0 0 1 2 10]))))
|
||||
|
||||
(t/is (str m) "matrix(0.984807753012208,0.17364817766693033,-0.17364817766693033,0.984807753012208,0,0)")))
|
||||
|
|
Loading…
Add table
Reference in a new issue