@@ -199,6 +199,9 @@ fn bezpath_t_value_to_parametric(bezpath: &kurbo::BezPath, t: BezPathTValue, pre
199
199
/// While the conceptual process described above asymptotically slows down and is never guaranteed to produce a maximal set in finite time,
200
200
/// this is implemented with an algorithm that produces a maximal set in O(n) time. The slowest part is actually checking if points are inside the subpath shape.
201
201
pub fn poisson_disk_points ( bezpath : & BezPath , separation_disk_diameter : f64 , rng : impl FnMut ( ) -> f64 , subpaths : & [ ( BezPath , Rect ) ] , subpath_index : usize ) -> Vec < DVec2 > {
202
+ if bezpath. elements ( ) . is_empty ( ) {
203
+ return Vec :: new ( ) ;
204
+ }
202
205
let bbox = bezpath. bounding_box ( ) ;
203
206
let ( offset_x, offset_y) = ( bbox. x0 , bbox. y0 ) ;
204
207
let ( width, height) = ( bbox. x1 - bbox. x0 , bbox. y1 - bbox. y0 ) ;
@@ -212,9 +215,9 @@ pub fn poisson_disk_points(bezpath: &BezPath, separation_disk_diameter: f64, rng
212
215
let point_in_shape_checker = |point : DVec2 | {
213
216
// Check against all paths the point is contained in to compute the correct winding number
214
217
let mut number = 0 ;
215
- for ( i, ( shape, bb ) ) in subpaths. iter ( ) . enumerate ( ) {
218
+ for ( i, ( shape, bbox ) ) in subpaths. iter ( ) . enumerate ( ) {
216
219
let point = point + DVec2 :: new ( bbox. x0 , bbox. y0 ) ;
217
- if bb . x0 > point. x || bb . y0 > point. y || bb . x1 < point. x || bb . y1 < point. y {
220
+ if bbox . x0 > point. x || bbox . y0 > point. y || bbox . x1 < point. x || bbox . y1 < point. y {
218
221
continue ;
219
222
}
220
223
let winding = shape. winding ( dvec2_to_point ( point) ) ;
@@ -227,9 +230,9 @@ pub fn poisson_disk_points(bezpath: &BezPath, separation_disk_diameter: f64, rng
227
230
number != 0
228
231
} ;
229
232
230
- let square_edges_intersect_shape_checker = |corner1 : DVec2 , size : f64 | {
231
- let corner2 = corner1 + DVec2 :: splat ( size) ;
232
- bezpath_rectangle_intersections_exist ( bezpath, corner1 , corner2 )
233
+ let square_edges_intersect_shape_checker = |position : DVec2 , size : f64 | {
234
+ let rect = Rect :: new ( position . x , position . y , position . x + size , position . y + size) ;
235
+ bezpath_rectangle_intersections_exist ( bezpath, rect )
233
236
} ;
234
237
235
238
let mut points = poisson_disk_sample ( width, height, separation_disk_diameter, point_in_shape_checker, square_edges_intersect_shape_checker, rng) ;
@@ -240,22 +243,33 @@ pub fn poisson_disk_points(bezpath: &BezPath, separation_disk_diameter: f64, rng
240
243
points
241
244
}
242
245
243
- fn bezpath_rectangle_intersections_exist ( bezpath : & BezPath , corner1 : DVec2 , corner2 : DVec2 ) -> bool {
244
- info ! ( "rect intersection => bezpath => {:?}, corner ({:?})" , bezpath, ( corner1, corner2) ) ;
245
- let a = corner1;
246
- let b = DVec2 :: new ( corner2. x , corner1. y ) ;
247
- let c = corner2;
248
- let d = DVec2 :: new ( corner1. x , corner2. y ) ;
246
+ fn bezpath_rectangle_intersections_exist ( bezpath : & BezPath , rect : Rect ) -> bool {
247
+ if !bezpath. bounding_box ( ) . overlaps ( rect) {
248
+ return false ;
249
+ }
249
250
250
- let top_line = Line :: new ( ( a. x , a. y ) , ( b. x , b. y ) ) ;
251
- let right_line = Line :: new ( ( b. x , b. y ) , ( c. x , c. y ) ) ;
252
- let bottom_line = Line :: new ( ( c. x , c. y ) , ( d. x , d. y ) ) ;
253
- let left_line = Line :: new ( ( d. x , d. y ) , ( a. x , a. y ) ) ;
251
+ // p1 p2
252
+ // -------------
253
+ // | |
254
+ // | |
255
+ // | |
256
+ // -------------
257
+ // p4 p3
258
+ let p1 = Point :: new ( rect. x0 , rect. y0 ) ;
259
+ let p2 = Point :: new ( rect. x1 , rect. y0 ) ;
260
+ let p3 = Point :: new ( rect. x1 , rect. y1 ) ;
261
+ let p4 = Point :: new ( rect. x0 , rect. y1 ) ;
262
+
263
+ let top_line = Line :: new ( ( p1. x , p1. y ) , ( p2. x , p2. y ) ) ;
264
+ let right_line = Line :: new ( ( p2. x , p2. y ) , ( p3. x , p3. y ) ) ;
265
+ let bottom_line = Line :: new ( ( p3. x , p3. y ) , ( p4. x , p4. y ) ) ;
266
+ let left_line = Line :: new ( ( p4. x , p4. y ) , ( p1. x , p1. y ) ) ;
267
+
268
+ let lines = [ top_line, right_line, bottom_line, left_line] ;
254
269
255
270
for segment in bezpath. segments ( ) {
256
- for line in [ top_line , right_line , bottom_line , left_line ] {
271
+ for line in lines {
257
272
if !segment. intersect_line ( line) . is_empty ( ) {
258
- info ! ( "insected." ) ;
259
273
return true ;
260
274
}
261
275
}
0 commit comments