Exemple #1
0
        private static bool CutCurveHullBuffer([NotNull] SegmentProxy segment,
                                               [NotNull] SegmentProxy hull,
                                               bool is3D, double r2,
                                               [NotNull] out IList <double[]> limits,
                                               out NearSegment hullStartNear,
                                               out NearSegment hullEndNear,
                                               out bool coincident)
        {
            coincident = GetCoincident(segment, hull, is3D, out hullStartNear, out hullEndNear);
            if (r2 > 0)
            {
                IPolygon buffer = hull.CreateBuffer(Math.Sqrt(r2));
                limits = SegmentUtils.GetLimits(segment, buffer);
            }
            else if (coincident)
            {
                limits = new List <double[]>();
                limits.Add(new double[] { 0, 1 });
            }
            else
            {
                limits = new List <double[]>();
            }

            return(limits.Count > 0);
        }
        public SegmentProxy GetSegment(int partIndex, int segmentIndex)
        {
            PartProxy    partProxy    = _partProxies[partIndex];
            SegmentProxy segmentProxy = partProxy.GetSegment(segmentIndex);

            return(segmentProxy);
        }
Exemple #3
0
        public static bool CutCurveCircle([NotNull] SegmentProxy segmentProxy,
                                          [NotNull] Pnt circleCenter,
                                          double r2, bool as3D,
                                          out IList <double[]> limits)
        {
            if (segmentProxy.IsLinear)
            {
                double tMin;
                double tMax;
                bool   cut = as3D
                                                   ? CutLineCircle3D(segmentProxy, circleCenter, r2,
                                                                     out tMin, out tMax)
                                                   : CutLineCircle2D(segmentProxy, circleCenter, r2,
                                                                     out tMin, out tMax);

                limits = new List <double[]>();
                if (cut && tMin < 1 && tMax > 0)
                {
                    limits.Add(new[] { tMin, tMax });
                }

                return(cut);
            }

            return(CutCurveCircle(segmentProxy, circleCenter, r2, out limits));
        }
Exemple #4
0
 public IEnumerable <SegmentProxy> GetSegments()
 {
     for (int i = 0; i < SegmentCount; i++)
     {
         SegmentProxy seg = GetSegment(i);
         yield return(seg);
     }
 }
Exemple #5
0
        internal static IList <double[]> GetLimits([NotNull] SegmentProxy segmentProxy,
                                                   [NotNull] IPolygon buffer)
        {
            // TODO this method would be extremely expensive when called on WksSegmentProxy instances

            var result = new List <double[]>();
            // Remark: segmentLine is altered by ITopologicalOperator.Intersect in  such a way
            // that equal segments may not be considered as equal anymore
            IPolyline segmentLine = segmentProxy.GetPolyline(true);
            //IPolyline segmentLine = segmentProxy.GetPolyline();
            var intersects = (IGeometryCollection)
                             ((ITopologicalOperator)buffer).Intersect(
                segmentLine,
                esriGeometryDimension.esriGeometry1Dimension);

            int intersectCount = intersects.GeometryCount;

            for (var i = 0; i < intersectCount; i++)
            {
                var part = (IPath)intersects.Geometry[i];

                double t0        = 0;
                double t1        = 0;
                double offset    = 0;
                var    rightSide = false;

                // TODO if called frequently, create abstract GetSegmentDistance(IPoint) on SegmentProxy,
                // with custom implementation on WksSegmentProxy.
                // Currently this seems to be called for AoSegmentProxys only, but this is not obvious.

                // TODO use a template point and part.QueryFromPoint() / part.QueryToPoint()?
                segmentLine.QueryPointAndDistance(esriSegmentExtension.esriExtendTangents,
                                                  part.FromPoint, true, HelpPoint,
                                                  ref t0, ref offset, ref rightSide);

                segmentLine.QueryPointAndDistance(esriSegmentExtension.esriExtendTangents,
                                                  part.ToPoint, true, HelpPoint,
                                                  ref t1, ref offset, ref rightSide);

                double tMin = Math.Min(t0, t1);
                double tMax = Math.Max(t0, t1);

                result.Add(new[] { tMin, tMax });
            }

            // Handle spatial tolerance problems for segments near tolerance size!
            if (intersectCount == 0 && !((IRelationalOperator)buffer).Disjoint(segmentLine))
            {
                ((ITopologicalOperator)segmentLine).Simplify();
                if (segmentLine.IsEmpty)
                {
                    result.Add(new[] { 0.0, 1.0 });
                }
            }

            return(result);
        }
