Skip to content

Commit bde85ac

Browse files
committed
Graduating from playground
0 parents  commit bde85ac

33 files changed

+21107
-0
lines changed

.eslintrc.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"parser": "babel-eslint",
3+
"rules": {
4+
"no-undef":"error"
5+
},
6+
"env" : {
7+
"node" : true,
8+
"es6": true
9+
}
10+
}

.gitignore

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
.DS_Store
2+
node_modules
3+
/dist
4+
/build
5+
6+
/demo/outline/
7+
/demo/interactive/public/lines.json
8+
9+
# local env files
10+
.env.local
11+
.env.*.local
12+
13+
14+
# Log files
15+
npm-debug.log*
16+
yarn-debug.log*
17+
yarn-error.log*
18+
19+
# Editor directories and files
20+
.idea
21+
.vscode
22+
*.suo
23+
*.ntvs*
24+
*.njsproj
25+
*.sln
26+
*.sw*

.npmignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
!build/
2+
demo

README.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
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+
[![K12 graph](https://i.imgur.com/PTXwvd3.png)]()
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.

demo/interactive/README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# sweep
2+
3+
## Project setup
4+
```
5+
npm install
6+
```
7+
8+
### Compiles and hot-reloads for development
9+
```
10+
npm start
11+
```
12+
13+
### Compiles and minifies for production
14+
```
15+
npm run build
16+
```
17+
18+
### Lints and fixes files
19+
```
20+
npm run lint
21+
```

demo/interactive/babel.config.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
presets: [
3+
'@vue/app'
4+
]
5+
}

0 commit comments

Comments
 (0)