flatten-js
Version:
Javascript library for 2d geometry
182 lines (147 loc) • 6.8 kB
Markdown
[](https://badge.fury.io/js/flatten-js)
[](https://travis-ci.org/alexbol99/flatten-js)
[](https://coveralls.io/github/alexbol99/flatten-js?branch=master)
# Javascript library for 2d geometry
Flatten-js is a small javascript library (about 45 Kb minified) for manipulating abstract geometrical objects like point, vector, line, segment,
circle, arc and polygon. The library works in any modern browsers as well as under nodejs.
## Installation
npm install --save flatten-js
## Usage
```javascript
// require package
let Flatten = require('flatten-js');
// extract object creators
let {point, circle, segment} = Flatten;
// make some construction
let s1 = segment(10,10,200,200);
let s2 = segment(10,160,200,30);
let c = circle(point(200, 110), 50);
let ip = s1.intersect(s2);
// visualize using svg output
let svg=[s1, s2, c, ip[0]].reduce((acc,shape) => acc + shape.svg(),"");
document.getElementById("graphics").innerHTML = svg;
```

Play with this code on requirebin http://requirebin.com/?gist=2bf8335f4655f103ba500b647e70f1fc
## First project
Check out this [flatten-js-test](https://github.com/alexbol99/flatten-js-test) from git to create your first project using **flatten-js** library.
Flatten-js-test has zero configuration, it works "as is" without transpiling in any modern browser.
## Documentation
Documentation may be found here https://alexbol99.github.io/flatten-js/index.html
## Library
### Shapes
Flatten-js library provides support for the following shapes in 2d:
* Point
* Vector
* Line
* Circle
* Segment
* Arc
* Polygon
Beyond of some trivial methods shape classes implement several common methods and queries:
* Points location test
* Intersection between shapes
* Distance to other shape
They also expose *box* property - axis aligned bounding box (AABB)
needed for search tree index construction
Shapes may be created using constructor:
```javascript
let c = new Circle( new Point(30,40), 100 );
```
or in functional form:
```javascript
let c = circle( point(30,40), 100 );
```
### Planar Set
Planar Set is a container of shapes.
It is implemented as an extension of the javascript Set object with the search tree index.<br/>
Any object added to Planar Set container have to expose *box* property,
where *box* should be an instance of the **Flatten.Box** class or implement special interface.<br/>
Planar Set provides range search query to locate shapes which
bounding boxes are intersected with the query box.
Example:
```javascript
let planarSet = new PlanarSet();
let segment = new Segment(1,1,2,2);
let circle = new Circle(new Point(3,3), 1);
planarSet.add(segment);
planarSet.add(circle);
let resp = planarSet.search(new Box(2,2,3,3));
console.log(resp.length); // expected to be 2
```
### Polygon
Polygon is a collection of closed loops, called **faces**.<br/>
Each face is a continuous closed chain of **edges**.<br/>
Edge may be either **segment** or **arc**.<br/>
Faces may contain each other as well as be disjoint. If internal face has a direction opposite
to the direction of containing face, it will be treated as a *hole*.<br/>
By definition, *faces* and *edges* are instances of PlanarSet, which means they are searchable containers
that enable range search queries.
#### Polygon construction
Polygon is constructing by adding faces. To create a new face, one needs to transfer an array
representing closed chain of edges. If chain has no arcs, it may be also an array of points
representing vertices of the face.
```javascript
// points will be used as vertices to create a face comprised from segments only
let vertices1 = [point(50,50), point(50,250), point(250, 250), point(250,50)];
let vertices2 = [point(100,100), point(200,100), point(200, 200), point(100,200)];
// arcs will be used as edges to create a face that may be comprised from segments and arcs
let arcs = [
arc(point(100,100), 50, 0, Math.PI/2, true),
arc(point(100,200), 50, -Math.PI/2, 0, true),
arc(point(200,200), 50, Math.PI, 3*Math.PI/2, true),
arc(point(200,100), 50, Math.PI/2, Math.PI, true),
];
// create empty polygon
let polygon = new Polygon();
// then add faces
polygon.addFace(vertices1);
polygon.addFace(vertices2);
polygon.addFace(arcs);
```
#### Traversing faces and edges
As being elements of Set containers, polygon's faces and edges may be traversed as regular set elements.
Face implements *next* iterator, so if one needs to traverse edges of the specific face,
it may be done in the following way:
```javascript
for (let face of polygon.faces) {
for (let edge of face) { // sic!
console.log(edge.shape.length); // do something
}
}
```
From the other hand, edges in the face form a circular bidirectional linked list,
so if more controlled iteration needed, one can use the following form:
```javascript
for (let face of polygon.faces) {
let edge = face.first;
do {
console.log(edge.shape.length); // do something
edge = edge.next;
} while (edge != face.first)
}
```
#### Specific polygon methods
There are several other methods specific for polygon and its faces
* `face.area()` - Returns area of the face
* `face.isSimple()` - Returns *true* if polygon has no self-intersections
* `face.getOrientation()` - Returns direction of the face - clockwise or counterclockwise
* `polygon.area()` - Returns area of the polygon. If polygon has holes,
their area is taken as negative.
## Visualization
This library does not concern about visualization.
Anyway, all classes, including PlanarSet, have `svg()` method, that returns a string which may be inserted into
defined SVG element, like this:
```javascript
// visualize using svg output
document.getElementById("graphics").innerHTML = polygon.svg();
```
## Tests
The project has comprehensive set of unit tests. If someone wants to play with then,
he (or she) may check out this project, install dependencies,
including dev dependencies (chai/mocha) and then run
```
npm test
```
## Contributing
In lieu of a formal style guide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code.