mirror of
https://github.com/penpot/penpot.git
synced 2025-02-03 21:09:00 -05:00
🐛 Handle NaN on shape transformations.
This commit is contained in:
parent
271ba51951
commit
27b4e483f0
2 changed files with 23 additions and 13 deletions
|
@ -133,13 +133,16 @@
|
||||||
[{x :x y :y :as p} {ox :x oy :y :as other}]
|
[{x :x y :y :as p} {ox :x oy :y :as other}]
|
||||||
(assert (point? p))
|
(assert (point? p))
|
||||||
(assert (point? other))
|
(assert (point? other))
|
||||||
|
|
||||||
(let [a (/ (+ (* x ox)
|
(let [a (/ (+ (* x ox)
|
||||||
(* y oy))
|
(* y oy))
|
||||||
(* (length p)
|
(* (length p)
|
||||||
(length other)))
|
(length other)))
|
||||||
a (mth/acos (if (< a -1) -1 (if (> a 1) 1 a)))]
|
a (mth/acos (if (< a -1) -1 (if (> a 1) 1 a)))
|
||||||
(-> (mth/degrees a)
|
d (-> (mth/degrees a)
|
||||||
(mth/precision 6))))
|
(mth/precision 6))]
|
||||||
|
(if (mth/nan? d) 0 d)))
|
||||||
|
|
||||||
|
|
||||||
(defn update-angle
|
(defn update-angle
|
||||||
"Update the angle of the point."
|
"Update the angle of the point."
|
||||||
|
|
|
@ -558,7 +558,6 @@
|
||||||
(defn calculate-rec-path-height
|
(defn calculate-rec-path-height
|
||||||
"Calculates the height of a paralelogram given by the path"
|
"Calculates the height of a paralelogram given by the path"
|
||||||
[path-shape]
|
[path-shape]
|
||||||
|
|
||||||
(let [p1 (get-in path-shape [:segments 2])
|
(let [p1 (get-in path-shape [:segments 2])
|
||||||
p2 (get-in path-shape [:segments 3])
|
p2 (get-in path-shape [:segments 3])
|
||||||
p3 (get-in path-shape [:segments 4])
|
p3 (get-in path-shape [:segments 4])
|
||||||
|
@ -719,7 +718,9 @@
|
||||||
(let [;; Apply modifiers to the rect as a path so we have the end shape expected
|
(let [;; Apply modifiers to the rect as a path so we have the end shape expected
|
||||||
shape-path (transform-apply-modifiers shape)
|
shape-path (transform-apply-modifiers shape)
|
||||||
shape-center (center shape-path)
|
shape-center (center shape-path)
|
||||||
resize-vector (get-in shape [:modifiers :resize-vector] (gpt/point 1 1))
|
resize-vector (-> (get-in shape [:modifiers :resize-vector] (gpt/point 1 1))
|
||||||
|
(update :x #(if (zero? %) 1 %))
|
||||||
|
(update :y #(if (zero? %) 1 %)))
|
||||||
|
|
||||||
;; Reverse the current transformation stack to get the base rectangle
|
;; Reverse the current transformation stack to get the base rectangle
|
||||||
shape-path-temp (center-transform shape-path (:transform-inverse shape (gmt/matrix)))
|
shape-path-temp (center-transform shape-path (:transform-inverse shape (gmt/matrix)))
|
||||||
|
@ -729,6 +730,7 @@
|
||||||
;; This rectangle is the new data for the current rectangle. We want to change our rectangle
|
;; This rectangle is the new data for the current rectangle. We want to change our rectangle
|
||||||
;; to have this width, height, x, y
|
;; to have this width, height, x, y
|
||||||
rec (center->rect shape-center (:width shape-path-temp-dim) (:height shape-path-temp-dim))
|
rec (center->rect shape-center (:width shape-path-temp-dim) (:height shape-path-temp-dim))
|
||||||
|
rec (fix-invalid-rect-values rec)
|
||||||
rec-path (rect->path rec)
|
rec-path (rect->path rec)
|
||||||
|
|
||||||
;; The next matrix is a series of transformations we have to do to the previous rec so that
|
;; The next matrix is a series of transformations we have to do to the previous rec so that
|
||||||
|
@ -740,37 +742,42 @@
|
||||||
|
|
||||||
;; When one of the axis is flipped we have to reverse the skew
|
;; When one of the axis is flipped we have to reverse the skew
|
||||||
skew-angle (if (neg? (* (:x resize-vector) (:y resize-vector))) (- skew-angle) skew-angle )
|
skew-angle (if (neg? (* (:x resize-vector) (:y resize-vector))) (- skew-angle) skew-angle )
|
||||||
|
skew-angle (if (mth/nan? skew-angle) 0 skew-angle)
|
||||||
|
|
||||||
|
|
||||||
stretch-matrix (gmt/multiply stretch-matrix (gmt/skew-matrix skew-angle 0))
|
stretch-matrix (gmt/multiply stretch-matrix (gmt/skew-matrix skew-angle 0))
|
||||||
|
|
||||||
h1 (calculate-rec-path-height shape-path-temp)
|
h1 (calculate-rec-path-height shape-path-temp)
|
||||||
h2 (calculate-rec-path-height (center-transform rec-path stretch-matrix))
|
h2 (calculate-rec-path-height (center-transform rec-path stretch-matrix))
|
||||||
stretch-matrix (gmt/multiply stretch-matrix (gmt/scale-matrix (gpt/point 1 (/ h1 h2))))
|
h3 (/ h1 h2)
|
||||||
|
h3 (if (mth/nan? h3) 1 h3)
|
||||||
|
|
||||||
rotation-angle (calculate-rec-path-rotation (center-transform rec-path stretch-matrix) shape-path-temp resize-vector)
|
stretch-matrix (gmt/multiply stretch-matrix (gmt/scale-matrix (gpt/point 1 h3)))
|
||||||
|
|
||||||
|
rotation-angle (calculate-rec-path-rotation (center-transform rec-path stretch-matrix)
|
||||||
|
shape-path-temp resize-vector)
|
||||||
|
|
||||||
stretch-matrix (gmt/multiply (gmt/rotate-matrix rotation-angle) stretch-matrix)
|
stretch-matrix (gmt/multiply (gmt/rotate-matrix rotation-angle) stretch-matrix)
|
||||||
|
|
||||||
;; This is the inverse to be able to remove the transformation
|
;; This is the inverse to be able to remove the transformation
|
||||||
stretch-matrix-inverse (-> (gmt/matrix)
|
stretch-matrix-inverse (-> (gmt/matrix)
|
||||||
(gmt/scale (gpt/point 1 (/ h2 h1)))
|
(gmt/scale (gpt/point 1 h3))
|
||||||
(gmt/skew (- skew-angle) 0)
|
(gmt/skew (- skew-angle) 0)
|
||||||
(gmt/rotate (- rotation-angle)))
|
(gmt/rotate (- rotation-angle)))
|
||||||
|
|
||||||
|
|
||||||
new-shape (as-> shape $
|
new-shape (as-> shape $
|
||||||
(merge $ rec)
|
(merge $ rec)
|
||||||
(update $ :x #(mth/precision % 0))
|
(update $ :x #(mth/precision % 0))
|
||||||
(update $ :y #(mth/precision % 0))
|
(update $ :y #(mth/precision % 0))
|
||||||
(update $ :width #(mth/precision % 0))
|
(update $ :width #(mth/precision % 0))
|
||||||
(update $ :height #(mth/precision % 0))
|
(update $ :height #(mth/precision % 0))
|
||||||
(fix-invalid-rect-values $)
|
|
||||||
(update $ :transform #(gmt/multiply (or % (gmt/matrix)) stretch-matrix))
|
(update $ :transform #(gmt/multiply (or % (gmt/matrix)) stretch-matrix))
|
||||||
(update $ :transform-inverse #(gmt/multiply stretch-matrix-inverse (or % (gmt/matrix))))
|
(update $ :transform-inverse #(gmt/multiply stretch-matrix-inverse (or % (gmt/matrix))))
|
||||||
(assoc $ :points (shape->points $))
|
(assoc $ :points (shape->points $))
|
||||||
(assoc $ :selrect (points->selrect (:points $)))
|
(assoc $ :selrect (points->selrect (:points $)))
|
||||||
(update $ :selrect fix-invalid-rect-values)
|
(update $ :selrect fix-invalid-rect-values)
|
||||||
(update $ :rotation #(mod (+ % (get-in $ [:modifiers :rotation] 0)) 360))
|
(update $ :rotation #(mod (+ (or % 0) (get-in $ [:modifiers :rotation] 0)) 360))
|
||||||
|
|
||||||
)]
|
)]
|
||||||
new-shape))
|
new-shape))
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue