@@ -124,9 +124,23 @@ function compareDist(a, b) {
124
124
125
125
// square distance from a segment bounding box to the given one
126
126
function sqSegBoxDist ( a , b , bbox ) {
127
- var dx = Math . max ( bbox [ 0 ] - Math . max ( a [ 0 ] , b [ 0 ] ) , Math . min ( a [ 0 ] , b [ 0 ] ) - bbox [ 2 ] , 0 ) ;
128
- var dy = Math . max ( bbox [ 1 ] - Math . max ( a [ 1 ] , b [ 1 ] ) , Math . min ( a [ 1 ] , b [ 1 ] ) - bbox [ 3 ] , 0 ) ;
129
- return dx * dx + dy * dy ;
127
+ if ( inside ( a , bbox ) || inside ( b , bbox ) ) return 0 ;
128
+ var d1 = sqSegSegDist ( a [ 0 ] , a [ 1 ] , b [ 0 ] , b [ 1 ] , bbox [ 0 ] , bbox [ 1 ] , bbox [ 2 ] , bbox [ 1 ] ) ;
129
+ if ( d1 === 0 ) return 0 ;
130
+ var d2 = sqSegSegDist ( a [ 0 ] , a [ 1 ] , b [ 0 ] , b [ 1 ] , bbox [ 0 ] , bbox [ 1 ] , bbox [ 0 ] , bbox [ 3 ] ) ;
131
+ if ( d2 === 0 ) return 0 ;
132
+ var d3 = sqSegSegDist ( a [ 0 ] , a [ 1 ] , b [ 0 ] , b [ 1 ] , bbox [ 2 ] , bbox [ 1 ] , bbox [ 2 ] , bbox [ 3 ] ) ;
133
+ if ( d3 === 0 ) return 0 ;
134
+ var d4 = sqSegSegDist ( a [ 0 ] , a [ 1 ] , b [ 0 ] , b [ 1 ] , bbox [ 0 ] , bbox [ 3 ] , bbox [ 2 ] , bbox [ 3 ] ) ;
135
+ if ( d4 === 0 ) return 0 ;
136
+ return Math . min ( d1 , d2 , d3 , d4 ) ;
137
+ }
138
+
139
+ function inside ( a , bbox ) {
140
+ return a [ 0 ] >= bbox [ 0 ] &&
141
+ a [ 0 ] <= bbox [ 2 ] &&
142
+ a [ 1 ] >= bbox [ 1 ] &&
143
+ a [ 1 ] <= bbox [ 3 ] ;
130
144
}
131
145
132
146
// check if the edge (a,b) doesn't intersect any other edges
@@ -254,3 +268,72 @@ function sqSegDist(p, p1, p2) {
254
268
255
269
return dx * dx + dy * dy ;
256
270
}
271
+
272
+ // segment to segment distance, ported from http://geomalgorithms.com/a07-_distance.html by Dan Sunday
273
+ function sqSegSegDist ( x0 , y0 , x1 , y1 , x2 , y2 , x3 , y3 ) {
274
+ var ux = x1 - x0 ;
275
+ var uy = y1 - y0 ;
276
+ var vx = x3 - x2 ;
277
+ var vy = y3 - y2 ;
278
+ var wx = x0 - x2 ;
279
+ var wy = y0 - y2 ;
280
+ var a = ux * ux + uy * uy ;
281
+ var b = ux * vx + uy * vy ;
282
+ var c = vx * vx + vy * vy ;
283
+ var d = ux * wx + uy * wy ;
284
+ var e = vx * wx + vy * wy ;
285
+ var D = a * c - b * b ;
286
+
287
+ var sc , sN , tc , tN ;
288
+ var sD = D ;
289
+ var tD = D ;
290
+
291
+ if ( D === 0 ) {
292
+ sN = 0 ;
293
+ sD = 1 ;
294
+ tN = e ;
295
+ tD = c ;
296
+ } else {
297
+ sN = b * e - c * d ;
298
+ tN = a * e - b * d ;
299
+ if ( sN < 0 ) {
300
+ sN = 0 ;
301
+ tN = e ;
302
+ tD = c ;
303
+ } else if ( sN > sD ) {
304
+ sN = sD ;
305
+ tN = e + b ;
306
+ tD = c ;
307
+ }
308
+ }
309
+
310
+ if ( tN < 0.0 ) {
311
+ tN = 0.0 ;
312
+ if ( - d < 0.0 ) sN = 0.0 ;
313
+ else if ( - d > a ) sN = sD ;
314
+ else {
315
+ sN = - d ;
316
+ sD = a ;
317
+ }
318
+ } else if ( tN > tD ) {
319
+ tN = tD ;
320
+ if ( ( - d + b ) < 0.0 ) sN = 0 ;
321
+ else if ( - d + b > a ) sN = sD ;
322
+ else {
323
+ sN = - d + b ;
324
+ sD = a ;
325
+ }
326
+ }
327
+
328
+ sc = sN === 0 ? 0 : sN / sD ;
329
+ tc = tN === 0 ? 0 : tN / tD ;
330
+
331
+ var cx = ( 1 - sc ) * x0 + sc * x1 ;
332
+ var cy = ( 1 - sc ) * y0 + sc * y1 ;
333
+ var cx2 = ( 1 - tc ) * x2 + tc * x3 ;
334
+ var cy2 = ( 1 - tc ) * y2 + tc * y3 ;
335
+ var dx = cx2 - cx ;
336
+ var dy = cy2 - cy ;
337
+
338
+ return dx * dx + dy * dy ;
339
+ }
0 commit comments