Exemple #6
0
 public SegmentHull([NotNull] SegmentProxy segment, double leftOffset, double rightOffset,
                    [NotNull] SegmentCap startCap, [NotNull] SegmentCap endCap)
 {
     _segment     = segment;
     _leftOffset  = leftOffset;
     _rightOffset = rightOffset;
     _startCap    = startCap;
     _endCap      = endCap;
 }
Exemple #7
0
        public static double GetClosestPointFraction([NotNull] SegmentProxy segmentProxy,
                                                     [NotNull] Pnt nearPoint,
                                                     bool as3D)
        {
            double?offset;
            bool?  onRightSide;

            return(GetClosestPointFraction(segmentProxy, nearPoint, out offset, out onRightSide,
                                           as3D));
        }
Exemple #8
0
        private static bool CutLineCircle2D([NotNull] SegmentProxy segmentProxy,
                                            [NotNull] Pnt center, double r2,
                                            out double tMin, out double tMax)
        {
            const bool as3D = false;

            var p0s = (Pnt2D)segmentProxy.GetStart(as3D);
            var p0e = (Pnt2D)segmentProxy.GetEnd(as3D);
            Pnt l0  = p0e - p0s;

            return(CutLineCircle(p0s, l0, center, r2, out tMin, out tMax));
        }
Exemple #9
0
        public static double GetClosestPointFraction([NotNull] SegmentProxy segmentProxy,
                                                     [NotNull] Pnt nearPoint,
                                                     out double?offset,
                                                     out bool?onRightSide,
                                                     bool as3D)
        {
            if (segmentProxy.IsLinear)
            {
                Pnt p0s = segmentProxy.GetStart(as3D);
                Pnt p0e = segmentProxy.GetEnd(as3D);
                Pnt l0  = p0e - p0s;
                offset      = null;
                onRightSide = null;
                return(GetAlongFraction(nearPoint - p0s, l0));
            }

            const bool forceCreation = true;
            IPolyline  segmentLine   = segmentProxy.GetPolyline(forceCreation);

            IPoint near = new PointClass();

            near.PutCoords(nearPoint.X, nearPoint.Y);

            IPoint onPoint = new PointClass();

            double     fraction    = 0;
            double     offsetValue = 0;
            var        rightSide   = false;
            const bool asRatio     = true;

            segmentLine.QueryPointAndDistance(esriSegmentExtension.esriNoExtension, near,
                                              asRatio, onPoint, ref fraction,
                                              ref offsetValue, ref rightSide);

            offset      = offsetValue;
            onRightSide = rightSide;
            return(fraction);
        }
Exemple #10
0
        private static bool CutCurveCircle([NotNull] SegmentProxy segmentProxy,
                                           [NotNull] IPnt circleCenter,
                                           double r2,
                                           [NotNull] out IList <double[]> limits)
        {
            double radius = Math.Sqrt(r2);
            IPoint center = new Point();

            center.PutCoords(circleCenter.X, circleCenter.Y);

            ICircularArc arc = new CircularArcClass();

            arc.PutCoordsByAngle(center, 0, 2 * Math.PI, radius);

            object emptyRef = Type.Missing;

            IPolygon circle = new PolygonClass();

            ((ISegmentCollection)circle).AddSegment(((ISegment)arc), ref emptyRef,
                                                    ref emptyRef);

            limits = GetLimits(segmentProxy, circle);
            return(limits.Count > 0);
        }
Exemple #11
0
        public IPolyline GetSubpart(int startSegmentIndex, double startFraction,
                                    int endSegmentIndex, double endFraction)
        {
            IPointCollection4 subpart = new PolylineClass();

            ((IZAware)subpart).ZAware = true;

            var add = 2;

            if (endFraction == 0)
            {
                add = 1;
            }

            int pointCount = endSegmentIndex - startSegmentIndex + add;
            var points     = new WKSPointZ[pointCount];

            SegmentProxy seg0 = GetSegment(startSegmentIndex);
            IPnt         p    = seg0.GetPointAt(startFraction, true);

            points[0] = QaGeometryUtils.GetWksPoint(p);
            for (int i = startSegmentIndex + 1; i <= endSegmentIndex; i++)
            {
                points[i - startSegmentIndex] = GetPlanePoint(i);
            }

            if (endFraction > 0)
            {
                SegmentProxy seg1 = GetSegment(endSegmentIndex);
                IPnt         end  = seg1.GetPointAt(endFraction, true);
                points[pointCount - 1] = QaGeometryUtils.GetWksPoint(end);
            }

            GeometryUtils.SetWKSPointZs(subpart, points);
            return((IPolyline)subpart);
        }
