示例#1
0
        private static void GetClosePart([NotNull] SegmentProxy neighbor,
                                         [NotNull] IPnt near,
                                         double searchDistanceSquared, bool is3D,
                                         out double min, out double max)
        {
            IList <double[]> limits;
            Pnt  p   = Pnt.Create(near);
            bool cut = SegmentUtils.CutCurveCircle(neighbor, p, searchDistanceSquared, is3D,
                                                   out limits);

            if (cut == false || limits.Count == 0)
            {
                min = SegmentUtils.GetClosestPointFraction(neighbor, p, is3D);
                max = min;
            }
            else
            {
                min = double.MaxValue;
                max = double.MinValue;
                foreach (double[] limit in limits)
                {
                    foreach (double d in limit)
                    {
                        min = Math.Min(d, min);
                        max = Math.Max(d, max);
                    }
                }
            }

            min = Math.Max(min, 0);
            max = Math.Max(max, 0);
            min = Math.Min(min, 1);
            max = Math.Min(max, 1);
        }
            protected override bool GetNextSegment(out double length, out double dz,
                                                   out int partIndex, out int segmentIndex)
            {
                if (!_enumSegments.MoveNext())
                {
                    length       = double.NaN;
                    dz           = double.NaN;
                    partIndex    = -1;
                    segmentIndex = -1;
                    return(false);
                }

                SegmentProxy segment = Assert.NotNull(_enumSegments.Current);

                partIndex    = segment.PartIndex;
                segmentIndex = segment.SegmentIndex;

                length = segment.Length;
                double z0 = segment.GetStart(true)[2];
                double z1 = segment.GetEnd(true)[2];

                dz = z1 - z0;

                return(true);
            }
示例#3
0
            protected override bool GetNextSliverArea(out double area, out double perimeter)
            {
                _latestPartSegments = null;
                if (!_enumValid)
                {
                    area      = double.NaN;
                    perimeter = double.NaN;
                    return(false);
                }

                SegmentProxy segment = Assert.NotNull(_segmentsEnum.Current);

                int currentPart  = segment.PartIndex;
                int segmentCount = _indexedMultiPatch.GetPartSegmentCount(currentPart);
                var partSegments = new List <SegmentProxy>(segmentCount)
                {
                    segment
                };

                while ((_enumValid = _segmentsEnum.MoveNext()) &&
                       Assert.NotNull(_segmentsEnum.Current).PartIndex == currentPart)
                {
                    partSegments.Add(_segmentsEnum.Current);
                }

                List <Pnt> planePoints = QaGeometryUtils.GetPoints(partSegments);
                Plane      plane       = QaGeometryUtils.CreatePlane((IEnumerable <SegmentProxy>)partSegments);

                QaGeometryUtils.CalculateProjectedArea(plane, planePoints, out area, out perimeter);

                _latestPartSegments = partSegments;

                return(true);
            }
 public SegmentProximity([NotNull] Pnt point,
                         bool as3D,
                         [NotNull] SegmentProxy segmentProxy)
     : base(point, as3D)
 {
     _segmentProxy = segmentProxy;
 }
示例#5
0
        public static WKSEnvelope GetEnvelope([NotNull] IIndexedSegments baseGeometry,
                                              int part, int startSegmentIndex,
                                              double startFraction,
                                              int endSegmentIndex, double endFraction)
        {
            SegmentProxy segment  = baseGeometry.GetSegment(part, startSegmentIndex);
            double       startEnd = 1;

            if (startSegmentIndex == endSegmentIndex)
            {
                startEnd = endFraction;
            }

            WKSEnvelope box = segment.GetSubCurveBox(startFraction, startEnd);

            for (int i = startSegmentIndex + 1; i < endSegmentIndex - 1; i++)
            {
                segment = baseGeometry.GetSegment(part, i);
                box     = GetUnion(box, segment.GetSubCurveBox(0, 1));
            }

            if (endSegmentIndex > startSegmentIndex && endFraction > 0)
            {
                segment = baseGeometry.GetSegment(part, endSegmentIndex);
                box     = GetUnion(box, segment.GetSubCurveBox(0, endFraction));
            }

            return(box);
        }
