@@ -32,12 +32,12 @@ $jit.geometry = {
32
32
33
33
/**
34
34
*
35
- * @param {Number } a1
36
- * @param {Number } a2
37
- * @param {Number } a3
35
+ * @param {Complex } p1
36
+ * @param {Complex } p2
37
+ * @param {Complex } p3
38
38
*/
39
- weightOfPoint : function ( a1 , a2 , a3 ) {
40
- return ( a3 - a1 ) / ( a2 - a1 ) ;
39
+ weightOfPoint : function ( p1 , p2 , p3 ) {
40
+ return ( p3 . x - p1 . x ) / ( p2 . x - p1 . x ) ;
41
41
} ,
42
42
43
43
/**
@@ -95,7 +95,7 @@ $jit.geometry = {
95
95
* Reserves those l[0],l[1],c[i] is counter-clockwise
96
96
*
97
97
* @param {Complex[] } convex
98
- * @param {Complex[][] } l as a ex line
98
+ * @param {Complex[] } l as a ex line
99
99
* @param {?Object } attached
100
100
*/
101
101
convexCut : function ( convex , l , attached ) {
@@ -268,14 +268,30 @@ $jit.geometry = {
268
268
* The intersection of two segments
269
269
* @param {Complex[] } l1
270
270
* @param {Complex[] } l2
271
+ * @param {Boolean } [constraint]
271
272
* @returns {Complex }
272
273
*/
273
- intersectionSeg : function ( l1 , l2 ) {
274
+ intersectionSeg : function ( l1 , l2 , constraint ) {
274
275
var c1 = Geometry . cross ( l1 [ 0 ] , l2 [ 0 ] , l2 [ 1 ] ) ,
275
276
c2 = Geometry . cross ( l1 [ 1 ] , l2 [ 0 ] , l2 [ 1 ] ) , k ;
276
- if ( c1 === c2 )
277
+ if ( c1 == c2 ) {
277
278
return null ;
279
+ }
278
280
k = c1 / ( c1 - c2 ) ;
281
+ if ( constraint ) {
282
+ if ( k < 0 || k > 1 ) {
283
+ return null ;
284
+ }
285
+ var c3 = Geometry . cross ( l2 [ 0 ] , l1 [ 0 ] , l1 [ 1 ] ) ,
286
+ c4 = Geometry . cross ( l2 [ 1 ] , l1 [ 0 ] , l1 [ 1 ] ) ;
287
+ if ( c3 == c4 ) {
288
+ return null ;
289
+ }
290
+ var k2 = c3 / ( c3 - c4 ) ;
291
+ if ( k2 < 0 || k2 > 1 ) {
292
+ return null ;
293
+ }
294
+ }
279
295
return Geometry . weightedPoint ( l1 [ 0 ] , l1 [ 1 ] , k ) ;
280
296
} ,
281
297
@@ -326,32 +342,6 @@ $jit.geometry = {
326
342
return ( ( dx > 0 ) ^ ( cdx > 0 ) ) ;
327
343
} ,
328
344
329
- /**
330
- *
331
- * @param {Complex } p1
332
- * @param {Complex } orig
333
- * @param {Complex } p2
334
- */
335
- angleBisectorLH : function ( p1 , orig , p2 , dist ) {
336
- dist = dist || 1 ;
337
- p1 = $C ( orig . x - p1 . x , orig . y - p1 . y ) ;
338
- p2 = $C ( p2 . x - orig . x , p2 . y - orig . y ) ;
339
- p1 . $scale ( 1 / p1 . norm ( ) ) ;
340
- p2 . $scale ( 3 / p2 . norm ( ) ) ;
341
- var oab = Geometry . weightedPoint ( p1 , p2 , 0.25 ) ;
342
- oab . $scale ( - dist / oab . norm ( ) ) ;
343
- oab . $prod ( Complex . IM ) ;
344
- return [ orig , orig . add ( oab ) ] ;
345
- } ,
346
-
347
- /**
348
- * http://en.wikipedia.org/wiki/Straight_skeleton
349
- * @param {Complex[] } polygon
350
- */
351
- straightSkeleton : function ( polygon ) {
352
-
353
- } ,
354
-
355
345
offsetConvex : function ( convex , offset ) {
356
346
if ( convex . length < 3 ) {
357
347
return [ ] ;
@@ -400,37 +390,29 @@ $jit.geometry = {
400
390
for ( start = first_line . next ; start != first_line ; start = start . next ) {
401
391
result . push ( start . cline [ 1 ] ) ;
402
392
}
393
+ if ( offset < 0 ) return Geometry . cleanConvexHull ( result ) ;
394
+ return result ;
395
+ } ,
403
396
404
- if ( offset < 0 ) {
405
- if ( result . length < 3 ) {
406
- return Geometry . centroid ( convex ) ;
407
- }
408
- var p1 = result [ 0 ] , p2 = result [ 1 ] , pos = 1 ;
409
- for ( i = 2 ; i < result . length ; i ++ ) {
410
- var curr = result [ i ] ;
411
- if ( Geometry . cross ( p1 , p2 , curr ) < 0 ) {
412
- for ( i = i + 1 ; i < result . length ; i ++ ) {
413
- var curr2 = result [ i ] ;
414
- if ( Geometry . cross ( p1 , p2 , curr2 ) > 0 ) {
415
- p2 = result [ pos ] = Geometry . intersectionSeg ( [ p1 , p2 ] , [ curr , curr2 ] ) ;
416
- curr = curr2 ;
417
- break ;
418
- } else {
419
- curr = curr2 ;
420
- }
421
- }
422
- if ( i == result . length ) {
423
-
397
+ cleanConvexHull : function ( convex ) {
398
+ var last = convex [ 0 ] , stack = [ last ] , found = [ ] , inter , np ;
399
+ for ( var i = 1 ; i <= convex . length ; i ++ ) {
400
+ var curr = convex [ i ] || convex [ 0 ] ;
401
+ for ( var j = stack . length - 1 ; j > 0 ; j -- ) {
402
+ var p1 = stack [ j ] , p2 = stack [ j - 1 ] ;
403
+ if ( inter = Geometry . intersectionSeg ( [ last , curr ] , [ p1 , p2 ] , true ) ) {
404
+ if ( Geometry . area ( np = [ inter ] . concat ( stack . slice ( j ) ) ) > 0 ) {
405
+ found . push ( np ) ;
424
406
}
407
+ stack . length = j ;
408
+ stack . push ( inter ) ;
425
409
}
426
-
427
- result [ pos ++ ] = curr ;
428
- p1 = p2 ;
429
- p2 = curr ;
430
410
}
411
+ stack . push ( curr ) ;
412
+ last = curr ;
431
413
}
432
-
433
- return result ;
414
+ if ( Geometry . area ( stack ) ) found . push ( stack ) ;
415
+ return found [ 0 ] || Geometry . centroid ( convex ) ;
434
416
} ,
435
417
436
418
randPointInTriangle : function ( t ) {
@@ -487,8 +469,8 @@ $jit.geometry = {
487
469
* {[Array}
488
470
*/
489
471
convexHull : function ( sites ) {
490
- var stack_top = 0 , i , temp , base , result ;
491
- for ( i = 1 ; i < sites . length ; i ++ ) {
472
+ var stack_top = 0 , i , temp , base , result , N = sites . length ;
473
+ for ( i = 1 ; i < N ; i ++ ) {
492
474
if ( sites [ i ] . y < sites [ 0 ] . y
493
475
|| ( sites [ i ] . y == sites [ 0 ] . y && sites [ i ] . x < sites [ 0 ] . x ) ) {
494
476
temp = sites [ i ] ;
@@ -499,15 +481,13 @@ $jit.geometry = {
499
481
base = sites [ 0 ] ;
500
482
sites . sort ( Geometry . convexHull . polarComp ( base ) ) ;
501
483
result = [ sites [ 0 ] , sites [ 1 ] ] ;
502
- stack_top = 1 ;
503
484
for ( i = 2 ; i < N ; i ++ ) {
504
- while ( stack_top
505
- && Geometry . cross ( result [ stack_top - 1 ] , result [ stack_top ] , sites [ i ] ) <= 0 ) {
506
- stack_top -- ;
485
+ while ( result . length && Geometry . cross ( result [ result . length - 2 ] , result [ result . length - 1 ] , sites [ i ] ) <= 0 ) {
486
+ result . pop ( ) ;
507
487
}
508
- result [ ++ stack_top ] = sites [ i ] ;
488
+ result . push ( sites [ i ] ) ;
509
489
}
510
- return result . slice ( stack_top + 1 ) ;
490
+ return result ;
511
491
} ,
512
492
513
493
/**
0 commit comments