Exemple #12
0
        private IPolyline GetLinearSubpart(int startSegmentIndex, double startFraction,
                                           int endSegmentIndex, double endFraction)
        {
            IPointCollection4 subpart = new PolylineClass();

            int add = 2;

            if (endFraction == 0)
            {
                add = 1;
            }

            int pointCount = endSegmentIndex - startSegmentIndex + add;
            var points     = new WKSPointZ[pointCount];

            SegmentProxy seg0 = GetSegment(startSegmentIndex);
            IPnt         p    = seg0.GetPointAt(startFraction, as3D: true);

            points[0] = QaGeometryUtils.GetWksPoint(p);
            for (int i = startSegmentIndex + 1; i <= endSegmentIndex; i++)
            {
                points[i - startSegmentIndex] = _points[i];
            }

            if (endFraction > 0)
            {
                SegmentProxy seg1 = GetSegment(endSegmentIndex);
                IPnt         end  = seg1.GetPointAt(endFraction, as3D: true);
                points[pointCount - 1] = QaGeometryUtils.GetWksPoint(end);
            }

            GeometryUtils.SetWKSPointZs(subpart, points);

            ((IPolyline)subpart).SpatialReference = SpatialReference;
            return((IPolyline)subpart);
        }
Exemple #13
0
        private static bool GetCoincident([NotNull] SegmentProxy segment,
                                          [NotNull] SegmentProxy hull,
                                          bool is3D,
                                          out NearSegment hullStartNear,
                                          out NearSegment hullEndNear)
        {
            hullStartNear = NearSegment.NotNear;           // TODO
            hullEndNear   = NearSegment.NotNear;           // TODO

            IPolyline segLine  = segment.GetPolyline(false);
            IPolyline hullLine = hull.GetPolyline(false);

            if (!((IRelationalOperator)segLine).Equals(hullLine))
            {
                return(false);
            }

            var coincident = true;

            Pnt segmentStart = segment.GetStart(is3D);
            Pnt segmentEnd   = segment.GetEnd(is3D);

            Pnt hullStart = hull.GetStart(is3D);
            Pnt hullEnd   = hull.GetEnd(is3D);

            double distFromSegFromHull;
            {
                double dx = segmentStart.X - hullStart.X;
                double dy = segmentStart.Y - hullStart.Y;
                distFromSegFromHull = dx * dx + dy * dy;
            }
            double distFromSegToHull;
            {
                double dx = segmentStart.X - hullEnd.X;
                double dy = segmentStart.Y - hullEnd.Y;
                distFromSegToHull = dx * dx + dy * dy;
            }

            bool isInverse = (distFromSegFromHull > distFromSegToHull);
            Pnt  hullMatchSegFrom;
            Pnt  hullMatchSegTo;

            if (!isInverse)
            {
                hullMatchSegFrom = hullStart;
                hullMatchSegTo   = hullEnd;
            }
            else
            {
                hullMatchSegFrom = hullEnd;
                hullMatchSegTo   = hullStart;
            }

            if (is3D)
            {
                double            zPrecision       = 0;
                ISpatialReference spatialReference = segment.SpatialReference;

                if (spatialReference != null && spatialReference.HasZPrecision())
                {
                    double falseZ;
                    double zUnits;
                    spatialReference.GetZFalseOriginAndUnits(out falseZ, out zUnits);
                    zPrecision = 1 / zUnits;
                }

                if (Math.Abs(hullMatchSegFrom[2] - segmentStart[2]) > zPrecision ||
                    Math.Abs(hullMatchSegTo[2] - segmentStart[2]) > zPrecision)
                {
                    coincident = false;
                }
            }

            if (coincident)
            {
                if (!isInverse)
                {
                    hullStartNear = NearSegment.NearStart;
                    hullEndNear   = NearSegment.NearEnd;
                }
                else
                {
                    hullStartNear = NearSegment.NearEnd;
                    hullEndNear   = NearSegment.NearStart;
                }
            }

            return(coincident);
        }