diff --git a/common/src/app/common/geom/shapes/path.cljc b/common/src/app/common/geom/shapes/path.cljc index a4be299854..b50a4ba76a 100644 --- a/common/src/app/common/geom/shapes/path.cljc +++ b/common/src/app/common/geom/shapes/path.cljc @@ -12,7 +12,8 @@ [app.common.geom.shapes.common :as gsc] [app.common.geom.shapes.rect :as gpr] [app.common.math :as mth] - [app.common.path.commands :as upc])) + [app.common.path.commands :as upc] + [app.common.path.subpaths :as sp])) (def ^:const curve-curve-precision 0.1) (def ^:const curve-range-precision 2) @@ -818,19 +819,33 @@ (defn is-point-in-content? [point content] + (let [selrect (content->selrect content) + ray-line [point (gpt/point (inc (:x point)) (:y point))] - (letfn [(cast-ray [cmd] - (let [ray-line [point (gpt/point (inc (:x point)) (:y point))]] - (case (:command cmd) - :line-to (ray-line-intersect point (command->line cmd)) - :curve-to (ray-curve-intersect ray-line (command->bezier cmd)) - #_:else [])))] + closed-subpaths + (->> content + (sp/close-subpaths) + (sp/get-subpaths) + (filterv sp/is-closed?)) - (->> content - (mapcat cast-ray) - (map second) - (reduce +) - (not= 0)))) + cast-ray + (fn [cmd] + (case (:command cmd) + :line-to (ray-line-intersect point (command->line cmd)) + :curve-to (ray-curve-intersect ray-line (command->bezier cmd)) + #_:else [])) + + is-point-in-subpath? + (fn [subpath] + (and (gpr/contains-point? (content->selrect (:data subpath)) point) + (->> (:data subpath) + (mapcat cast-ray) + (map second) + (reduce +) + (not= 0))))] + + (and (gpr/contains-point? selrect point) + (some is-point-in-subpath? closed-subpaths)))) (defn split-line-to "Given a point and a line-to command will create a two new line-to commands diff --git a/common/src/app/common/path/subpaths.cljc b/common/src/app/common/path/subpaths.cljc index ca92a6c300..7dc19720d5 100644 --- a/common/src/app/common/path/subpaths.cljc +++ b/common/src/app/common/path/subpaths.cljc @@ -116,6 +116,9 @@ (->> subpaths (reduce merge-with-candidate [candidate []])))) +(defn is-closed? [subpath] + (pt= (:from subpath) (:to subpath))) + (defn close-subpaths "Searches a path for posible supaths that can create closed loops and merge them" [content] @@ -127,7 +130,7 @@ (if (some? current) (let [[new-current new-subpaths] - (if (pt= (:from current) (:to current)) + (if (is-closed? current) [current subpaths] (merge-paths current subpaths))]