This library includes a suite of geometry tools that exist and can be leveraged independently of the rest of the Planar Graph and origami related code.



A point is represented by its components in 2D space: x and y. We call this class object an XY.

let point = new XY(0.5, 0.666)

Lines, Rays, Segments

Mathematical lines extend infinitely in both directions, rays extend infinitely in one direction, and line segments, or edges are bound by two endpoints.

let segment = new Edge()
let ray = new Ray()
let line = new Line()

Four arguments describe two points (x1, y1, x2, y2).

Edges and lines are defined by two collinear points, rays however are defined by an origin and a direction vector.


A ConvexPolygon object is defined its edges, it contains the classic convex hull algorithm, and can clip lines, rays, and edges into a new edge which fits within its boundary.

The convex hull algorithm performed on a collection of points

let polygon = new ConvexPolygon()
let clipped = polygon.clipEdge( new Edge(0.5, 0, 0.5, 1) )

Clipping functions return an edge with a new set of endpoints.


In preparation for origami operations, there is much to be done with one node and its adjacent edges.

Junction: the area including one node, its adjacent edges, and the interior angles they form.

Junctions themselves are made up of sectors, the number of sectors is equal to the number of edges, or interior angles.

Sector: two adjacent ordered edges and the space that creates an angle between them.

The angle between two vectors can be the smaller or the larger which is why it's important to order the vectors, and consider the clockwise space between them.

If all that isn't confusing enough, computers render +Y down and clockwise appears counter-clockwise. FML


The space between two vectors creates two interior angles. It's important to distinguish between vectors a and b the clockwise or the counter-clockwise interior angle.


Two vectors bisected results in two answers. This function will return the bisection of the smaller interior angle first.

[XY,XY] = bisect(a:XY, b:XY) 


Matrices are the dark arts of geometric transformations. Inside of one matrix can contain instructions for any number of rotations, translations, reflections, scaling, shearing (mathematically speaking some of those are redundant).

A matrix for 2D transformations needs 6 numbers: 4 for rotation, scaling, and reflection operations, and 2 for translation.


A 2x2 matrix is sufficient to represent a reflection line that goes through the origin. For all lines, an additional 1x2 column is required.

drag the blue circles to move the line of reflection


The nearest point on a line to another point can be located if you draw a normal vector that passes through the point.

In the case of line segments, the normal might lie beyond the endpoints. The shortest point is now one of the two endpoints.

The sketch on the left determines the nearest point only using a normal vector and the sketch on the right includes the endpoints in the calculation.


Epsilon (ε) is the tiny space deep in the floating point number past the decimal point.

Nearly every math function in this library offers an optional argument to allow you to specify a level of precision.

For most generative applications an epsilon of 0.00000001 is sufficient for Javascript's 64 bit floats. 0.001 is more reasonable when dealing with imported files created in vector graphics applications with sometimes imprecise input.