# A hidden gold of JointJS, the geometry library

September 12th, 2013

The JointJS diagramming library contains a not-yet-documented standalone pure JavaScript mini library that implements many useful geometry operations. This post shows all the primitives that the geometry library exposes. The geometry library does not have any dependencies, is AMD complient and can be used outside of JointJS. The source code of the library can be found on Github.

It's important to note that many of the methods of the geometry library are inspired by their Squeak Smalltalk implementations.

## List of primitives

This is the complete list of primitives that the geometry library exposes:

• point
• line
• rect
• ellipse
• bezier

## Point

Methods of the `point` primitve are:

• `adhereToRect(r)` If the point lies outside the rectangle `r`, return the nearest point on the boundary of `r`.
• `theta(p)` Return the angle (in degrees) between the point, another point `p` and the x-axis.
• `distance(p)` Return the distance between the point and another point `p`.
• `manhattenDistance(p)` Return the manhatten distance between the point and another point `p`.
• `offset(dx, dy)` Offset the point (change its x and y coordinates) by `dx` and `dy`.
• `magnitude()` Return the magnitude of the point vector.
• `update(x, y)` Update the point x and y coordinates with new values and return the point itself. Useful for chaining
• `round([decimals])` Round the point (optionally on `decimal` places) and return the point itself.
• `normalize([len])` Normalize the point vector and return the point itself. In other words, scale the line segment between (0, 0) and the point in order for it to have a length of `len`. If `len` is not passed, it is considered to be `1` in which case a unit vector is computed.
• `difference(p)` Return a point that has coordinates computed as a difference between the point and another point `p`.
• `toPolar(o)` Convert rectangular to polar coordinates. If the origin `o` is not specified, it is considered to be at (0,0).
• `rotate(o, angle)` Rotate the point by `angle` around the origin `o`.
• `move(ref, distance)` Move the point on a line that leads to another point `ref` by distance `distance`.
• `changeInAngle(dx, dy, ref)` Return the change in angle that is the result of moving the point from its previous position (-dx, -dy) to its new position. This move is relative to the `ref` point and x axis.

Methods of the point constructor:

• `fromPolar(r, angle, o)` Construct a point from polar coordinates.
• `random(x1, x2, y1, y2)` Construct a point with random coordinates that fall into the range `[x1, x2]` and `[y1, y2]`.

### Examples

``````
var p1 = point(20, 50);
var p2 = point('150 200');
p1.distance(p2);
p1.theta(p2);
p1.normalize(2);
console.log(p1 + ''); // prints 20@50
``````

## Line

Methods of the `line` primitive are:

• `length()` Return the length of the line.
• `squaredLength()` Return the squared length of the line. Useful in cases the real length is not necessary (saves the Math.sqrt() operation).
• `midpoint()` Return the point that is in the middle of the line.
• `intersection(l)` Return the point that the line is intersecting another line `l`. Return `null` if there is no such point.

### Examples

``````
var l1 = line(point(20, 50), point(150, 200));
var l2 = line(point(320, 150), point(20, 20));
l1.length();
l1.intersection(l2);
l1.midpoint();
console.log(l1 + ''); // prints 20@50 150@200
``````

## Rectangle

Methods of the `rect` primitive are:

• `origin()` Return the point that is the top left corner of the rectangle.
• `corner()` Return the point that is the bottom right corner of the rectangle.
• `topRight()` Return the point that is the top right corner of the rectangle.
• `bottomLeft()` Return the point that is the bottom left corner of the rectangle.
• `center()` Return the point that is the center of the rectangle.
• `intersect(r)` Return `true` if the rectangle intersects another rectangle `r`.
• `sideNearestToPoint(p)` Return the `"top", "left", "right" or "bottom"` string denoting the side which is nearest to the point `p`.
• `containsPoint(p)` Return `true` if the rectangle contains the point `p`.
• `pointNearestToPoint(p)` Return the point on the boundary of the rectangle nearest to the point `p`.
• `intersectionWithLineFromCenterToPoint(p, angle)` Return the point on the boundary of the rectangle that is the intersection of the rectangle with the line starting in the center of the rectangle ending in the point `p`. If `angle` is specified, the intersection will take into account a rotation of the rectangle by `angle` degrees around its center.
• `moveAndExpand(r)` Offset the rectangle by `r.x` and `r.y` and expand it by `r.width` and `r.height`.
• `round(decimals)` Round the rectangle (optionally on `decimal` places) and return the rectangle itself.

### Examples

``````
var r1 = rect(20, 50, 200, 100);  // x, y, width, height
var r2 = rect(80, 70, 300, 200);
r1.origin();
r1.intersect(r2); // true
console.log(r1 + ''); // prints 20@50 220@150
``````

## Ellipse

Methods of the `ellipse` primitive are:

• `bbox()` Return the rectangle that is the bounding box of the ellipse.
• `intersectionWithLineFromCenterToPoint(p, angle)` Return the point on the boundary of the ellipse that is the intersection of the ellipse with the line starting in the center of the ellipse ending in the point `p`. If `angle` is specified, the intersection will take into account a rotation of the ellipse by `angle` degrees around its center.

### Examples

``````
var e1 = ellipse(point(100, 50), 50, 80);  // center, a, b
e1.bbox();
console.log(e1 + ''); // prints 100@50 50 80
``````

## Bezier

Methods of the `bezier` primitive are:

• `curveThroughPoints(points)` Return SVG path commands that define a cubic bezier curve going through the `points`.

## Other exported methods of the module

The geometry module (in AMD environment terms) or the `g` global variable (without AMD), contains these additional methods:

• `toDeg(rad)` Convert radians `rad` to degrees.
• `toRad(deg)` Convert degrees `deg` to radians.
• `snapToGrid(val, gridSize)` Snap the value `val` to a grid of size `gridSize`.

## Conclusion

The geometry library of JointJS is a handy tool for applications that deal with geometry primitives. As this library does not have any dependencies and is implemented purely in JavaScript without using the browser DOM, it can run even on the server (e.g. in NodeJS).