|
| 1 | +# isect - intersection detection library |
| 2 | + |
| 3 | +This library allows you to find all intersections in a given set of |
| 4 | +segments. |
| 5 | + |
| 6 | +TODO: Image |
| 7 | + |
| 8 | +# Methods |
| 9 | + |
| 10 | +The library implements two methods |
| 11 | + |
| 12 | +## Bentley-Ottmann sweep line algorithm |
| 13 | + |
| 14 | +This algorithm has `O(n*log(n) + k*log(n))` performance, where `n` is number of |
| 15 | +segments, and `k` is number of intersections. |
| 16 | + |
| 17 | +This method is preferred when you have large number of lines, and not too many |
| 18 | +intersections (`k = o(n^2/log(n)`, to be more specific). |
| 19 | + |
| 20 | +The algorithm follows "Computation Geometry, Algorithms and Applications" book |
| 21 | +by Mark de Berg, Otfried Cheong, Marc van Kreveld, and Mark Overmars. It does support |
| 22 | +degenerate cases, though read limitations to learn more. |
| 23 | + |
| 24 | +## Brute force algorithm |
| 25 | + |
| 26 | +This is "naive" implementation where each segment is compared with all other segments, |
| 27 | +and thus has O(n*n) performance. |
| 28 | + |
| 29 | +Despite it's naiveté, it works much faster than Bentley-Ottmann algorithm for the cases |
| 30 | +when there are a few thousand lines and millions of intersections. This scenario is |
| 31 | +common in force-based graph drawing, where "hairball" formed by a few thousand lines. |
| 32 | + |
| 33 | +## Performance measurements |
| 34 | + |
| 35 | +The benchmark code is available here. |
| 36 | + |
| 37 | +[]() |
| 38 | +``` |
| 39 | +Sweep: Circular lines 12x40 x 1,022 ops/sec ±1.94% (90 runs sampled) |
| 40 | +Brute: Circular lines 12x40 x 7,252 ops/sec ±3.15% (78 runs sampled) |
| 41 | +Sweep: 100 Random lines lines in 42px box x 267 ops/sec ±0.80% (89 runs sampled) |
| 42 | +Brute: 100 Random lines lines in 42px box x 3,751 ops/sec ±2.42% (76 runs sampled) |
| 43 | +Sweep: 2,500 sparse lines x 135 ops/sec ±0.55% (75 runs sampled) |
| 44 | +Brute: 2,500 sparse lines x 13.57 ops/sec ±0.43% (38 runs sampled) |
| 45 | +``` |
| 46 | + |
| 47 | + |
| 48 | +# usage |
| 49 | + |
| 50 | +## installation |
| 51 | +Install the module from npm: |
| 52 | + |
| 53 | +``` |
| 54 | +npm i isect |
| 55 | +``` |
| 56 | + |
| 57 | +## basic usage |
| 58 | + |
| 59 | +The code below detects all intersections between segments in the array: |
| 60 | + |
| 61 | +``` js |
| 62 | +var isect = require('isect'); |
| 63 | + |
| 64 | +// Prepare the library to detect all intersection |
| 65 | +var iSector = isect([{ |
| 66 | + from: {x: 0, y: 0}, |
| 67 | + to: {x: 10, y: 10} |
| 68 | +}, { |
| 69 | + from: {x: 0, y: 10}, |
| 70 | + to: {x: 10, y: 0} |
| 71 | +}]); |
| 72 | + |
| 73 | +// Detect them all, operation is synchronous. |
| 74 | +var intersections = iSector.run(); |
| 75 | +console.log(intersections); |
| 76 | +// Prints: |
| 77 | +// |
| 78 | +// [ { point: { x: 5, y: 5 }, segments: [ [Object], [Object] ] } ] |
| 79 | +// |
| 80 | +// array of segments contain both segments. |
| 81 | +``` |
| 82 | + |
| 83 | +## Early stopping |
| 84 | + |
| 85 | +If you don't care about all intersections, but want to know if there is |
| 86 | +at least one intersection, you can pass a `onFound()` callback and request |
| 87 | +the library to stop as soon as it finds the intersection: |
| 88 | + |
| 89 | +``` js |
| 90 | +var iSector = isect([/* array of segments */], { |
| 91 | + onFound(point, interior, lower, upper) { |
| 92 | + // `point` is {x, y} of the intersection, |
| 93 | + // `interior`is array of segments that have this point inside |
| 94 | + // `lower` are segments that have point as a lower endpoint (segment.to) |
| 95 | + // `upper` are segments that have point as an upper endpoint (segment.from) |
| 96 | + |
| 97 | + // If you return true from this method, no further processing will be done: |
| 98 | + |
| 99 | + return true; // yes, stop right now! |
| 100 | + } |
| 101 | +}); |
| 102 | +``` |
| 103 | + |
| 104 | +## Asynchronous workflow |
| 105 | + |
| 106 | +TODO: explain |
| 107 | + |
| 108 | + |
| 109 | +## Performance |
| 110 | + |
| 111 | + |
| 112 | + |
| 113 | +## Limitations |
| 114 | + |
| 115 | +The library is susceptible to floating point rounding errors. It is |
| 116 | +possible to construct an example, with nearly horizontal lines, that would |
| 117 | +cause library to fail. TODO: link to drunk grid with small variance and large |
| 118 | +number of lines. |
| 119 | + |
| 120 | +While library does detected `point-segment` overlap, it does not detected `point-point` |
| 121 | +overlap. I.e. identical points in the input dataset, that do not overlap any segment |
| 122 | +will not be reported. |
0 commit comments