@flatten-js/core
Advanced tools
Comparing version 1.4.8 to 1.5.0
@@ -464,6 +464,8 @@ // Type definitions for flatten-js library | ||
readonly box: Box; | ||
readonly isSegment: boolean; | ||
readonly isArc: boolean; | ||
readonly isLine: boolean; | ||
readonly isRay: boolean | ||
// public methods | ||
isSegment() : boolean; | ||
isArc() : boolean; | ||
contains(pt: Point): boolean; | ||
@@ -540,3 +542,2 @@ middle(): Point; | ||
cut(multiline: Multiline): Polygon[]; | ||
cutFace(pt1: Point, pt2: Point): [Polygon, Polygon]; | ||
cutWithLine(line: Line): Polygon; | ||
@@ -543,0 +544,0 @@ findEdgeByPoint(pt: Point): PolygonEdge; |
@@ -37,4 +37,4 @@ /** | ||
export {CCW, CW, ORIENTATION, INSIDE, OUTSIDE, BOUNDARY} from './src/utils/constants'; | ||
export {CCW, CW, ORIENTATION, INSIDE, OUTSIDE, BOUNDARY, OVERLAP_SAME, OVERLAP_OPPOSITE} from './src/utils/constants'; | ||
export default Flatten; |
{ | ||
"name": "@flatten-js/core", | ||
"version": "1.4.8", | ||
"version": "1.5.0", | ||
"description": "Javascript library for 2d geometry", | ||
@@ -5,0 +5,0 @@ "main": "dist/main.cjs", |
@@ -427,15 +427,19 @@ /** | ||
export function intersectEdge2Segment(edge, segment) { | ||
return edge.isSegment() ? intersectSegment2Segment(edge.shape, segment) : intersectSegment2Arc(segment, edge.shape); | ||
return edge.isSegment ? intersectSegment2Segment(edge.shape, segment) : intersectSegment2Arc(segment, edge.shape); | ||
} | ||
export function intersectEdge2Arc(edge, arc) { | ||
return edge.isSegment() ? intersectSegment2Arc(edge.shape, arc) : intersectArc2Arc(edge.shape, arc); | ||
return edge.isSegment ? intersectSegment2Arc(edge.shape, arc) : intersectArc2Arc(edge.shape, arc); | ||
} | ||
export function intersectEdge2Line(edge, line) { | ||
return edge.isSegment() ? intersectSegment2Line(edge.shape, line) : intersectLine2Arc(line, edge.shape); | ||
return edge.isSegment ? intersectSegment2Line(edge.shape, line) : intersectLine2Arc(line, edge.shape); | ||
} | ||
export function intersectEdge2Ray(edge, ray) { | ||
return edge.isSegment ? intersectRay2Segment(ray, edge.shape) : intersectRay2Arc(ray, edge.shape); | ||
} | ||
export function intersectEdge2Circle(edge, circle) { | ||
return edge.isSegment() ? intersectSegment2Circle(edge.shape, circle) : intersectArc2Circle(edge.shape, circle); | ||
return edge.isSegment ? intersectSegment2Circle(edge.shape, circle) : intersectArc2Circle(edge.shape, circle); | ||
} | ||
@@ -502,7 +506,15 @@ | ||
export function intersectEdge2Edge(edge1, edge2) { | ||
const shape1 = edge1.shape; | ||
const shape2 = edge2.shape; | ||
return edge1.isSegment() ? | ||
(edge2.isSegment() ? intersectSegment2Segment(shape1, shape2) : intersectSegment2Arc(shape1, shape2)) : | ||
(edge2.isSegment() ? intersectSegment2Arc(shape2, shape1) : intersectArc2Arc(shape1, shape2)); | ||
if (edge1.isSegment) { | ||
return intersectEdge2Segment(edge2, edge1.shape) | ||
} | ||
else if (edge1.isArc) { | ||
return intersectEdge2Arc(edge2, edge1.shape) | ||
} | ||
else if (edge1.isLine) { | ||
return intersectEdge2Line(edge2, edge1.shape) | ||
} | ||
else if (edge1.isRay) { | ||
return intersectEdge2Ray(edge2, edge1.shape) | ||
} | ||
return [] | ||
} | ||
@@ -520,5 +532,14 @@ | ||
for (let resp_edge of resp_edges) { | ||
for (let pt of intersectEdge2Edge(edge, resp_edge)) { | ||
ip.push(pt); | ||
if (resp_edge.isSegment) { | ||
ip = [...ip, ...intersectSegment2Polygon(resp_edge, polygon)] | ||
} | ||
else if (resp_edge.isArc) { | ||
ip = [...ip, ...intersectArc2Polygon(resp_edge, polygon)] | ||
} | ||
else if (resp_edge.isLine) { | ||
ip = [...ip, ...intersectLine2Polygon(resp_edge, polygon)] | ||
} | ||
else if (resp_edge.isRay) { | ||
ip = [...ip, ...intersectRay2Polygon(resp_edge, polygon)] | ||
} | ||
} | ||
@@ -525,0 +546,0 @@ |
@@ -206,3 +206,3 @@ /* | ||
denim.E2I = new Flatten.Polygon([circle.toArc()]).cut(multiline); | ||
denim.E2I = new Flatten.Polygon([circle.toArc()]).cutWithLine(line); | ||
} | ||
@@ -249,3 +249,3 @@ | ||
denim.E2I = new Flatten.Polygon(box.toSegments()).cut(multiline); | ||
denim.E2I = new Flatten.Polygon(box.toSegments()).cutWithLine(line); | ||
} | ||
@@ -270,3 +270,3 @@ } | ||
denim.E2I = polygon.cut(multiline); | ||
denim.E2I = polygon.cutWithLine(line); | ||
@@ -273,0 +273,0 @@ return denim; |
@@ -96,10 +96,18 @@ /** | ||
isSegment() { | ||
get isSegment() { | ||
return this.shape instanceof Flatten.Segment; | ||
} | ||
isArc() { | ||
get isArc() { | ||
return this.shape instanceof Flatten.Arc; | ||
} | ||
get isLine() { | ||
return this.shape instanceof Flatten.Line; | ||
} | ||
get isRay() { | ||
return this.shape instanceof Flatten.Ray | ||
} | ||
/** | ||
@@ -106,0 +114,0 @@ * Get middle point of the edge |
@@ -286,3 +286,3 @@ /** | ||
if (pt instanceof Flatten.Point) { | ||
return [new Flatten.Ray(pt, this.norm.invert()), new Flatten.Ray(pt, this.norm)] | ||
return [new Flatten.Ray(pt, this.norm), new Flatten.Ray(pt, this.norm)] | ||
} | ||
@@ -289,0 +289,0 @@ else { |
@@ -5,3 +5,2 @@ "use strict"; | ||
import LinkedList from '../data_structures/linked_list'; | ||
import {END_VERTEX, NOT_VERTEX, START_VERTEX} from "../utils/constants"; | ||
import {convertToString} from "../utils/attributes"; | ||
@@ -21,6 +20,6 @@ | ||
if (args.length == 1) { | ||
if (args.length === 1) { | ||
if (args[0] instanceof Array) { | ||
let shapes = args[0]; | ||
if (shapes.length == 0) | ||
if (shapes.length === 0) | ||
return; | ||
@@ -42,2 +41,4 @@ | ||
} | ||
this.setArcLength() | ||
} | ||
@@ -60,3 +61,3 @@ } | ||
get box() { | ||
return this.edges.reduce( (acc,edge) => acc = acc.merge(edge.box), new Flatten.Box() ); | ||
return this.edges.reduce( (acc,edge) => acc.merge(edge.box), new Flatten.Box() ); | ||
} | ||
@@ -83,2 +84,20 @@ | ||
/** | ||
* Set arc_length property for each of the edges in the face. | ||
* Arc_length of the edge it the arc length from the first edge of the face | ||
*/ | ||
setArcLength() { | ||
for (let edge of this) { | ||
this.setOneEdgeArcLength(edge); | ||
} | ||
} | ||
setOneEdgeArcLength(edge) { | ||
if (edge === this.first) { | ||
edge.arc_length = 0.0; | ||
} else { | ||
edge.arc_length = edge.prev.arc_length + edge.prev.length; | ||
} | ||
} | ||
/** | ||
* Split edge and add new vertex, return new edge inserted | ||
@@ -111,2 +130,10 @@ * @param {Point} pt - point on edge that will be added as new vertex | ||
getChain(edgeFrom, edgeTo) { | ||
let edges = [] | ||
for (let edge = edgeFrom; edge !== edgeTo.next; edge = edge.next) { | ||
edges.push(edge) | ||
} | ||
return edges | ||
} | ||
/** | ||
@@ -113,0 +140,0 @@ * Split edges of multiline with intersection points and return mutated multiline |
@@ -14,7 +14,7 @@ /** | ||
addToIntPoints, calculateInclusionFlags, filterDuplicatedIntersections, | ||
getSortedArray, getSortedArrayOnLine, initializeInclusionFlags, insertBetweenIntPoints, | ||
getSortedArray, initializeInclusionFlags, insertBetweenIntPoints, | ||
splitByIntersections | ||
} from "../data_structures/smart_intersections"; | ||
import {Multiline} from "./multiline"; | ||
import {intersectEdge2Line} from "../algorithms/intersection"; | ||
import {intersectEdge2Edge} from "../algorithms/intersection"; | ||
import {INSIDE, BOUNDARY} from "../utils/constants"; | ||
@@ -295,94 +295,9 @@ import {convertToString} from "../utils/attributes"; | ||
/** | ||
* Cut polygon with multiline and return array of new polygons | ||
* Multiline should be constructed from a line with intersection point, see notebook: | ||
* https://next.observablehq.com/@alexbol99/cut-polygon-with-line | ||
* Cut polygon with multiline and return a new polygon | ||
* @param {Multiline} multiline | ||
* @returns {Polygon[]} | ||
* @returns {Polygon} | ||
*/ | ||
cut(multiline) { | ||
let cutPolygons = [this.clone()]; | ||
for (let edge of multiline) { | ||
if (edge.setInclusion(this) !== INSIDE) | ||
continue; | ||
let newPoly = this.clone() | ||
let cut_edge_start = edge.shape.start; | ||
let cut_edge_end = edge.shape.end; | ||
let newCutPolygons = []; | ||
for (let polygon of cutPolygons) { | ||
if (polygon.findEdgeByPoint(cut_edge_start) === undefined) { | ||
newCutPolygons.push(polygon); | ||
} else { | ||
let [cutPoly1, cutPoly2] = polygon.cutFace(cut_edge_start, cut_edge_end); | ||
newCutPolygons.push(cutPoly1, cutPoly2); | ||
} | ||
} | ||
cutPolygons = newCutPolygons; | ||
} | ||
return cutPolygons; | ||
} | ||
/** | ||
* Cut face of polygon with a segment between two points and create two new polygons | ||
* Supposed that a segments between points does not intersect any other edge | ||
* @param {Point} pt1 | ||
* @param {Point} pt2 | ||
* @returns {Polygon[]} | ||
*/ | ||
cutFace(pt1, pt2) { | ||
let edge1 = this.findEdgeByPoint(pt1); | ||
let edge2 = this.findEdgeByPoint(pt2); | ||
if (edge1.face !== edge2.face) | ||
return []; | ||
// Cut face into two and create new polygon with two faces | ||
let edgeBefore1 = this.addVertex(pt1, edge1); | ||
edge2 = this.findEdgeByPoint(pt2); | ||
let edgeBefore2 = this.addVertex(pt2, edge2); | ||
let face = edgeBefore1.face; | ||
let newEdge1 = new Flatten.Edge( | ||
new Flatten.Segment(edgeBefore1.end, edgeBefore2.end) | ||
); | ||
let newEdge2 = new Flatten.Edge( | ||
new Flatten.Segment(edgeBefore2.end, edgeBefore1.end) | ||
); | ||
// Swap links | ||
edgeBefore1.next.prev = newEdge2; | ||
newEdge2.next = edgeBefore1.next; | ||
edgeBefore1.next = newEdge1; | ||
newEdge1.prev = edgeBefore1; | ||
edgeBefore2.next.prev = newEdge1; | ||
newEdge1.next = edgeBefore2.next; | ||
edgeBefore2.next = newEdge2; | ||
newEdge2.prev = edgeBefore2; | ||
// Insert new edge to the edges container and 2d index | ||
this.edges.add(newEdge1); | ||
this.edges.add(newEdge2); | ||
// Add two new faces | ||
let face1 = this.addFace(newEdge1, edgeBefore1); | ||
let face2 = this.addFace(newEdge2, edgeBefore2); | ||
// Remove old face | ||
this.faces.delete(face); | ||
return [face1.toPolygon(), face2.toPolygon()]; | ||
} | ||
/** | ||
* Return a result of cutting polygon with line | ||
* @param {Line} line - cutting line | ||
* @returns {Polygon} newPoly - resulted polygon | ||
*/ | ||
cutWithLine(line) { | ||
let newPoly = this.clone(); | ||
let multiline = new Multiline([line]); | ||
// smart intersections | ||
@@ -396,10 +311,12 @@ let intersections = { | ||
// intersect line with each edge of the polygon | ||
// intersect each edge of multiline with each edge of the polygon | ||
// and create smart intersections | ||
for (let edge of newPoly.edges) { | ||
let ip = intersectEdge2Line(edge, line); | ||
// for each intersection point | ||
for (let pt of ip) { | ||
addToIntPoints(multiline.first, pt, intersections.int_points1); | ||
addToIntPoints(edge, pt, intersections.int_points2); | ||
for (let edge1 of multiline.edges) { | ||
for (let edge2 of newPoly.edges) { | ||
let ip = intersectEdge2Edge(edge1, edge2); | ||
// for each intersection point | ||
for (let pt of ip) { | ||
addToIntPoints(edge1, pt, intersections.int_points1); | ||
addToIntPoints(edge2, pt, intersections.int_points2); | ||
} | ||
} | ||
@@ -413,3 +330,3 @@ } | ||
// sort smart intersections | ||
intersections.int_points1_sorted = getSortedArrayOnLine(line, intersections.int_points1); | ||
intersections.int_points1_sorted = getSortedArray(intersections.int_points1); | ||
intersections.int_points2_sorted = getSortedArray(intersections.int_points2); | ||
@@ -425,3 +342,3 @@ | ||
// sort intersection points again after filtering | ||
intersections.int_points1_sorted = getSortedArrayOnLine(line, intersections.int_points1); | ||
intersections.int_points1_sorted = getSortedArray(intersections.int_points1); | ||
intersections.int_points2_sorted = getSortedArray(intersections.int_points2); | ||
@@ -437,3 +354,4 @@ | ||
for (let int_point1 of intersections.int_points1_sorted) { | ||
if (int_point1.edge_before.bv === int_point1.edge_after.bv) { | ||
if (int_point1.edge_before && int_point1.edge_after && | ||
int_point1.edge_before.bv === int_point1.edge_after.bv) { | ||
intersections.int_points2[int_point1.id] = -1; // to be filtered out | ||
@@ -451,19 +369,27 @@ int_point1.id = -1; // to be filtered out | ||
// sort intersection points 3d time after filtering | ||
intersections.int_points1_sorted = getSortedArrayOnLine(line, intersections.int_points1); | ||
intersections.int_points1_sorted = getSortedArray(intersections.int_points1); | ||
intersections.int_points2_sorted = getSortedArray(intersections.int_points2); | ||
// Add 2 new inner edges between intersection points | ||
let int_point1_prev = intersections.int_points1[0]; | ||
let new_edge; | ||
for (let int_point1_curr of intersections.int_points1_sorted) { | ||
if (int_point1_curr.edge_before.bv === INSIDE) { | ||
new_edge = new Flatten.Edge(new Flatten.Segment(int_point1_prev.pt, int_point1_curr.pt)); // (int_point1_curr.edge_before.shape); | ||
insertBetweenIntPoints(intersections.int_points2[int_point1_prev.id], intersections.int_points2[int_point1_curr.id], new_edge); | ||
newPoly.edges.add(new_edge); | ||
// Add new inner edges between intersection points | ||
let int_point1_prev | ||
let int_point1_curr; | ||
for (let i = 1; i < intersections.int_points1_sorted.length; i++) { | ||
int_point1_curr = intersections.int_points1_sorted[i] | ||
int_point1_prev = intersections.int_points1_sorted[i-1]; | ||
if (int_point1_curr.edge_before && int_point1_curr.edge_before.bv === INSIDE) { | ||
let edgeFrom = int_point1_prev.edge_after | ||
let edgeTo = int_point1_curr.edge_before | ||
let newEdges = multiline.getChain(edgeFrom, edgeTo) | ||
insertBetweenIntPoints(intersections.int_points2[int_point1_prev.id], intersections.int_points2[int_point1_curr.id], newEdges); | ||
newEdges.forEach(edge => newPoly.edges.add(edge)) | ||
new_edge = new Flatten.Edge(new Flatten.Segment(int_point1_curr.pt, int_point1_prev.pt)); // (int_point1_curr.edge_before.shape.reverse()); | ||
insertBetweenIntPoints(intersections.int_points2[int_point1_curr.id], intersections.int_points2[int_point1_prev.id], new_edge); | ||
newPoly.edges.add(new_edge); | ||
newEdges = newEdges.reverse().map(edge => new Flatten.Edge(edge.shape.reverse())) | ||
for (let k=0; k < newEdges.length-1; k++) { | ||
newEdges[k].next = newEdges[k+1] | ||
newEdges[k+1].prev = newEdges[k] | ||
} | ||
insertBetweenIntPoints(intersections.int_points2[int_point1_curr.id], intersections.int_points2[int_point1_prev.id], newEdges); | ||
newEdges.forEach(edge => newPoly.edges.add(edge)); | ||
} | ||
int_point1_prev = int_point1_curr; | ||
} | ||
@@ -473,6 +399,18 @@ | ||
newPoly.recreateFaces(); | ||
return newPoly; | ||
return newPoly | ||
} | ||
/** | ||
* A special case of cut() function | ||
* The return is a polygon cut with line | ||
* @param {Line} line - cutting line | ||
* @returns {Polygon} newPoly - resulted polygon | ||
*/ | ||
cutWithLine(line) { | ||
let multiline = new Multiline([line]); | ||
return this.cut(multiline); | ||
} | ||
/** | ||
* Returns the first found edge of polygon that contains given point | ||
@@ -494,4 +432,4 @@ * If point is a vertex, return the edge where the point is an end vertex, not a start one | ||
/** | ||
* Split polygon into array of polygons, where each polygon is an island with all | ||
* hole that it contains | ||
* Split polygon into array of polygons, where each polygon is an outer face with all | ||
* containing inner faces | ||
* @returns {Flatten.Polygon[]} | ||
@@ -498,0 +436,0 @@ */ |
@@ -7,2 +7,3 @@ "use strict"; | ||
import {Errors} from "../utils/errors"; | ||
import {vector} from './vector' | ||
@@ -116,2 +117,14 @@ /** | ||
/** | ||
* Return coordinate of the point that lies on the ray in the transformed | ||
* coordinate system where center is the projection of the point(0,0) to | ||
* the line containing this ray and axe y is collinear to the normal vector. <br/> | ||
* This method assumes that point lies on the ray | ||
* @param {Point} pt - point on a ray | ||
* @returns {number} | ||
*/ | ||
coord(pt) { | ||
return vector(pt.x, pt.y).cross(this.norm); | ||
} | ||
/** | ||
* Split ray with point and return array of segment and new ray | ||
@@ -118,0 +131,0 @@ * @param {Point} pt |
@@ -35,3 +35,11 @@ /* | ||
// Fix intersection point which is end point of the last edge | ||
let arc_length = (is_vertex & Constants.END_VERTEX) && edge.next.arc_length === 0 ? 0 : edge.arc_length + len; | ||
let arc_length | ||
if (len === Infinity) { | ||
arc_length = shapes[0].coord(pt) | ||
} | ||
else { | ||
arc_length = (is_vertex & Constants.END_VERTEX) && edge.next && edge.next.arc_length === 0 ? | ||
0 : | ||
edge.arc_length + len; | ||
} | ||
@@ -99,13 +107,13 @@ int_points.push({ | ||
export function getSortedArrayOnLine(line, int_points) { | ||
return int_points.slice().sort( (int_point1, int_point2) => { | ||
if (line.coord(int_point1.pt) < line.coord(int_point2.pt)) { | ||
return -1; | ||
} | ||
if (line.coord(int_point1.pt) > line.coord(int_point2.pt)) { | ||
return 1; | ||
} | ||
return 0; | ||
}) | ||
} | ||
// export function getSortedArrayOnLine(line, int_points) { | ||
// return int_points.slice().sort( (int_point1, int_point2) => { | ||
// if (line.coord(int_point1.pt) < line.coord(int_point2.pt)) { | ||
// return -1; | ||
// } | ||
// if (line.coord(int_point1.pt) > line.coord(int_point2.pt)) { | ||
// return 1; | ||
// } | ||
// return 0; | ||
// }) | ||
// } | ||
@@ -158,6 +166,6 @@ export function filterDuplicatedIntersections(intersections) | ||
if (int_point_cur2.id == -1) continue; | ||
if (int_point_cur2.id === -1) continue; | ||
/* already deleted */ | ||
if (int_point_ref2.id == -1 || /* can't be reference if already deleted */ | ||
if (int_point_ref2.id === -1 || /* can't be reference if already deleted */ | ||
!(Utils.EQ(int_point_cur2.arc_length, int_point_ref2.arc_length))) { | ||
@@ -195,16 +203,20 @@ int_point_ref2 = int_point_cur2; | ||
for (let int_point of int_points) { | ||
int_point.edge_before.bvStart = undefined; | ||
int_point.edge_before.bvEnd = undefined; | ||
int_point.edge_before.bv = undefined; | ||
int_point.edge_before.overlap = undefined; | ||
if (int_point.edge_before) { | ||
int_point.edge_before.bvStart = undefined; | ||
int_point.edge_before.bvEnd = undefined; | ||
int_point.edge_before.bv = undefined; | ||
int_point.edge_before.overlap = undefined; | ||
} | ||
int_point.edge_after.bvStart = undefined; | ||
int_point.edge_after.bvEnd = undefined; | ||
int_point.edge_after.bv = undefined; | ||
int_point.edge_after.overlap = undefined; | ||
if (int_point.edge_after) { | ||
int_point.edge_after.bvStart = undefined; | ||
int_point.edge_after.bvEnd = undefined; | ||
int_point.edge_after.bv = undefined; | ||
int_point.edge_after.overlap = undefined; | ||
} | ||
} | ||
for (let int_point of int_points) { | ||
int_point.edge_before.bvEnd = Constants.BOUNDARY; | ||
int_point.edge_after.bvStart = Constants.BOUNDARY; | ||
if (int_point.edge_before) int_point.edge_before.bvEnd = Constants.BOUNDARY; | ||
if (int_point.edge_after) int_point.edge_after.bvStart = Constants.BOUNDARY; | ||
} | ||
@@ -216,4 +228,4 @@ } | ||
for (let int_point of int_points) { | ||
int_point.edge_before.setInclusion(polygon); | ||
int_point.edge_after.setInclusion(polygon); | ||
if (int_point.edge_before) int_point.edge_before.setInclusion(polygon); | ||
if (int_point.edge_after) int_point.edge_after.setInclusion(polygon); | ||
} | ||
@@ -305,3 +317,3 @@ } | ||
if (int_points.length == 1) return 1; | ||
if (int_points.length === 1) return 1; | ||
@@ -311,3 +323,3 @@ int_point_current = int_points[cur_int_point_num]; | ||
for (let i = cur_int_point_num + 1; i < int_points.length; i++) { | ||
if (int_point_current.face != cur_face) { /* next face started */ | ||
if (int_point_current.face !== cur_face) { /* next face started */ | ||
break; | ||
@@ -345,4 +357,10 @@ } | ||
if (int_point.is_vertex & Constants.START_VERTEX) { // nothing to split | ||
int_point.edge_before = edge.prev; | ||
int_point.is_vertex = Constants.END_VERTEX; | ||
if (edge.prev) { | ||
int_point.edge_before = edge.prev; // polygon | ||
int_point.is_vertex = Constants.END_VERTEX; | ||
} | ||
else { // multiline start vertex | ||
int_point.edge_after = int_point.edge_before | ||
int_point.edge_before = edge.prev | ||
} | ||
continue; | ||
@@ -359,15 +377,17 @@ } | ||
for (let int_point of int_points) { | ||
int_point.edge_after = int_point.edge_before.next; | ||
if (int_point.edge_before) { | ||
int_point.edge_after = int_point.edge_before.next; | ||
} | ||
} | ||
} | ||
export function insertBetweenIntPoints(int_point1, int_point2, new_edge) { | ||
let edge_before = int_point1.edge_before; | ||
let edge_after = int_point2.edge_after; | ||
export function insertBetweenIntPoints(int_point1, int_point2, new_edges) { | ||
const edge_before = int_point1.edge_before; | ||
const edge_after = int_point2.edge_after; | ||
const len = new_edges.length | ||
edge_before.next = new_edges[0]; | ||
new_edges[0].prev = edge_before; | ||
edge_before.next = new_edge; | ||
new_edge.prev = edge_before; | ||
new_edge.next = edge_after; | ||
edge_after.prev = new_edge; | ||
new_edges[len-1].next = edge_after; | ||
edge_after.prev = new_edges[len-1]; | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1200750
30794