示例#6
0
        internal static double GetLength([NotNull] IIndexedSegments baseGeometry,
                                         int partIndex,
                                         int startSegmentIndex, double startFraction,
                                         int endSegmentIndex, double endFraction)
        {
            double length = 0;

            for (int i = startSegmentIndex; i <= endSegmentIndex; i++)
            {
                SegmentProxy seg = baseGeometry.GetSegment(partIndex, i);

                double segLength = seg.Length;
                double addLength = segLength;

                if (i == startSegmentIndex)
                {
                    addLength -= segLength * startFraction;
                }

                if (i == endSegmentIndex)
                {
                    addLength -= segLength * (1 - endFraction);
                }

                length += addLength;
            }

            return(length);
        }
示例#7
0
 public Selection(EditorState state, int segmentNum, int sideNum, int pointNum)
 {
     _state   = state;
     _segment = _state.Level.Segments[segmentNum];
     _side    = _segment.Sides[_sideNum = sideNum];
     _point   = _side.Points[_pointNum = pointNum];
 }
示例#8
0
            protected override bool VerifyContinue(SegmentProxy seg0, SegmentProxy seg1,
                                                   SegmentNeighbors processed1,
                                                   SegmentParts partsOfSeg0, bool coincident)
            {
                TryAssignComplete(seg1, processed1, partsOfSeg0);

                SegmentParts coincidentPartsOfSeg0;
                var          key = new SegmentPart(seg0, 0, 1, true);

                if (!_coincidentParts.TryGetValue(key, out coincidentPartsOfSeg0))
                {
                    coincidentPartsOfSeg0 = new SegmentParts();
                    _coincidentParts.Add(key, coincidentPartsOfSeg0);
                }

                if (coincident)
                {
                    partsOfSeg0.IsComplete = true;
                    coincidentPartsOfSeg0.Add(key);
                    return(false);
                }
                //return true;

                IBox seg0Box = seg0.Extent;

                seg0Box = new Box(Pnt.Create(seg0Box.Min), Pnt.Create(seg0Box.Max));
                if (_coincidenceTolerance > 0)
                {
                    seg0Box.Min.X -= _coincidenceTolerance;
                    seg0Box.Min.Y -= _coincidenceTolerance;
                    seg0Box.Max.X += _coincidenceTolerance;
                    seg0Box.Max.Y += _coincidenceTolerance;
                }

                if (!seg0Box.Intersects(seg1.Extent))
                {
                    return(true);
                }

                var              cap = new RoundCap();
                NearSegment      hullStart;
                NearSegment      hullEnd;
                bool             isCoincident;
                IList <double[]> limits =
                    FindNeighborhood(
                        new SegmentHull(seg0, 0, cap, cap),
                        new SegmentHull(seg1, _coincidenceTolerance, cap, cap),
                        _is3D, 0,
                        out hullStart, out hullEnd, out isCoincident);
                IList <SegmentPart> addParts = GetSegmentParts(seg0, seg1, limits, isCoincident);

                coincidentPartsOfSeg0.AddRange(addParts);

                bool isComplete = SegmentPart.VerifyComplete(coincidentPartsOfSeg0);

                partsOfSeg0.IsComplete = isComplete;

                return(!isComplete);
            }
            public HeightSegment(SegmentProxy segment)
            {
                _segment = segment;
                double z0 = segment.GetStart(true)[2];
                double z1 = segment.GetStart(true)[2];

                _height = (z0 + z1) / 2.0;
            }
            protected override bool VerifyContinue(SegmentProxy seg0, SegmentProxy seg1,
                                                   SegmentNeighbors processed1,
                                                   SegmentParts partsOfSeg0, bool coincident)
            {
                bool isComplete = SegmentPart.VerifyComplete(partsOfSeg0);

                TryAssignComplete(seg1, processed1, partsOfSeg0);
                return(!isComplete);
            }
