### 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.