From 9cd6d57337af419917ebc267ecb5e1c3e20a9f9d Mon Sep 17 00:00:00 2001 From: Paul Kupper <11900073+pkupper@users.noreply.github.com> Date: Wed, 11 Aug 2021 23:58:10 +0200 Subject: [PATCH] Fix n-gon intersection (#342) * Fix n-gon intersection * Fix not all layers selected with box selection * Code golf for TrueDoctor --- Cargo.lock | 2 +- graphene/Cargo.toml | 4 +++- graphene/src/intersection.rs | 41 ++++++++++++++---------------------- 3 files changed, 20 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2459b309d2..1c56b9a347 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -168,7 +168,7 @@ dependencies = [ [[package]] name = "kurbo" version = "0.8.1" -source = "git+https://github.com/linebender/kurbo#0ef68211223b956942c4a5834d66a2625cb8d575" +source = "git+https://github.com/GraphiteEditor/kurbo.git#feb9ef74f841fcc5890bfe6ae763fbb986c80490" dependencies = [ "arrayvec", "serde", diff --git a/graphene/Cargo.toml b/graphene/Cargo.toml index 019f056ee8..f6d8964ea8 100644 --- a/graphene/Cargo.toml +++ b/graphene/Cargo.toml @@ -11,6 +11,8 @@ license = "Apache-2.0" [dependencies] log = "0.4" -kurbo = {git="https://github.com/linebender/kurbo", features = ["serde"]} +kurbo = { git = "https://github.com/GraphiteEditor/kurbo.git", features = [ + "serde", +] } serde = { version = "1.0", features = ["derive"] } glam = { version = "0.17", features = ["serde"] } diff --git a/graphene/src/intersection.rs b/graphene/src/intersection.rs index ddbbfe53fa..c4a940ff74 100644 --- a/graphene/src/intersection.rs +++ b/graphene/src/intersection.rs @@ -1,7 +1,7 @@ use std::ops::Mul; use glam::{DAffine2, DVec2}; -use kurbo::{BezPath, Line, PathSeg, Point, Shape, Vec2}; +use kurbo::{BezPath, Line, PathSeg, Point, Shape}; #[derive(Debug, Clone, Default, Copy)] pub struct Quad([DVec2; 4]); @@ -9,7 +9,7 @@ pub struct Quad([DVec2; 4]); impl Quad { pub fn from_box(bbox: [DVec2; 2]) -> Self { let size = bbox[1] - bbox[0]; - Self([bbox[0], bbox[0] + size * DVec2::X, bbox[0] + size * DVec2::Y, bbox[1]]) + Self([bbox[0], bbox[0] + size * DVec2::X, bbox[1], bbox[0] + size * DVec2::Y]) } pub fn lines(&self) -> [Line; 4] { @@ -20,6 +20,16 @@ impl Quad { Line::new(to_point(self.0[3]), to_point(self.0[0])), ] } + + pub fn path(&self) -> BezPath { + let mut path = kurbo::BezPath::new(); + path.move_to(to_point(self.0[0])); + path.line_to(to_point(self.0[1])); + path.line_to(to_point(self.0[2])); + path.line_to(to_point(self.0[3])); + path.close_path(); + path + } } impl Mul for DAffine2 { @@ -44,31 +54,12 @@ pub fn intersect_quad_bez_path(quad: Quad, shape: &BezPath, closed: bool) -> boo return true; } // check if selection is entirely within the shape - if closed && quad.0.iter().any(|q| shape.contains(to_point(*q))) { + if closed && shape.contains(to_point(quad.0[0])) { return true; } - // check if shape is entirely within the selection - if let Some(shape_point) = get_arbitrary_point_on_path(shape) { - let mut pos = 0; - let mut neg = 0; - for line in quad.lines() { - if line.p0 == shape_point { - return true; - }; - let line_vec = Vec2::new(line.p1.x - line.p0.x, line.p1.y - line.p0.y); - let point_vec = Vec2::new(line.p1.x - shape_point.x, line.p1.y - shape_point.y); - let cross = line_vec.cross(point_vec); - if cross > 0.0 { - pos += 1; - } else if cross < 0.0 { - neg += 1; - } - if pos > 0 && neg > 0 { - return false; - } - } - } - true + + // check if shape is entirely within selection + get_arbitrary_point_on_path(shape).map(|shape_point| quad.path().contains(shape_point)).unwrap_or_default() } pub fn get_arbitrary_point_on_path(path: &BezPath) -> Option {