0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-23 06:58:58 -05:00

Simplify has-point? impl for non-path shapes

This commit is contained in:
Andrey Antukh 2023-08-25 10:21:48 +02:00 committed by Andrés Moya
parent 266e1c7142
commit 64accaa842
3 changed files with 40 additions and 7 deletions

View file

@ -7,13 +7,15 @@
(ns app.common.geom.shapes.intersect
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt]
[app.common.geom.rect :as grc]
[app.common.geom.shapes.common :as gco]
[app.common.geom.shapes.path :as gpp]
[app.common.geom.shapes.text :as gte]
[app.common.math :as mth]))
[app.common.math :as mth]
[app.common.pages.helpers :as cph]))
(defn orientation
"Given three ordered points gives the orientation
@ -335,13 +337,33 @@
(let [lines (grc/rect->lines rect)]
(is-point-inside-evenodd? point lines)))
(defn has-point?
"Check if the shape contains a point"
(defn slow-has-point?
[shape point]
(let [lines (points->lines (:points shape))]
;; TODO: Will only work for simple shapes
(let [lines (points->lines (dm/get-prop shape :points))]
(is-point-inside-evenodd? point lines)))
(defn fast-has-point?
[shape point]
(let [x1 (dm/get-prop shape :x)
y1 (dm/get-prop shape :x)
x2 (+ x1 (dm/get-prop shape :width))
y2 (+ y1 (dm/get-prop shape :height))
px (dm/get-prop point :x)
py (dm/get-prop point :y)]
(and (>= px x1)
(<= px x2)
(>= py y1)
(<= py y2))))
(defn has-point?
[shape point]
(if (or ^boolean (cph/path-shape? shape)
^boolean (cph/bool-shape? shape)
^boolean (cph/circle-shape? shape))
(slow-has-point? shape point)
(fast-has-point? shape point)))
(defn rect-contains-shape?
[rect shape]
(->> shape

View file

@ -10,6 +10,7 @@
[app.common.geom.point :as gpt]
[app.common.geom.rect :as grc]
[app.common.geom.shapes :as gsh]
[app.common.geom.shapes.intersect :as gsin]
[app.common.geom.shapes.transforms :as gsht]
[app.common.math :as mth :refer [close?]]
[app.common.types.modifiers :as ctm]
@ -224,3 +225,14 @@
(grc/rect->points)
(gsh/transform-points (gmt/rotate-matrix 45)))
(gmt/matrix (* (mth/cos g45) 2) (* (mth/sin g45) 2) (* (- (mth/sin g45)) 4) (* (mth/cos g45) 4) 0 0))))
(t/deftest shape-has-point-pred
(let [{:keys [points] :as shape} (create-test-shape :rect {})
point1 (first points)
point2 (update point1 :x - 100)]
(t/is (true? (gsin/fast-has-point? shape point1)))
(t/is (true? (gsin/slow-has-point? shape point1)))
(t/is (false? (gsin/fast-has-point? shape point2)))
(t/is (false? (gsin/fast-has-point? shape point2)))
))

View file

@ -318,8 +318,7 @@
;; We need to reverse the children because if two children
;; overlap we want to select the one that's over (and it's
;; in the later vector position
selected (->> children
reverse
selected (->> (reverse children)
(d/seek #(gsh/has-point? % position)))]
(when selected
(rx/of (select-shape (:id selected))))))))