示例#11
0
        private static double GetDistanceToVertices([NotNull] IPoint point,
                                                    [NotNull] IFeature neighbourFeature,
                                                    [NotNull] IPoint nearestPoint,
                                                    double maxNeededDistance)
        {
            double minDistance2 = double.MaxValue;

            SegmentProxy nearestSegment = null;
            var          isEndNearest   = false;
            Pnt          qaPoint        = QaGeometryUtils.CreatePoint3D(point);

            IEnumerable <SegmentProxy> segments = EnumSegments(qaPoint, neighbourFeature,
                                                               maxNeededDistance);

            foreach (SegmentProxy segment in segments)
            {
                if (GetNearest(qaPoint, segment.GetStart(false), ref minDistance2))
                {
                    nearestSegment = segment;
                    isEndNearest   = false;
                }

                if (GetNearest(qaPoint, segment.GetEnd(false), ref minDistance2))
                {
                    nearestSegment = segment;
                    isEndNearest   = true;
                }
            }

            double minDistance;

            if (nearestSegment != null)
            {
                minDistance = Math.Sqrt(minDistance2);

                if (minDistance <= maxNeededDistance)
                {
                    Pnt nearest = !isEndNearest
                                                              ? nearestSegment.GetStart(true)
                                                              : nearestSegment.GetEnd(true);

                    nearestPoint.PutCoords(nearest.X, nearest.Y);
                    nearestPoint.Z = nearest[2];
                }
            }
            else
            {
                minDistance = double.MaxValue;
            }

            return(minDistance);
        }
示例#12
0
        private IEnumerable <bool> GetConnectedCandidateAtStarts(IIndexedSegments geometry,
                                                                 SegmentProxy segment)
        {
            if (segment.SegmentIndex == 0 ||
                ConnectionMode != ConnectionMode.EndpointOnEndpoint)
            {
                yield return(true);
            }

            if (segment.SegmentIndex + 1 == geometry.GetPartSegmentCount(segment.PartIndex) ||
                ConnectionMode != ConnectionMode.EndpointOnEndpoint)
            {
                yield return(false);
            }
        }
        private static void AddSegment([NotNull] IFeature feature,
                                       [NotNull] IIndexedSegments geom,
                                       [NotNull] IList <Subcurve> connectedList,
                                       [NotNull] SegmentProxy segProxy, double min,
                                       double max)
        {
            if (min >= max)
            {
                return;
            }

            Subcurve current = null;

            if (connectedList.Count > 0)
            {
                current = connectedList[connectedList.Count - 1];
            }

            if (current != null)
            {
                if (current.PartIndex != segProxy.PartIndex)
                {
                    current = null;
                }
                else if (current.EndSegmentIndex + current.EndFraction <
                         segProxy.SegmentIndex + min)
                {
                    current = null;
                }
            }

            if (current == null)
            {
                current = new Subcurve(geom, segProxy.PartIndex, segProxy.SegmentIndex,
                                       min, segProxy.SegmentIndex, max);
                connectedList.Add(current);
            }
            else
            {
                if (current.EndSegmentIndex + current.EndFraction < segProxy.SegmentIndex + max)
                {
                    current.EndSegmentIndex = segProxy.SegmentIndex;
                    current.EndFraction     = max;
                }
            }
        }
            private bool IsHorizontal([NotNull] SegmentProxy segment)
            {
                double length = segment.Length;

                if (Math.Abs(length) < double.Epsilon)
                {
                    return(false);
                }

                double z0         = segment.GetStart(true)[2];
                double z1         = segment.GetEnd(true)[2];
                double slopeAngle = Math.Atan2(Math.Abs(z1 - z0), length);

                bool isHorizontal = slopeAngle <= _horizontalToleranceRad;

                return(isHorizontal);
            }
示例#15
0
        public AzimuthSegment([NotNull] SegmentProxy segment, double xyResolution)
        {
            Segment       = segment;
            _xyResolution = xyResolution;
            Pnt start = Segment.GetStart(false);
            Pnt end   = Segment.GetEnd(false);

            double dx = end.X - start.X;
            double dy = end.Y - start.Y;

            Azimuth = Math.Atan2(dx, dy); // Azimuth is the angle to north

            if (Azimuth < 0)              // the orientation must be ignored
            {
                Azimuth += Math.PI;
            }
        }
示例#16
0
            private static SegmentProxyInfo GetSegmentproxyInfo(
                [NotNull] NeighboredSegmentsSubpart segmentsSubpart, int baseSegmentIndex)
            {
                int subpartIndex =
                    segmentsSubpart.FullStartFraction < segmentsSubpart.FullEndFraction
                                                ? baseSegmentIndex - segmentsSubpart.FullStartFraction
                                                : segmentsSubpart.FullStartFraction - baseSegmentIndex - 1;

                SegmentProxy segmentProxy = segmentsSubpart.GetSegment(subpartIndex);

                var key = new SegmentPart(segmentProxy, 0, 1, true);
                // SegmentPart key = new SegmentPart(segmentsSubpart.PartIndex, iSegment, 0, 1, true);
                SegmentParts segmentParts;

                segmentsSubpart.SegmentNeighbors.TryGetValue(key, out segmentParts);

                return(new SegmentProxyInfo(segmentProxy, segmentsSubpart));
            }
示例#17
0
        private static double GetOffset([NotNull] Pnt pnt,
                                        [NotNull] SegmentProxy segmentProxy,
                                        out double fraction,
                                        out bool?onRightSide)
        {
            double?offset;

            fraction = SegmentUtils.GetClosestPointFraction(
                segmentProxy, pnt, out offset, out onRightSide, as3D: false);

            double distance2;

            if (fraction < 0)
            {
                distance2   = pnt.Dist2(segmentProxy.GetStart(as3D: false));
                onRightSide = null;
            }
            else if (fraction > 1)
            {
                distance2   = pnt.Dist2(segmentProxy.GetEnd(as3D: false));
                onRightSide = null;
            }
            else
            {
                if (!offset.HasValue)
                {
                    Pnt    s          = segmentProxy.GetStart(as3D: false);
                    Pnt    e          = segmentProxy.GetEnd(as3D: false);
                    double vectorProd = (pnt - s).VectorProduct(s - e);
                    onRightSide = vectorProd < 0;
                    distance2   = pnt.Dist2(segmentProxy.GetPointAt(fraction, as3D: false));
                }
                else
                {
                    distance2 = 0;                     // offset has value and will be used as distance
                }
            }

            double distance = offset ?? Math.Sqrt(distance2);

            return(distance);
        }
示例#18
0
        private static void GetClosePart([NotNull] SegmentProxy neighbor,
                                         [NotNull] IIndexedSegments geom,
                                         [NotNull] SegmentPart segPart,
                                         double searchDistanceSquared, bool is3D,
                                         out double min, out double max)
        {
            SegmentProxy part = geom.GetSegment(segPart.PartIndex, segPart.SegmentIndex);
            IPnt         start = part.GetPointAt(segPart.MinFraction);
            double       minStart, maxStart;

            GetClosePart(neighbor, start, searchDistanceSquared, is3D, out minStart,
                         out maxStart);

            IPnt   end = part.GetPointAt(segPart.MaxFraction);
            double minEnd, maxEnd;

            GetClosePart(neighbor, end, searchDistanceSquared, is3D, out minEnd, out maxEnd);

            min = Math.Min(minStart, minEnd);
            max = Math.Max(maxStart, maxEnd);
        }
示例#19
0
        public void CanCutRoundRound()
        {
            var cap = new RoundCap();

            SegmentProxy segment0 = CreateSegment(0, 0, 0, 10);
            var          hull     = new SegmentHull(segment0, 1, cap, cap);

            SegmentProxy segment1 = CreateSegment(-5, 5, 5, 5);
            var          neighbor = new SegmentHull(segment1, 1, cap, cap);

            var pair = new SegmentPair2D(hull, neighbor);

            IList <double[]> limits;
            NearSegment      startNear;
            NearSegment      endNear;
            bool             coincident;
            bool             intersects = pair.CutCurveHull(0, out limits, out startNear, out endNear,
                                                            out coincident);

            Assert.IsTrue(intersects);
        }
示例#20
0
        public void CutCurveHullTest()
        {
            //seg0 = CreateSegment(GeometryFactory.CreatePoint(0, 0, 0), GeometryFactory.CreatePoint(100, 200, 10));
            //seg1 = CreateSegment(GeometryFactory.CreatePoint(0, 0, 0), GeometryFactory.CreatePoint(100, 200, 10));
            //SegmentUtils.CutCurveHull(seg0, seg1, 0, 0, true,
            //    out limits, out hullStartNear, out hullEndNear, out coincident);

            const double r  = 0.0001;
            const double x0 = 600000;
            const double y0 = 200000;

            SegmentProxy seg0 = CreateSegment(
                GeometryFactory.CreatePoint(x0 + 100, y0 + 200, 10),
                GeometryFactory.CreatePoint(x0, y0, 500));
            SegmentProxy seg1 = CreateSegment(
                GeometryFactory.CreatePoint(x0, y0, 500 + 2 * r),
                GeometryFactory.CreatePoint(x0 - 200 - r, y0, 20));

            IList <double[]> limits;
            NearSegment      hullStartNear;
            NearSegment      hullEndNear;
            bool             coincident;

            SegmentHull hull0  = seg0.CreateHull(0);
            SegmentHull hull1  = seg1.CreateHull(0);
            var         pair2D = new SegmentPair2D(hull0, hull1);

            pair2D.CutCurveHull(0,
                                out limits, out hullStartNear, out hullEndNear, out coincident);
            Assert.AreEqual(1, limits.Count);

            var pair3D = new SegmentPair3D(hull0, hull1);

            pair3D.CutCurveHull(0,
                                out limits, out hullStartNear, out hullEndNear, out coincident);
            Assert.AreEqual(0, limits.Count);
        }
示例#21
0
 private static bool AreEqualSegments(SegmentProxy x, SegmentProxy y)
 {
     return(x.PartIndex == y.PartIndex &&
            x.SegmentIndex == y.SegmentIndex);
 }
示例#22
0
        private void AddSegment([NotNull] IFeature feature,
                                [NotNull] IIndexedSegments geom,
                                [NotNull] IList <Subcurve> standardConnectedList,
                                [NotNull] IList <Subcurve> nearSelfConnectedList,
                                [NotNull] SegmentPart segPart,
                                double connectedMinLength,
                                double nearSquared)
        {
            Subcurve         current       = null;
            IList <Subcurve> connectedList = standardConnectedList;

            SegmentProxy neighbor = segPart.NearSelf;

            if (neighbor != null)
            {
                // Get the distance between the parts that are near
                double d0        = double.MaxValue;
                int    partIndex = segPart.PartIndex;

                if (geom.IsPartClosed(partIndex) || segPart.SegmentIndex > neighbor.SegmentIndex)
                {
                    if (segPart.PartIndex == neighbor.PartIndex)
                    // TODO revise; workaround to avoid exception (invalid index)
                    {
                        // raw estimate for distance betwenn segPart and neighborPart
                        // this estimate is too small, because not the entire part of neighbor is near segPart
                        var curve = new SubClosedCurve(geom, partIndex,
                                                       neighbor.SegmentIndex + 1,
                                                       segPart.FullMin);
                        d0 = curve.GetLength();
                        if (d0 < connectedMinLength)
                        {
                            double d0Max = d0 + neighbor.Length;
                            if (d0Max > connectedMinLength)
                            {
                                // closer investigation necessary
                                double min;
                                double max;
                                GetClosePart(neighbor, geom, segPart, nearSquared, Is3D,
                                             out min, out max);

                                d0 = d0 + (1 - max) * neighbor.Length;
                            }                     // else segPart is definitly near neighbor
                        }                         //else segPart is definitly not near neighbor
                    }
                }

                if (geom.IsPartClosed(partIndex) || segPart.SegmentIndex < neighbor.SegmentIndex)
                {
                    if (segPart.PartIndex == neighbor.PartIndex)
                    // TODO revise; workaround to avoid exception (invalid index)
                    {
                        var curve = new SubClosedCurve(geom, partIndex,
                                                       segPart.FullMax,
                                                       neighbor.SegmentIndex);

                        double d0Min = curve.GetLength();
                        if (d0Min < connectedMinLength)
                        {
                            double d0Max = d0Min + neighbor.Length;
                            if (d0Max > connectedMinLength)
                            {
                                // closer investigation necessary
                                double min;
                                double max;
                                GetClosePart(neighbor, geom, segPart, nearSquared, Is3D,
                                             out min, out max);

                                d0Min = d0Min + min * neighbor.Length;
                            }                     //else segPart is definitly near neighbor
                        }                         // else segPart is definitly not near neighbor

                        d0 = Math.Min(d0, d0Min);
                    }
                }

                if (d0 < connectedMinLength)
                {
                    connectedList = nearSelfConnectedList;
                }
            }

            if (connectedList.Count > 0)
            {
                current = connectedList[connectedList.Count - 1];
            }

            if (current != null)
            {
                if (current.PartIndex != segPart.PartIndex)
                {
                    current = null;
                }
                else if (current.EndFullIndex < segPart.FullMin)
                {
                    current = null;
                }
            }

            if (current == null)
            {
                current = new Subcurve(geom, segPart.PartIndex, segPart.SegmentIndex,
                                       segPart.MinFraction, segPart.SegmentIndex,
                                       segPart.MaxFraction);
                connectedList.Add(current);
            }
            else
            {
                if (current.EndFullIndex < segPart.FullMax)
                {
                    current.EndSegmentIndex = segPart.SegmentIndex;
                    current.EndFraction     = segPart.MaxFraction;
                }
            }
        }
示例#23
0
 public SegmentProxyInfo([NotNull] SegmentProxy segmentProxy,
                         [NotNull] NeighboredSegmentsSubpart subpart)
 {
     SegmentProxy = segmentProxy;
     Subpart      = subpart;
 }
示例#24
0
        private static bool?GetOnRightSide(
            [NotNull] SegmentProxy nearestSegment, double nearestFraction,
            [NotNull] SegmentProxy segmentProxy, double alongFraction,
            [NotNull] IGeometry baseGeometry)
        {
            if (nearestSegment.PartIndex != segmentProxy.PartIndex)
            {
                return(null);
            }

            SegmentProxy from;
            SegmentProxy to;

            if (nearestFraction >= 1)
            {
                if (alongFraction > 0)
                {
                    return(null);
                }

                ISegmentProxy next = nearestSegment.GetNextSegment(baseGeometry);
                if (next == null)
                {
                    return(null);
                }

                if (next.SegmentIndex != segmentProxy.SegmentIndex)
                {
                    return(null);
                }

                from = nearestSegment;
                to   = segmentProxy;
            }
            else if (nearestFraction <= 0)
            {
                if (alongFraction < 1)
                {
                    return(null);
                }

                ISegmentProxy next = segmentProxy.GetNextSegment(baseGeometry);
                if (next == null)
                {
                    return(null);
                }

                if (next.SegmentIndex != nearestSegment.SegmentIndex)
                {
                    return(null);
                }

                from = segmentProxy;
                to   = nearestSegment;
            }
            else
            {
                // unexpected
                return(null);
            }

            Pnt vectorFrom = from.GetEnd(as3D: false) - from.GetStart(as3D: false);
            Pnt vectorTo   = to.GetEnd(as3D: false) - to.GetStart(as3D: false);

            bool onRightSide = vectorFrom.VectorProduct(vectorTo) > 0;

            return(onRightSide);
        }
示例#25
0
        private static double GetDistanceToCurve(
            [NotNull] IPoint point,
            [NotNull] IFeature neighbourFeature,
            [NotNull] IPoint nearestPoint,
            double maxNeededDistance,
            out bool onRightSide)
        {
            var neighborCurve = (ICurve)neighbourFeature.Shape;

            if (UseQueryPointAndDistance)
            {
                const bool asRatio   = false;
                double     along     = 0;
                double     distance  = 0;
                var        rightSide = false;

                // TLMQA-292 (EBG - BB): most time spent here (> 90%)
                neighborCurve.QueryPointAndDistance(esriSegmentExtension.esriNoExtension,
                                                    point, asRatio, nearestPoint,
                                                    ref along, ref distance, ref rightSide);
                onRightSide = rightSide;
                return(distance);
            }

            {
                double       nearestDistance    = maxNeededDistance * 1.01;
                bool?        nearestOnRightSide = null;
                SegmentProxy nearestSegment     = null;
                double       nearestFraction    = 0;

                double x;
                double y;
                point.QueryCoords(out x, out y);
                Pnt qaPoint = new Pnt2D(x, y);
                foreach (SegmentProxy segmentProxy in
                         EnumSegments(qaPoint, neighbourFeature, maxNeededDistance))
                {
                    bool?  onSegmentRightSide;
                    double alongFraction;
                    double offset = GetOffset(qaPoint, segmentProxy,
                                              out alongFraction, out onSegmentRightSide);
                    if (offset <= nearestDistance)
                    {
                        if (!onSegmentRightSide.HasValue && !nearestOnRightSide.HasValue &&
                            nearestSegment != null)
                        {
                            nearestOnRightSide = GetOnRightSide(
                                nearestSegment, nearestFraction, segmentProxy, alongFraction,
                                neighborCurve);
                        }
                        else if (offset < nearestDistance)
                        {
                            nearestOnRightSide = onSegmentRightSide;
                        }

                        nearestDistance = offset;
                        nearestSegment  = segmentProxy;
                        nearestFraction = alongFraction;
                    }
                }

                if (nearestSegment != null)
                {
                    double f = Math.Min(1, Math.Max(0, nearestFraction));
                    IPnt   p = nearestSegment.GetPointAt(f, as3D: true);
                    nearestPoint.PutCoords(p.X, p.Y);
                    nearestPoint.Z = p[2];

                    if (!nearestOnRightSide.HasValue)
                    {
                        // Extend segment lineary to determine right side
                        Pnt s = nearestSegment.GetStart(as3D: false);
                        Pnt e = nearestSegment.GetEnd(as3D: false);

                        if (nearestFraction >= 1)
                        {
                            nearestOnRightSide = (e - s).VectorProduct(e - qaPoint) > 0;
                        }
                        else if (nearestFraction <= 0)
                        {
                            nearestOnRightSide = (e - s).VectorProduct(s - qaPoint) > 0;
                        }
                    }
                }

                onRightSide = nearestOnRightSide ?? false;
                return(nearestDistance);
            }
        }
示例#26
0
            private void Initialize()
            {
                _indexedMultipatch = GetAdaptedMultiPatch();
                IMultiPatch multiPatch = _indexedMultipatch.BaseGeometry;

                _verticalFaceSegments = new List <SegmentProxy>();

                var patches            = (IGeometryCollection)multiPatch;
                var verticalPatchParts = new Dictionary <int, List <int> >();

                int patchCount = patches.GeometryCount;

                for (int patchIndex = 0; patchIndex < patchCount; patchIndex++)
                {
                    List <int> partIndexes = _indexedMultipatch.GetPartIndexes(patchIndex);

                    foreach (int partIndex in partIndexes)
                    {
                        int partSegmentCount =
                            _indexedMultipatch.GetPartSegmentCount(partIndex);

                        var segments = new List <SegmentProxy>(partSegmentCount);
                        for (int segmentIndex = 0;
                             segmentIndex < partSegmentCount;
                             segmentIndex++)
                        {
                            segments.Add(
                                _indexedMultipatch.GetSegment(partIndex, segmentIndex));
                        }

                        Plane plane =
                            QaGeometryUtils.CreatePlane(
                                (IEnumerable <SegmentProxy>)segments);

                        if (Math.Abs(plane.GetNormalVector().Z) < double.Epsilon)
                        {
                            List <int> verticalParts;
                            if (!verticalPatchParts.TryGetValue(
                                    patchIndex, out verticalParts))
                            {
                                verticalParts = new List <int>();
                                verticalPatchParts.Add(patchIndex, verticalParts);
                            }

                            verticalParts.Add(partIndex);
                            _verticalFaceSegments.AddRange(segments);
                        }
                    }
                }

                if (verticalPatchParts.Count > 0)
                {
                    object      missing = Type.Missing;
                    IMultiPatch nonVerticalMultiPatch =
                        new MultiPatchClass
                    {
                        SpatialReference = multiPatch.SpatialReference
                    };

                    for (int patchIndex = 0; patchIndex < patchCount; patchIndex++)
                    {
                        List <int> verticalParts;
                        IGeometry  patch =
                            ((IGeometryCollection)multiPatch).Geometry[patchIndex];

                        if (!verticalPatchParts.TryGetValue(
                                patchIndex, out verticalParts))
                        {
                            IGeometry clone = GeometryFactory.Clone(patch);
                            ((IGeometryCollection)nonVerticalMultiPatch).AddGeometry(
                                clone,
                                ref missing,
                                ref missing);
                            var ring = patch as IRing;
                            if (ring != null)
                            {
                                bool isBeginning = false;
                                esriMultiPatchRingType ringType =
                                    multiPatch.GetRingType(ring, ref isBeginning);
                                nonVerticalMultiPatch.PutRingType(
                                    (IRing)clone, ringType);
                            }
                        }
                        else
                        {
                            if (patch is IRing)
                            {
                                continue;
                            }

                            List <int> partIndexes =
                                _indexedMultipatch.GetPartIndexes(patchIndex);

                            foreach (int partIndex in partIndexes)
                            {
                                if (verticalParts.Contains(partIndex))
                                {
                                    continue;
                                }

                                int partSegmentCount =
                                    _indexedMultipatch.GetPartSegmentCount(partIndex);

                                var points = new List <WKSPointZ>(3);

                                for (int segmentIndex = 0;
                                     segmentIndex < partSegmentCount;
                                     segmentIndex++)
                                {
                                    SegmentProxy segment =
                                        _indexedMultipatch.GetSegment(
                                            partIndex, segmentIndex);

                                    const bool as3D = true;
                                    Pnt        p    = segment.GetStart(as3D);

                                    points.Add(
                                        WKSPointZUtils.CreatePoint(p.X, p.Y, p[2]));
                                }

                                IRing ring = CreateRing(points);

                                ((IGeometryCollection)nonVerticalMultiPatch).AddGeometry(
                                    ring,
                                    ref missing,
                                    ref missing);
                            }
                        }
                    }

                    _nonVerticalMultipatch = nonVerticalMultiPatch;
                }
                else
                {
                    _nonVerticalMultipatch = multiPatch;
                }
            }
示例#27
0
 protected override bool VerifyContinue(SegmentProxy seg0, SegmentProxy seg1,
                                        SegmentNeighbors processed1,
                                        SegmentParts partsOfSeg0, bool coincident)
 {
     return(true);
 }