### Install and import Constrainautor
Source: https://github.com/kninnug/constrainautor/blob/master/README.md
Installation and various import methods for the library.
```bash
npm install @kninnug/constrainautor
```
```javascript
const Constrainautor = require('@kninnug/constrainautor');
```
```javascript
import Constrainautor from '@kninnug/constrainautor';
```
```html
```
```html
```
--------------------------------
### Full Constrained Triangulation Example
Source: https://context7.com/kninnug/constrainautor/llms.txt
Demonstrates the typical workflow of creating a constrained triangulation for a polygon with a hole using Delaunator and Constrainautor. Ensure input points are unique and constraint edges do not intersect.
```typescript
import Delaunator from 'delaunator';
import Constrainautor from '@kninnug/constrainautor';
// Define a polygon with a hole (outer boundary + inner boundary)
const points: [number, number][] = [
// Outer boundary (clockwise)
[0, 0], [200, 0], [200, 200], [0, 200],
// Inner hole (counter-clockwise)
[50, 50], [150, 50], [150, 150], [50, 150]
];
// Edges that must exist in the triangulation
const constraintEdges: [number, number][] = [
// Outer boundary edges
[0, 1], [1, 2], [2, 3], [3, 0],
// Inner hole edges
[4, 5], [5, 6], [6, 7], [7, 4]
];
// Step 1: Create Delaunay triangulation
const del = Delaunator.from(points);
// Step 2: Create Constrainautor and constrain all edges
const con = new Constrainautor(del, constraintEdges);
// Step 3: Iterate over resulting triangles
console.log('Constrained triangulation:');
for (let i = 0; i < del.triangles.length; i += 3) {
const t0 = del.triangles[i];
const t1 = del.triangles[i + 1];
const t2 = del.triangles[i + 2];
console.log(`Triangle ${i/3}: [${t0}, ${t1}, ${t2}]`);
console.log(` Vertices: (${points[t0]}), (${points[t1]}), (${points[t2]})`);
}
// Step 4: Identify which triangles are inside vs outside the polygon
// (requires additional logic based on winding order or point-in-polygon tests)
// Helper: Get all edges with their constraint status
function getEdges(del: Delaunator<[number, number]>, con: Constrainautor) {
const edges: Array<{from: number, to: number, constrained: boolean}> = [];
for (let edg = 0; edg < del.triangles.length; edg++) {
const nextEdg = (edg % 3 === 2) ? edg - 2 : edg + 1;
const from = del.triangles[edg];
const to = del.triangles[nextEdg];
if (from < to) { // Avoid duplicates
edges.push({
from,
to,
constrained: con.isConstrained(edg)
});
}
}
return edges;
}
const allEdges = getEdges(del, con);
console.log(`
Total edges: ${allEdges.length}`);
console.log(`Constrained edges: ${allEdges.filter(e => e.constrained).length}`);
```
--------------------------------
### Find Edge Between Points
Source: https://context7.com/kninnug/constrainautor/llms.txt
Use findEdge to get the half-edge ID between two points. Returns a positive ID if the edge exists in the specified direction, a negative ID if the edge exists but points in the reverse direction (on the hull), or Infinity if no edge connects the points.
```typescript
import Delaunator from 'delaunator';
import Constrainautor from '@kninnug/constrainautor';
const points = [[0, 0], [100, 0], [50, 100]];
const del = Delaunator.from(points);
const con = new Constrainautor(del);
// Find edges between points
const edge01 = con.findEdge(0, 1);
const edge10 = con.findEdge(1, 0);
const noEdge = con.findEdge(0, 0); // Same point - no edge
console.log(`Edge 0->1: ${edge01}`); // Positive id if exists pointing this direction
console.log(`Edge 1->0: ${edge10}`); // Different id for reverse direction
console.log(`Edge 0->0: ${noEdge}`); // Infinity - no self-edge
// Check if an edge is on the hull (returns negative id)
if (edge01 < 0) {
console.log(`Edge 0->1 is on hull, actual edge points 1->0`);
} else if (edge01 === Infinity) {
console.log(`No edge between 0 and 1`);
} else {
console.log(`Edge 0->1 found with id ${edge01}`);
}
```
--------------------------------
### Initialize Constrainautor
Source: https://context7.com/kninnug/constrainautor/llms.txt
Create a new instance from a Delaunator triangulation, optionally providing an array of edges to constrain immediately.
```typescript
import Delaunator from 'delaunator';
import Constrainautor from '@kninnug/constrainautor';
// Define points for triangulation
const points = [[150, 50], [50, 200], [150, 350], [250, 200]];
// Create Delaunay triangulation with Delaunator
const del = Delaunator.from(points);
// Create Constrainautor instance
const con = new Constrainautor(del);
// Or create with edges to constrain immediately
const edges: [number, number][] = [[0, 2], [1, 3]];
const conWithEdges = new Constrainautor(del, edges);
// Access the modified triangulation
console.log(con.del.triangles); // Uint32Array of triangle vertex indices
console.log(con.del.halfedges); // Int32Array of half-edge connections
```
--------------------------------
### Constructor
Source: https://context7.com/kninnug/constrainautor/llms.txt
Creates a new Constrainautor instance from a Delaunator triangulation. Optionally accepts an array of edges to constrain immediately upon construction.
```APIDOC
## Constructor
Creates a new Constrainautor instance from a Delaunator triangulation. Optionally accepts an array of edges to constrain immediately upon construction.
### Request Example
```typescript
import Delaunator from 'delaunator';
import Constrainautor from '@kninnug/constrainautor';
// Define points for triangulation
const points = [[150, 50], [50, 200], [150, 350], [250, 200]];
// Create Delaunay triangulation with Delaunator
const del = Delaunator.from(points);
// Create Constrainautor instance
const con = new Constrainautor(del);
// Or create with edges to constrain immediately
const edges: [number, number][] = [[0, 2], [1, 3]];
const conWithEdges = new Constrainautor(del, edges);
// Access the modified triangulation
console.log(con.del.triangles); // Uint32Array of triangle vertex indices
console.log(con.del.halfedges); // Int32Array of half-edge connections
```
### Response Example
```typescript
// The Constrainautor instance is returned, and the Delaunator triangulation is modified in-place.
// Access modified triangulation via con.del
```
```
--------------------------------
### con.constrainAll
Source: https://github.com/kninnug/constrainautor/blob/master/README.md
A shortcut for constraining an array of edges using `constrainOne`. The edges must be provided as an array of point index pairs.
```APIDOC
## con.constrainAll(edges)
### Description
A shortcut to constraining an array of edges by `constrainOne`. The argument `edges` must be an array of arrays of indices into the `points` array originally supplied to Delaunator, i.e: `[[p1, p2], [p3, p4], ...]`. Returns `this`.
NB: since version 4.0.0 this method returns the `Constrainautor` instance, instead of the Delaunator object.
### Method
`con.constrainAll(edges: Array<[number, number]>): Constrainautor`
### Parameters
#### Request Body
- **edges** (Array<[number, number]>) - Required - An array of edges, where each edge is represented by a pair of point indices.
```
--------------------------------
### Constrain a triangulation edge
Source: https://github.com/kninnug/constrainautor/blob/master/README.md
Demonstrates creating a Constrainautor instance from a Delaunator output and forcing a specific edge between two points.
```javascript
// A diamond
const points = [[150, 50], [50, 200], [150, 350], [250, 200]];
// Creates a horizontal edge in the middle
const del = Delaunator.from(points),
const con = new Constrainautor(del);
// .. but we want a vertical edge, from [150, 50] to [150, 350]:
con.constrainOne(0, 2);
// del now has the constrained triangulation, in the same format that
// Delaunator outputs
```
--------------------------------
### con.findEdge
Source: https://github.com/kninnug/constrainautor/blob/master/README.md
Finds the id of the half-edge going from point `p1` to point `p2`. Handles cases where the edge exists in reverse or not at all.
```APIDOC
## con.findEdge(p1, p2)
### Description
Find the id of the half-edge going from `p1` to `p2`. If there is only an edge from `p2` to `p1` (i.e. it is on the hull), it will return the negated id. If there is no edge between `p1` and `p2`, the return value is `Infinity`.
### Method
`con.findEdge(p1: number, p2: number): number`
### Parameters
#### Query Parameters
- **p1** (number) - Required - The index of the starting point.
- **p2** (number) - Required - The index of the ending point.
```
--------------------------------
### findEdge
Source: https://context7.com/kninnug/constrainautor/llms.txt
Finds the half-edge id between two points.
```APIDOC
## findEdge
### Description
Finds the half-edge id that goes from point p1 to point p2. Returns the edge id if found, a negative id if the edge exists but points from p2 to p1 (on hull), or Infinity if no edge exists between the points.
### Parameters
#### Path Parameters
- **p1** (number) - Required - The index of the starting point.
- **p2** (number) - Required - The index of the ending point.
### Response
#### Success Response (200)
- **edgeId** (number) - The id of the half-edge, a negative value if on the hull, or Infinity if not found.
```
--------------------------------
### delaunify
Source: https://context7.com/kninnug/constrainautor/llms.txt
Restores the Delaunay property for non-constrained edges.
```APIDOC
## delaunify
### Description
Restores the Delaunay property for non-constrained edges by flipping edges that violate the Delaunay condition.
### Parameters
#### Path Parameters
- **deep** (boolean) - Optional - If true, performs deep flipping until all edges are Delaunay.
### Response
#### Success Response (200)
- **void** - No return value.
```
--------------------------------
### Constrainautor Constructor
Source: https://github.com/kninnug/constrainautor/blob/master/README.md
Constructs a new Constrainautor instance. The Delaunator object is modified in-place. Optionally, edges can be provided to constrain them during construction.
```APIDOC
## new Constrainautor(del[, edges])
### Description
Construct a new Constrainautor from the given triangulation. The `del` object should be returned from Delaunator, and is modified in-place by the Constrainautor methods. If `edges` is provided, it will constrain those with `constrainAll`.
### Parameters
#### Path Parameters
- **del** (object) - Required - The Delaunator triangulation object.
- **edges** (array of arrays) - Optional - An array of edges to constrain, where each edge is represented by two point indices.
```
--------------------------------
### isConstrained
Source: https://context7.com/kninnug/constrainautor/llms.txt
Checks if a specific half-edge is marked as constrained.
```APIDOC
## isConstrained
### Description
Checks whether a half-edge has been marked as constrained. Returns true if the edge was previously constrained via constrainOne or constrainAll.
### Parameters
#### Path Parameters
- **edgeId** (number) - Required - The id of the half-edge to check.
### Response
#### Success Response (200)
- **isConstrained** (boolean) - Returns true if the edge is constrained, false otherwise.
```
--------------------------------
### constrainAll
Source: https://context7.com/kninnug/constrainautor/llms.txt
Constrains multiple edges at once by calling constrainOne for each edge in the provided array. Returns the Constrainautor instance for method chaining.
```APIDOC
## constrainAll
Constrains multiple edges at once by calling constrainOne for each edge in the provided array. Returns the Constrainautor instance for method chaining.
### Parameters
#### Request Body
- **edges** (Array<[number, number]>) - Required - An array of edges, where each edge is a tuple of two point indices.
### Request Example
```typescript
import Delaunator from 'delaunator';
import Constrainautor from '@kninnug/constrainautor';
// Define a more complex polygon
const points = [
[0, 0], [100, 0], [200, 0], // points 0, 1, 2
[0, 100], [100, 100], [200, 100], // points 3, 4, 5
[0, 200], [100, 200], [200, 200] // points 6, 7, 8
];
const del = Delaunator.from(points);
const con = new Constrainautor(del);
// Define multiple edges to constrain (forming a cross pattern)
const edgesToConstrain: [number, number][] = [
[1, 7], // Vertical line through center
[3, 5], // Horizontal line through center
];
// Constrain all edges at once
con.constrainAll(edgesToConstrain);
// Verify all edges are constrained
for (const [p1, p2] of edgesToConstrain) {
const edgeId = con.findEdge(p1, p2);
console.log(`Edge ${p1}->${p2}: id=${edgeId}, constrained=${con.isConstrained(Math.abs(edgeId))}`);
}
```
### Response Example
```typescript
// Returns the Constrainautor instance for method chaining.
// Example output:
// Edge 1->7: id=3, constrained=true
// Edge 3->5: id=8, constrained=true
```
```
--------------------------------
### Restore Delaunay Property
Source: https://context7.com/kninnug/constrainautor/llms.txt
The delaunify method restores the Delaunay property for non-constrained edges by flipping violating edges. While automatically called by constrainOne, manual invocation (optionally in deep mode) can be useful after direct triangulation modifications.
```typescript
import Delaunator from 'delaunator';
import Constrainautor from '@kninnug/constrainautor';
const points = [
[0, 0], [100, 0], [100, 100], [0, 100], [50, 50]
];
const del = Delaunator.from(points);
const con = new Constrainautor(del);
// Constrain edges (delaunify is called automatically)
con.constrainOne(0, 2);
// Manual delaunify is optional - useful after direct triangulation manipulation
// Pass true for deep mode to keep flipping until all edges are Delaunay
con.delaunify(true);
// Verify Delaunay property holds for non-constrained edges
console.log('Triangulation has been re-Delaunified');
```
--------------------------------
### Constrain multiple edges
Source: https://context7.com/kninnug/constrainautor/llms.txt
Use constrainAll to enforce multiple edges simultaneously, returning the instance for method chaining.
```typescript
import Delaunator from 'delaunator';
import Constrainautor from '@kninnug/constrainautor';
// Define a more complex polygon
const points = [
[0, 0], [100, 0], [200, 0], // points 0, 1, 2
[0, 100], [100, 100], [200, 100], // points 3, 4, 5
[0, 200], [100, 200], [200, 200] // points 6, 7, 8
];
const del = Delaunator.from(points);
const con = new Constrainautor(del);
// Define multiple edges to constrain (forming a cross pattern)
const edges: [number, number][] = [
[1, 7], // Vertical line through center
[3, 5], // Horizontal line through center
];
// Constrain all edges at once
con.constrainAll(edges);
// Verify all edges are constrained
for (const [p1, p2] of edges) {
const edgeId = con.findEdge(p1, p2);
console.log(`Edge ${p1}->${p2}: id=${edgeId}, constrained=${con.isConstrained(Math.abs(edgeId))}`);
}
// Output:
// Edge 1->7: id=3, constrained=true
// Edge 3->5: id=8, constrained=true
```
--------------------------------
### untriangulatedPoints
Source: https://context7.com/kninnug/constrainautor/llms.txt
Retrieves points not included in the triangulation.
```APIDOC
## untriangulatedPoints
### Description
Returns an array of point indices that were not included in the triangulation. This occurs when points are coincident or too close together.
### Response
#### Success Response (200)
- **indices** (Array) - An array of point indices that were skipped during triangulation.
```
--------------------------------
### con.isConstrained
Source: https://github.com/kninnug/constrainautor/blob/master/README.md
Checks if a given half-edge is marked as a constraint edge.
```APIDOC
## con.isConstrained(edg)
### Description
Whether the half-edge with the given id is a constraint edge. Returns true if `edg` was earlier returned by a call to `constrainOne`. Note: this doesn't try to detect if the edge must be a constraint, merely that it has been marked as such by the `Constrainautor` instance.
### Method
`con.isConstrained(edg: number): boolean`
### Parameters
#### Path Parameters
- **edg** (number) - Required - The id of the half-edge to check.
```
--------------------------------
### con.untriangulatedPoints
Source: https://github.com/kninnug/constrainautor/blob/master/README.md
Returns a list of points that were not triangulated by Delaunator, typically due to being too close to other points.
```APIDOC
## con.untriangulatedPoints()
### Description
When two or more points are close together, Delaunator will only triangulate one of them. This method will return a list of points that were not triangulated, i.e. which have no incoming (or outgoing) half-edges. Trying to constrain an edge between points, either of which are not triangulaged, will result in an error being thrown.
### Method
`con.untriangulatedPoints(): Array`
### Response
#### Success Response (200)
- **Array** - A list of indices of points that were not triangulated.
```
--------------------------------
### Check Segment Intersection with Constrainautor
Source: https://context7.com/kninnug/constrainautor/llms.txt
Use Constrainautor.intersectSegments to determine if two line segments intersect. This static method is numerically stable and can be used independently.
```typescript
import Constrainautor from '@kninnug/constrainautor';
// Check if segment (0,0)-(10,10) intersects with (0,10)-(10,0)
const intersects = Constrainautor.intersectSegments(
0, 0, // p1x, p1y - first segment start
10, 10, // p2x, p2y - first segment end
0, 10, // p3x, p3y - second segment start
10, 0 // p4x, p4y - second segment end
);
console.log(`Segments intersect: ${intersects}`); // true (X pattern)
// Non-intersecting parallel segments
const parallel = Constrainautor.intersectSegments(
0, 0, 10, 0, // Horizontal segment at y=0
0, 5, 10, 5 // Horizontal segment at y=5
);
console.log(`Parallel segments intersect: ${parallel}`); // false
// Segments sharing an endpoint (not considered intersecting)
const shared = Constrainautor.intersectSegments(
0, 0, 10, 10, // Segment 1
10, 10, 20, 0 // Segment 2 (shares endpoint)
);
console.log(`Shared endpoint intersects: ${shared}`); // false
```
--------------------------------
### con.delaunify
Source: https://github.com/kninnug/constrainautor/blob/master/README.md
Checks and corrects non-constrained edges to satisfy the Delaunay condition. Can perform a single pass or a deep correction until all edges are Delaunay. Note: Since v4.0.0, this is often unnecessary after constraining edges.
```APIDOC
## con.delaunify([deep = false])
### Description
Checks non-constrained edges if they satisfy the Delaunay condition (for every two triangles sharing an edge, neither lies completely within the circumcircle of the other), and flips the edge if they don't. If `deep` is `true`, it will check & correct until all flipped edges satisfy the condition, otherwise it will do only one pass and some edges may still not be Delaunay.
NB 1: since version 4.0.0 it is no longer necessary (or useful) to call this method after constraining edges, since `constrainOne` will also do it.
NB 2: since version 4.0.0 this method returns `this` instead of `this.del`.
### Method
`con.delaunify(deep?: boolean): Constrainautor`
### Parameters
#### Query Parameters
- **deep** (boolean) - Optional - If `true`, performs deep correction until all edges satisfy the Delaunay condition. Defaults to `false`.
```
--------------------------------
### constrainOne
Source: https://context7.com/kninnug/constrainautor/llms.txt
Constrains a single edge between two points in the triangulation. The points are specified by their indices in the original points array passed to Delaunator. Returns the half-edge id pointing from p1 to p2 (or negative if on hull pointing p2 to p1).
```APIDOC
## constrainOne
Constrains a single edge between two points in the triangulation. The points are specified by their indices in the original points array passed to Delaunator. Returns the half-edge id pointing from p1 to p2 (or negative if on hull pointing p2 to p1).
### Parameters
#### Path Parameters
- **p1** (number) - Required - The index of the first point.
- **p2** (number) - Required - The index of the second point.
### Request Example
```typescript
import Delaunator from 'delaunator';
import Constrainautor from '@kninnug/constrainautor';
// Create a diamond shape
const points = [[150, 50], [50, 200], [150, 350], [250, 200]];
const del = Delaunator.from(points);
const con = new Constrainautor(del);
// Delaunator creates a horizontal edge by default
// Constrain a vertical edge from point 0 [150,50] to point 2 [150,350]
const edgeId = con.constrainOne(0, 2);
console.log(`Constrained edge id: ${edgeId}`);
// The triangulation is now modified in-place
// Iterate over triangles (every 3 indices form a triangle)
for (let i = 0; i < del.triangles.length; i += 3) {
const p1 = del.triangles[i];
const p2 = del.triangles[i + 1];
const p3 = del.triangles[i + 2];
console.log(`Triangle: ${p1} -> ${p2} -> ${p3}`);
}
```
### Response Example
```typescript
// Returns the half-edge id pointing from p1 to p2 (or negative if on hull pointing p2 to p1).
// Example output:
// Constrained edge id: 5
// Triangle: 2 -> 0 -> 1
// Triangle: 0 -> 2 -> 3
```
```
--------------------------------
### Constrain a single edge
Source: https://context7.com/kninnug/constrainautor/llms.txt
Use constrainOne to enforce a specific edge between two point indices. The triangulation is modified in-place.
```typescript
import Delaunator from 'delaunator';
import Constrainautor from '@kninnug/constrainautor';
// Create a diamond shape
const points = [[150, 50], [50, 200], [150, 350], [250, 200]];
const del = Delaunator.from(points);
const con = new Constrainautor(del);
// Delaunator creates a horizontal edge by default
// Constrain a vertical edge from point 0 [150,50] to point 2 [150,350]
const edgeId = con.constrainOne(0, 2);
console.log(`Constrained edge id: ${edgeId}`);
// The triangulation is now modified in-place
// Iterate over triangles (every 3 indices form a triangle)
for (let i = 0; i < del.triangles.length; i += 3) {
const p1 = del.triangles[i];
const p2 = del.triangles[i + 1];
const p3 = del.triangles[i + 2];
console.log(`Triangle: ${p1} -> ${p2} -> ${p3}`);
}
// Output:
// Triangle: 2 -> 0 -> 1
// Triangle: 0 -> 2 -> 3
```
--------------------------------
### Constrainautor.constrainOne
Source: https://github.com/kninnug/constrainautor/blob/master/README.md
Constrains a single edge in the triangulation between two specified points.
```APIDOC
## con.constrainOne(p1, p2)
### Description
Constrain an edge in the triangulation. The arguments `p1` and `p2` must be indices into the `points` array originally supplied to the Delaunator. It returns the id of the half-edge that points from `p1` to `p2`, or the negative id of the half-edge that points from `p2` to `p1`. Note: this half-edge id is only valid up to the next call to `constrainOne`, after which the constrained edge will still be there, but may have a different id.
### Parameters
#### Path Parameters
- **p1** (number) - Required - The index of the first point.
- **p2** (number) - Required - The index of the second point.
### Response
#### Success Response (200)
- **halfEdgeId** (number) - The id of the constrained half-edge.
```
--------------------------------
### Identify Untriangulated Points
Source: https://context7.com/kninnug/constrainautor/llms.txt
Use untriangulatedPoints to find indices of points that Delaunator could not include in the triangulation, often due to proximity or coincidence. Attempting to constrain edges involving these points will result in an error, so it's recommended to check this list first.
```typescript
import Delaunator from 'delaunator';
import Constrainautor from '@kninnug/constrainautor';
// Points with some very close together (may not all be triangulated)
const points = [
[0, 0], [100, 0], [50, 100],
[0, 0.0000001], // Very close to point 0 - may not be triangulated
];
const del = Delaunator.from(points);
const con = new Constrainautor(del);
// Check for untriangulated points before constraining
const untriangulated = con.untriangulatedPoints();
if (untriangulated.length > 0) {
console.log(`Warning: Points not triangulated: ${untriangulated}`);
// Output: Warning: Points not triangulated: [3]
}
// Safe constraining - check first
function safeConstrain(con: Constrainautor, p1: number, p2: number) {
const untri = con.untriangulatedPoints();
if (untri.includes(p1) || untri.includes(p2)) {
console.log(`Cannot constrain: point ${untri.includes(p1) ? p1 : p2} not triangulated`);
return null;
}
return con.constrainOne(p1, p2);
}
safeConstrain(con, 0, 3); // Will warn instead of throwing
safeConstrain(con, 0, 2); // Will succeed
```
--------------------------------
### Check if Edge is Constrained
Source: https://context7.com/kninnug/constrainautor/llms.txt
The isConstrained method checks if a given half-edge ID corresponds to an edge that has been marked as constrained using constrainOne or constrainAll. It returns true if constrained, false otherwise.
```typescript
import Delaunator from 'delaunator';
import Constrainautor from '@kninnug/constrainautor';
const points = [[0, 0], [100, 0], [50, 100], [50, 50]];
const del = Delaunator.from(points);
const con = new Constrainautor(del);
// Constrain one edge
const constrainedEdge = con.constrainOne(0, 2);
// Check constraint status of various edges
console.log(`Edge ${constrainedEdge} constrained: ${con.isConstrained(constrainedEdge)}`);
// Output: Edge X constrained: true
// Check all edges in the triangulation
for (let edg = 0; edg < del.triangles.length; edg++) {
if (con.isConstrained(edg)) {
const p1 = del.triangles[edg];
const p2 = del.triangles[(edg % 3 === 2) ? edg - 2 : edg + 1];
console.log(`Constrained edge ${edg}: point ${p1} -> point ${p2}`);
}
}
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.