Fix n-gon intersection (#342)
* Fix n-gon intersection * Fix not all layers selected with box selection * Code golf for TrueDoctor
This commit is contained in:
parent
39c784599d
commit
6c14c5e04e
|
|
@ -13,9 +13,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayvec"
|
name = "arrayvec"
|
||||||
version = "0.5.2"
|
version = "0.7.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atty"
|
name = "atty"
|
||||||
|
|
@ -167,8 +167,8 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kurbo"
|
name = "kurbo"
|
||||||
version = "0.8.1"
|
version = "0.8.3"
|
||||||
source = "git+https://github.com/linebender/kurbo#0ef68211223b956942c4a5834d66a2625cb8d575"
|
source = "git+https://github.com/linebender/kurbo.git#9ed4b73dac4f085065d7a6968121581cb8296089"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@ license = "Apache-2.0"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
|
||||||
kurbo = {git="https://github.com/linebender/kurbo", features = ["serde"]}
|
kurbo = { git = "https://github.com/linebender/kurbo.git", features = [
|
||||||
|
"serde",
|
||||||
|
] }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
glam = { version = "0.17", features = ["serde"] }
|
glam = { version = "0.17", features = ["serde"] }
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use std::ops::Mul;
|
use std::ops::Mul;
|
||||||
|
|
||||||
use glam::{DAffine2, DVec2};
|
use glam::{DAffine2, DVec2};
|
||||||
use kurbo::{BezPath, Line, PathSeg, Point, Shape, Vec2};
|
use kurbo::{BezPath, Line, PathSeg, Point, Shape};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Copy)]
|
#[derive(Debug, Clone, Default, Copy)]
|
||||||
pub struct Quad([DVec2; 4]);
|
pub struct Quad([DVec2; 4]);
|
||||||
|
|
@ -9,7 +9,7 @@ pub struct Quad([DVec2; 4]);
|
||||||
impl Quad {
|
impl Quad {
|
||||||
pub fn from_box(bbox: [DVec2; 2]) -> Self {
|
pub fn from_box(bbox: [DVec2; 2]) -> Self {
|
||||||
let size = bbox[1] - bbox[0];
|
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] {
|
pub fn lines(&self) -> [Line; 4] {
|
||||||
|
|
@ -20,6 +20,16 @@ impl Quad {
|
||||||
Line::new(to_point(self.0[3]), to_point(self.0[0])),
|
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<Quad> for DAffine2 {
|
impl Mul<Quad> for DAffine2 {
|
||||||
|
|
@ -44,31 +54,12 @@ pub fn intersect_quad_bez_path(quad: Quad, shape: &BezPath, closed: bool) -> boo
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// check if selection is entirely within the shape
|
// 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;
|
return true;
|
||||||
}
|
}
|
||||||
// check if shape is entirely within the selection
|
|
||||||
if let Some(shape_point) = get_arbitrary_point_on_path(shape) {
|
// check if shape is entirely within selection
|
||||||
let mut pos = 0;
|
get_arbitrary_point_on_path(shape).map(|shape_point| quad.path().contains(shape_point)).unwrap_or_default()
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_arbitrary_point_on_path(path: &BezPath) -> Option<Point> {
|
pub fn get_arbitrary_point_on_path(path: &BezPath) -> Option<Point> {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue