// these are special implementations, all others delegate to the topo-graph.
 internal static com.epl.geometry.Geometry PointMinusPolygon_(com.epl.geometry.Point point, com.epl.geometry.Polygon polygon, double tolerance, com.epl.geometry.ProgressTracker progress_tracker)
 {
     com.epl.geometry.PolygonUtils.PiPResult result = com.epl.geometry.PolygonUtils.IsPointInPolygon2D(polygon, point, tolerance);
     if (result == com.epl.geometry.PolygonUtils.PiPResult.PiPOutside)
     {
         return(point);
     }
     return(point.CreateInstance());
 }
 // return the input point
 internal static com.epl.geometry.Geometry PointMinusEnvelope_(com.epl.geometry.Point point, com.epl.geometry.Envelope envelope, double tolerance, com.epl.geometry.ProgressTracker progress_tracker)
 {
     com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
     envelope.QueryEnvelope2D(env);
     env.Inflate(tolerance, tolerance);
     com.epl.geometry.Point2D pt = point.GetXY();
     if (!env.Contains(pt))
     {
         return(point);
     }
     return(point.CreateInstance());
 }
        internal static com.epl.geometry.Geometry PointMinusPolyline_(com.epl.geometry.Point point, com.epl.geometry.Polyline polyline, double tolerance, com.epl.geometry.ProgressTracker progress_tracker)
        {
            com.epl.geometry.Point2D         pt       = point.GetXY();
            com.epl.geometry.SegmentIterator seg_iter = polyline.QuerySegmentIterator();
            double tolerance_cluster    = tolerance * System.Math.Sqrt(2.0) * 1.00001;
            double tolerance_cluster_sq = tolerance_cluster * tolerance_cluster;

            com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
            while (seg_iter.NextPath())
            {
                while (seg_iter.HasNextSegment())
                {
                    com.epl.geometry.Segment segment = seg_iter.NextSegment();
                    segment.QueryEnvelope2D(env);
                    env.Inflate(tolerance_cluster, tolerance_cluster);
                    if (!env.Contains(pt))
                    {
                        continue;
                    }
                    if (segment.IsIntersecting(pt, tolerance))
                    {
                        return(point.CreateInstance());
                    }
                    // check segment end points to the cluster tolerance
                    com.epl.geometry.Point2D end_point = segment.GetStartXY();
                    if (com.epl.geometry.Point2D.SqrDistance(pt, end_point) <= tolerance_cluster_sq)
                    {
                        return(point.CreateInstance());
                    }
                    end_point = segment.GetEndXY();
                    if (com.epl.geometry.Point2D.SqrDistance(pt, end_point) <= tolerance_cluster_sq)
                    {
                        return(point.CreateInstance());
                    }
                }
            }
            return(point);
        }
        internal static com.epl.geometry.Geometry PointMinusPoint_(com.epl.geometry.Point point_a, com.epl.geometry.Point point_b, double tolerance, com.epl.geometry.ProgressTracker progress_tracker)
        {
            double tolerance_cluster    = tolerance * System.Math.Sqrt(2.0) * 1.00001;
            double tolerance_cluster_sq = tolerance_cluster * tolerance_cluster;

            com.epl.geometry.Point2D pt_a = point_a.GetXY();
            com.epl.geometry.Point2D pt_b = point_b.GetXY();
            if (com.epl.geometry.Point2D.SqrDistance(pt_a, pt_b) <= tolerance_cluster_sq)
            {
                return(point_a.CreateInstance());
            }
            // return empty point
            return(point_a);
        }
        internal static com.epl.geometry.Geometry PointMinusMultiPoint_(com.epl.geometry.Point point, com.epl.geometry.MultiPoint multi_point, double tolerance, com.epl.geometry.ProgressTracker progress_tracker)
        {
            com.epl.geometry.MultiPointImpl       multipointImpl = (com.epl.geometry.MultiPointImpl)(multi_point._getImpl());
            com.epl.geometry.AttributeStreamOfDbl position       = (com.epl.geometry.AttributeStreamOfDbl)multipointImpl.GetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.POSITION);
            int point_count = multi_point.GetPointCount();

            com.epl.geometry.Point2D point2D = point.GetXY();
            com.epl.geometry.Point2D pt      = new com.epl.geometry.Point2D();
            double tolerance_cluster         = tolerance * System.Math.Sqrt(2.0) * 1.00001;
            double tolerance_cluster_sq      = tolerance_cluster * tolerance_cluster;

            for (int i = 0; i < point_count; i++)
            {
                position.Read(2 * i, pt);
                double sqr_dist = com.epl.geometry.Point2D.SqrDistance(pt, point2D);
                if (sqr_dist <= tolerance_cluster_sq)
                {
                    return(point.CreateInstance());
                }
            }
            // return an empty point.
            return(point);
        }