Fix floating point error with Poisson-disk points being sampled outside shape (#1596)
* Check opposite corner * Commets and test * Fix compiling --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
parent
5f72a6a8a1
commit
aed30d78b8
|
|
@ -584,6 +584,7 @@ version = "0.4.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dyn-any",
|
"dyn-any",
|
||||||
"glam",
|
"glam",
|
||||||
|
"log",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,3 +18,4 @@ glam = { version = "0.24", features = ["serde"] }
|
||||||
|
|
||||||
dyn-any = { version = "0.3.0", path = "../dyn-any", optional = true }
|
dyn-any = { version = "0.3.0", path = "../dyn-any", optional = true }
|
||||||
serde = { version = "1.0", workspace = true, optional = true }
|
serde = { version = "1.0", workspace = true, optional = true }
|
||||||
|
log = { workspace = true, optional = true }
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,11 @@ pub fn poisson_disk_sample(
|
||||||
// Intersecting the shape's border
|
// Intersecting the shape's border
|
||||||
else {
|
else {
|
||||||
// The sub-square is fully inside the shape if its top-left corner is inside and its edges don't intersect the shape border
|
// The sub-square is fully inside the shape if its top-left corner is inside and its edges don't intersect the shape border
|
||||||
let sub_square_fully_inside_shape = !square_edges_intersect_shape_checker(sub_square, subdivided_size) && point_in_shape_checker(sub_square);
|
let sub_square_fully_inside_shape =
|
||||||
|
!square_edges_intersect_shape_checker(sub_square, subdivided_size) && point_in_shape_checker(sub_square) && point_in_shape_checker(sub_square + subdivided_size);
|
||||||
|
// if !square_edges_intersect_shape_checker(sub_square, subdivided_size) { assert_eq!(point_in_shape_checker(sub_square), point_in_shape_checker(sub_square + subdivided_size)); }
|
||||||
|
// Sometimes this fails so it is necessary to also check the bottom right corner.
|
||||||
|
|
||||||
Some(ActiveSquare::new(sub_square, sub_square_fully_inside_shape))
|
Some(ActiveSquare::new(sub_square, sub_square_fully_inside_shape))
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -219,8 +223,9 @@ impl ActiveListLevel {
|
||||||
let point_in_shape = point_in_shape_checker(corner);
|
let point_in_shape = point_in_shape_checker(corner);
|
||||||
let square_edges_intersect_shape = square_edges_intersect_shape_checker(corner, square_size);
|
let square_edges_intersect_shape = square_edges_intersect_shape_checker(corner, square_size);
|
||||||
let square_not_outside_shape = point_in_shape || square_edges_intersect_shape;
|
let square_not_outside_shape = point_in_shape || square_edges_intersect_shape;
|
||||||
let square_in_shape = point_in_shape && !square_edges_intersect_shape;
|
let square_in_shape = point_in_shape_checker(corner + square_size) && !square_edges_intersect_shape;
|
||||||
|
// if !square_edges_intersect_shape { assert_eq!(point_in_shape_checker(corner), point_in_shape_checker(corner + square_size)); }
|
||||||
|
// Sometimes this fails so it is necessary to also check the bottom right corner.
|
||||||
square_not_outside_shape.then_some(ActiveSquare::new(corner, square_in_shape))
|
square_not_outside_shape.then_some(ActiveSquare::new(corner, square_in_shape))
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
|
||||||
|
|
@ -160,12 +160,12 @@ impl<ManipulatorGroupId: crate::Identifier> Subpath<ManipulatorGroupId> {
|
||||||
for bezier in self.iter() {
|
for bezier in self.iter() {
|
||||||
// Check that the two bounding boxes don't intersect, since we can avoid doing intersection's cubic root finding in that case
|
// Check that the two bounding boxes don't intersect, since we can avoid doing intersection's cubic root finding in that case
|
||||||
let [bezier_corner1, bezier_corner2] = bezier.bounding_box_of_anchors_and_handles();
|
let [bezier_corner1, bezier_corner2] = bezier.bounding_box_of_anchors_and_handles();
|
||||||
if !(((corner1.x <= bezier_corner1.x) && (bezier_corner1.x <= corner2.x) || (corner1.x <= bezier_corner2.x) && (bezier_corner2.x <= corner2.x))
|
if !(((corner1.x < bezier_corner1.x) && (bezier_corner1.x < corner2.x) || (corner1.x < bezier_corner2.x) && (bezier_corner2.x < corner2.x))
|
||||||
&& corner1.y <= bezier_corner2.y
|
&& corner1.y < bezier_corner2.y
|
||||||
&& corner2.y >= bezier_corner1.y
|
&& corner2.y > bezier_corner1.y
|
||||||
|| ((corner1.y <= bezier_corner1.y) && (bezier_corner1.y <= corner2.y) || (corner1.y <= bezier_corner2.y) && (bezier_corner2.y <= corner2.y))
|
|| ((corner1.y < bezier_corner1.y) && (bezier_corner1.y < corner2.y) || (corner1.y < bezier_corner2.y) && (bezier_corner2.y < corner2.y))
|
||||||
&& corner1.x <= bezier_corner2.x
|
&& corner1.x < bezier_corner2.x
|
||||||
&& corner2.x >= bezier_corner1.x)
|
&& corner2.x > bezier_corner1.x)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue