Removes duplicate vertices from the polygon. Only successive points are
recognized as duplicates.
@param {Number} tolerance snap distance for finding duplicates
@return itself
488097
function( tolerance ){
            //if tolerance is 0, it will be faster to just use 'equals' method
            var equals = tolerance ? 'equalsWithTolerance' : 'equals';
            var p, prev, i = 0, num = this.vertices.length;
            var last;
            for( ; i<num; i++ ){
                p = this.vertices[i];
                //if its the 'equals' method tolerance will just be ingored
                if( p[equals]( prev, tolerance ) ){
                    //remove from array, step back counter
                    this.vertices.splice( i, 1 );
                    i--;
                    num--;
                } else {
                    prev = p;
                }
            }
            num = this.vertices.length;
            if( num >  0 ){
                last = this.vertices[num-1];
                if( last[equals]( this.vertices[0], tolerance ) ){
                    this.vertices.splice( num-1, 1 );
                }
            }
            return this;
        }
772560
public function reduce( $tolerance )
    {
        $key = 0;
        while ( $key < $this->lastKey(-3) ) {
            $out = $key + 2;
            $pd = $this->shortestDistanceToSegment(
                $this->points[$out],
                $this->points[$key],
                $this->points[$key + 1]
            );
            while ( $out < $this->lastKey() && $pd < $tolerance ) {
                $pd = $this->shortestDistanceToSegment(
                    $this->points[++$out],
                    $this->points[$key],
                    $this->points[$key + 1]
                );
            }
            for ( $i = $key+1, $l = $out - 1; $i < $l; $i++ ) {
                unset($this->points[$i]);
            }
            $this->reindex();
            $key++;
        }
        return $this->points;
    }
900790
static Geometry pointMinusPolygon_(Point point, Polygon polygon,
			double tolerance, ProgressTracker progress_tracker) {
		PolygonUtils.PiPResult result = PolygonUtils.isPointInPolygon2D(
				polygon, point, tolerance);

		if (result == PolygonUtils.PiPResult.PiPOutside)
			return point;

		return point.createInstance();
	}
391089
function(polygon) {
            var result = {
                type: null,
                front: null,
                back: null
            };
            // cache in local vars (speedup):
            var planenormal = this.normal;
            var vertices = polygon.vertices;
            var numvertices = vertices.length;
            if (polygon.plane.equals(this)) {
                result.type = 0;
            } else {
                var EPS = CSG.Plane.EPSILON;
                var thisw = this.w;
                var hasfront = false;
                var hasback = false;
                var vertexIsBack = [];
                var MINEPS = -EPS;
                for (var i = 0; i < numvertices; i++) {
                    var t = planenormal.dot(vertices[i].pos) - thisw;
                    var isback = (t < 0);
                    vertexIsBack.push(isback);
                    if (t > EPS) hasfront = true;
                    if (t < MINEPS) hasback = true;
                }
                if ((!hasfront) && (!hasback)) {
                    // all points coplanar
                    var t = planenormal.dot(polygon.plane.normal);
                    result.type = (t >= 0) ? 0 : 1;
                } else if (!hasback) {
                    result.type = 2;
                } else if (!hasfront) {
                    result.type = 3;
                } else {
                    // spanning
                    result.type = 4;
                    var frontvertices = [],
                        backvertices = [];
                    var isback = vertexIsBack[0];
                    for (var vertexindex = 0; vertexindex < numvertices; vertexindex++) {
                        var vertex = vertices[vertexindex];
                        var nextvertexindex = vertexindex + 1;
                        if (nextvertexindex >= numvertices) nextvertexindex = 0;
                        var nextisback = vertexIsBack[nextvertexindex];
                        if (isback == nextisback) {
                            // line segment is on one side of the plane:
                            if (isback) {
                                backvertices.push(vertex);
                            } else {
                                frontvertices.push(vertex);
                            }
                        } else {
                            // line segment intersects plane:
                            var point = vertex.pos;
                            var nextpoint = vertices[nextvertexindex].pos;
                            var intersectionpoint = this.splitLineBetweenPoints(point, nextpoint);
                            var intersectionvertex = new CSG.Vertex(intersectionpoint);
                            if (isback) {
                                backvertices.push(vertex);
                                backvertices.push(intersectionvertex);
                                frontvertices.push(intersectionvertex);
                            } else {
                                frontvertices.push(vertex);
                                frontvertices.push(intersectionvertex);
                                backvertices.push(intersectionvertex);
                            }
                        }
                        isback = nextisback;
                    } // for vertexindex
                    // remove duplicate vertices:
                    var EPS_SQUARED = CSG.Plane.EPSILON * CSG.Plane.EPSILON;
                    if (backvertices.length >= 3) {
                        var prevvertex = backvertices[backvertices.length - 1];
                        for (var vertexindex = 0; vertexindex < backvertices.length; vertexindex++) {
                            var vertex = backvertices[vertexindex];
                            if (vertex.pos.distanceToSquared(prevvertex.pos) < EPS_SQUARED) {
                                backvertices.splice(vertexindex, 1);
                                vertexindex--;
                            }
                            prevvertex = vertex;
                        }
                    }
                    if (frontvertices.length >= 3) {
                        var prevvertex = frontvertices[frontvertices.length - 1];
                        for (var vertexindex = 0; vertexindex < frontvertices.length; vertexindex++) {
                            var vertex = frontvertices[vertexindex];
                            if (vertex.pos.distanceToSquared(prevvertex.pos) < EPS_SQUARED) {
                                frontvertices.splice(vertexindex, 1);
                                vertexindex--;
                            }
                            prevvertex = vertex;
                        }
                    }
                    if (frontvertices.length >= 3) {
                        result.front = new CSG.Polygon(frontvertices, polygon.shared, polygon.plane);
                    }
                    if (backvertices.length >= 3) {
                        result.back = new CSG.Polygon(backvertices, polygon.shared, polygon.plane);
                    }
                }
            }
            return result;
        }
970659
public static Geometry removePoint(Geometry geometry, Polygon polygon) throws SQLException {
        if(geometry == null){
            return null;
        }
        GeometryEditor localGeometryEditor = new GeometryEditor();
        PolygonDeleteVertexOperation localBoxDeleteVertexOperation = new PolygonDeleteVertexOperation(geometry.getFactory(), new PreparedPolygon(polygon));
        Geometry localGeometry = localGeometryEditor.edit(geometry, localBoxDeleteVertexOperation);
        if (localGeometry.isEmpty()) {
            return null;
        }
        return localGeometry;            
    }
1111669
boolean sweep(EditShape shape, double tolerance) {
		Transformation2D transform = new Transformation2D();
		transform.setSwapCoordinates();
		shape.applyTransformation(transform);// swap coordinates for the sweep
												// along x
		setEditShape_(shape);
		m_b_cracked = false;
		m_tolerance = tolerance;
		m_tolerance_sqr = tolerance * tolerance;

		boolean b_cracked = sweepImpl_();
		shape.applyTransformation(transform);
		if (!b_cracked) {
			fillEventQueuePass2();
			b_cracked |= sweepImpl_();
		}
		
		if (m_vertex_cluster_index != -1) {
			m_shape.removeUserIndex(m_vertex_cluster_index);
			m_vertex_cluster_index = -1;
		}
		
		m_shape = null;
		return m_b_cracked;
	}
1339169
boolean sweepVertical(EditShape shape, double tolerance) {
		setEditShape_(shape);
		m_b_cracked = false;
		m_tolerance = tolerance;
		m_tolerance_sqr = tolerance * tolerance;
		m_complications = false;
		boolean bresult = sweepImpl_();
		if (!m_complications) {
			int filtered = shape.filterClosePoints(tolerance, true, false);
			m_complications = filtered == 1;
			bresult |= filtered == 1;
		}
		
		if (m_vertex_cluster_index != -1) {
			m_shape.removeUserIndex(m_vertex_cluster_index);
			m_vertex_cluster_index = -1;
		}
		
		m_shape = null;
		return bresult;
	}
945467
public static Geometry removeRepeatedPoints(Geometry geometry) throws SQLException, SQLException, SQLException, SQLException {
        return removeDuplicateCoordinates(geometry, 0);
    }
605196
function() {

		var verticesMap = {}; // Hashmap for looking up vertice by position coordinates (and making sure they are unique)
		var unique = [], changes = [];

		var v, key;
		var precisionPoints = 4; // number of decimal points, eg. 4 for epsilon of 0.0001
		var precision = Math.pow( 10, precisionPoints );
		var i,il, face;
		var abcd = 'abcd', o, k, j, jl, u;

		for ( i = 0, il = this.vertices.length; i < il; i ++ ) {

			v = this.vertices[ i ];
			key = [ Math.round( v.x * precision ), Math.round( v.y * precision ), Math.round( v.z * precision ) ].join( '_' );

			if ( verticesMap[ key ] === undefined ) {

				verticesMap[ key ] = i;
				unique.push( this.vertices[ i ] );
				changes[ i ] = unique.length - 1;

			} else {

				//console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);
				changes[ i ] = changes[ verticesMap[ key ] ];

			}

		};


		// Start to patch face indices

		for( i = 0, il = this.faces.length; i < il; i ++ ) {

			face = this.faces[ i ];

			if ( face instanceof THREE.Face3 ) {

				face.a = changes[ face.a ];
				face.b = changes[ face.b ];
				face.c = changes[ face.c ];

			} else if ( face instanceof THREE.Face4 ) {

				face.a = changes[ face.a ];
				face.b = changes[ face.b ];
				face.c = changes[ face.c ];
				face.d = changes[ face.d ];

				// check dups in (a, b, c, d) and convert to -> face3
				o = [face.a, face.b, face.c, face.d];
				for (k=3;k>0;k--) {
					if ( o.indexOf(face[abcd[k]]) != k ) {
						// console.log('faces', face.a, face.b, face.c, face.d, 'dup at', k);
						o.splice(k, 1);
						this.faces[ i ] = new THREE.Face3(o[0], o[1], o[2]);
						for (j=0,jl=this.faceVertexUvs.length;j<jl;j++) {
							u = this.faceVertexUvs[j][i];
							if (u) u.splice(k, 1);
						}
						
						break;
					}
				}


			}

		}

		// Use unique set of vertices
		var diff = this.vertices.length - unique.length;
		this.vertices = unique;
		return diff;

	}
759619
def _remove_duplicate_points(points, groups):
    ''' 

    '''

    group_initial_ids = groups[:, GPFIRST]

    to_be_reduced = np.zeros(len(group_initial_ids))
    to_be_removed = []

    for ig, g in enumerate(groups):
        iid, typ, pid = g[GPFIRST], g[GTYPE], g[GPID]
        # Remove first point from sections that are
        # not the root section, a soma, or a child of a soma
        if pid != -1 and typ != 1 and groups[pid][GTYPE] != 1:
            # Remove duplicate from list of points
            to_be_removed.append(iid)
            # Reduce the id of the following sections
            # in groups structure by one
            to_be_reduced[ig + 1:] += 1

    groups[:, GPFIRST] = groups[:, GPFIRST] - to_be_reduced
    points = np.delete(points, to_be_removed, axis=0)

    return points, groups
210262
private static boolean polygonContainsPoint_(Polygon polygon_a,
			Point point_b, double tolerance, ProgressTracker progress_tracker) {
		Point2D pt_b = point_b.getXY();
		return polygonContainsPointImpl_(polygon_a, pt_b, tolerance,
				progress_tracker);
	}
1062426
private static boolean multiPointCoverageMultiPoint_(
			MultiPoint _multipointA, MultiPoint _multipointB, double tolerance,
			boolean bPerformWithin, boolean bPerformEquals,
			boolean bPerformOverlaps, ProgressTracker progress_tracker) {
		boolean bPerformContains = false;
		MultiPoint multipoint_a;
		MultiPoint multipoint_b;

		if (_multipointA.getPointCount() > _multipointB.getPointCount()) {
			if (bPerformWithin) {
				bPerformWithin = false;
				bPerformContains = true;
			}

			multipoint_a = _multipointB;
			multipoint_b = _multipointA;
		} else {
			multipoint_a = _multipointA;
			multipoint_b = _multipointB;
		}

		AttributeStreamOfInt8 contained = null;

		if (bPerformEquals || bPerformOverlaps || bPerformContains) {
			contained = new AttributeStreamOfInt8(multipoint_b.getPointCount());

			for (int i = 0; i < multipoint_b.getPointCount(); i++)
				contained.write(i, (byte) 0);
		}

		Envelope2D env_a = new Envelope2D();
		Envelope2D env_b = new Envelope2D();
		Envelope2D envInter = new Envelope2D();
		multipoint_a.queryEnvelope2D(env_a);
		multipoint_b.queryEnvelope2D(env_b);
		env_a.inflate(tolerance, tolerance);
		env_b.inflate(tolerance, tolerance);
		envInter.setCoords(env_a);
		envInter.intersect(env_b);

		Point2D ptA = new Point2D();
		Point2D ptB = new Point2D();

		boolean bWithin = true; // starts off true by default

		QuadTreeImpl quadTreeB = InternalUtils.buildQuadTree(
				(MultiPointImpl) (multipoint_b._getImpl()), envInter);
		QuadTreeImpl.QuadTreeIteratorImpl qtIterB = quadTreeB.getIterator();
		double tolerance_sq = tolerance * tolerance;

		for (int vertex_a = 0; vertex_a < multipoint_a.getPointCount(); vertex_a++) {
			multipoint_a.getXY(vertex_a, ptA);

			if (!envInter.contains(ptA)) {
				if (bPerformEquals || bPerformWithin)
					return false;
				else {
					bWithin = false;
					continue;
				}
			}

			boolean bPtACovered = false;
			env_a.setCoords(ptA.x, ptA.y, ptA.x, ptA.y);
			qtIterB.resetIterator(env_a, tolerance);
			for (int elementHandleB = qtIterB.next(); elementHandleB != -1; elementHandleB = qtIterB
					.next()) {
				int vertex_b = quadTreeB.getElement(elementHandleB);
				multipoint_b.getXY(vertex_b, ptB);

				if (Point2D.sqrDistance(ptA, ptB) <= tolerance_sq) {
					if (bPerformEquals || bPerformOverlaps || bPerformContains)
						contained.write(vertex_b, (byte) 1);

					bPtACovered = true;

					if (bPerformWithin)
						break;
				}
			}

			if (!bPtACovered) {
				bWithin = false;

				if (bPerformEquals || bPerformWithin)
					return false;
			}
		}

		if (bPerformOverlaps && bWithin)
			return false;

		if (bPerformWithin)
			return true;

		for (int i = 0; i < multipoint_b.getPointCount(); i++) {
			if (contained.read(i) == 1) {
				if (bPerformOverlaps)
					return true;
			} else {
				if (bPerformEquals || bPerformContains)
					return false;
			}
		}

		if (bPerformOverlaps)
			return false;

		return true;
	}
359101
static boolean executeNonReciprocal(EditShape shape, double tolerance) {
		Clusterer clusterer = new Clusterer();
		clusterer.m_shape = shape;
		clusterer.m_tolerance = tolerance;
		clusterer.m_sqr_tolerance = tolerance * tolerance;
		clusterer.m_cell_size = 2 * tolerance;
		clusterer.m_inv_cell_size = 1.0 / clusterer.m_cell_size;
		return clusterer.clusterNonReciprocal_();
	}
632480
public static boolean isPointNearPoint(LatLng point, LatLng shapePoint, double tolerance) {
        return SphericalUtil.computeDistanceBetween(point, shapePoint) <= tolerance;
    }
1222388
function snapRound (points, edges, useColor) {
  // 1. find edge crossings
  var edgeBounds = boundEdges(points, edges)
  var crossings = getCrossings(points, edges, edgeBounds)

  // 2. find t-junctions
  var vertBounds = boundPoints(points)
  var tjunctions = getTJunctions(points, edges, edgeBounds, vertBounds)

  // 3. cut edges, construct rational points
  var ratPoints = cutEdges(points, edges, crossings, tjunctions, useColor)

  // 4. dedupe verts
  var labels = dedupPoints(points, ratPoints, vertBounds)

  // 5. dedupe edges
  dedupEdges(edges, labels, useColor)

  // 6. check termination
  if (!labels) {
    return (crossings.length > 0 || tjunctions.length > 0)
  }

  // More iterations necessary
  return true
}
912425
public static GeometryCollection removeDuplicateCoordinates(GeometryCollection geometryCollection, double tolerance) throws SQLException {
        ArrayList<Geometry> geoms = new ArrayList<>();
        for (int i = 0; i < geometryCollection.getNumGeometries(); i++) {
            Geometry geom = geometryCollection.getGeometryN(i);
            geoms.add(removeDuplicateCoordinates(geom, tolerance));
        }
        return FACTORY.createGeometryCollection(GeometryFactory.toGeometryArray(geoms));
    }
1268690
function () {

		var verticesMap = {}; // Hashmap for looking up vertice by position coordinates (and making sure they are unique)
		var unique = [], changes = [];

		var v, key;
		var precisionPoints = 4; // number of decimal points, eg. 4 for epsilon of 0.0001
		var precision = Math.pow( 10, precisionPoints );
		var i,il, face;
		var indices, k, j, jl, u;

		for ( i = 0, il = this.vertices.length; i < il; i ++ ) {

			v = this.vertices[ i ];
			key = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision );

			if ( verticesMap[ key ] === undefined ) {

				verticesMap[ key ] = i;
				unique.push( this.vertices[ i ] );
				changes[ i ] = unique.length - 1;

			} else {

				//console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);
				changes[ i ] = changes[ verticesMap[ key ] ];

			}

		};


		// if faces are completely degenerate after merging vertices, we
		// have to remove them from the geometry.
		var faceIndicesToRemove = [];

		for( i = 0, il = this.faces.length; i < il; i ++ ) {

			face = this.faces[ i ];

			face.a = changes[ face.a ];
			face.b = changes[ face.b ];
			face.c = changes[ face.c ];

			indices = [ face.a, face.b, face.c ];

			var dupIndex = -1;

			// if any duplicate vertices are found in a Face3
			// we have to remove the face as nothing can be saved
			for ( var n = 0; n < 3; n ++ ) {
				if ( indices[ n ] == indices[ ( n + 1 ) % 3 ] ) {

					dupIndex = n;
					faceIndicesToRemove.push( i );
					break;

				}
			}

		}

		for ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) {
			var idx = faceIndicesToRemove[ i ];

			this.faces.splice( idx, 1 );

			for ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {

				this.faceVertexUvs[ j ].splice( idx, 1 );

			}

		}

		// Use unique set of vertices

		var diff = this.vertices.length - unique.length;
		this.vertices = unique;
		return diff;

	}