예제 #1
0
 protected abstract bool CutLineHull(double centerOffset, double r2, double tolerance,
                                     out double tMin, out double tMax,
                                     out NearSegment hullStartNear,
                                     out NearSegment hullEndNear,
                                     out bool coincident);
예제 #2
0
        protected static bool Near([NotNull] Pnt p0,
                                   [NotNull] Pnt l0,
                                   [NotNull] Pnt p1,
                                   [NotNull] Pnt l1,
                                   double r2,
                                   double l12,
                                   ref double tMin, ref double tMax,
                                   ref NearSegment hullStartNear,
                                   ref NearSegment hullEndNear)
        {
            double cMin, cMax;

            double u0 = (p0 + tMin * l0 - p1) * l1 / l12;
            double u1 = (p0 + tMax * l0 - p1) * l1 / l12;

            if (u0 < 0)
            {
                if (SegmentUtils.CutLineCircle(p0, l0, p1, r2, out cMin, out cMax) == false)
                {
                    return(false);
                }

                hullStartNear = Near(cMin, cMax);

                // Debug.Assert(cMin > tMin); numerical exceptions possible
                tMin = cMin;
                if (u1 < 0)
                {
                    //Debug.Assert(cMax < tMax); numerical exceptions possible
                    tMax = cMax;
                }
            }
            else if (u0 > 1)
            {
                if (SegmentUtils.CutLineCircle(p0, l0, p1 + l1, r2, out cMin, out cMax) == false)
                {
                    return(false);
                }

                hullEndNear = Near(cMin, cMax);

                //Debug.Assert(cMin > tMin); numerical exceptions possible
                tMin = cMin;
                if (u1 > 1)
                {
                    //Debug.Assert(cMax < tMax); numerical exceptions possible
                    tMax = cMax;
                }
            }

            if (u1 < 0 && u0 >= 0)
            {
                if (SegmentUtils.CutLineCircle(p0, l0, p1, r2, out cMin, out cMax) == false)
                {
                    //throw new InvalidProgramException(
                    //	"error in software design assumption"); numerical exceptions possible
                    tMax          = tMin + u0 / (u0 - u1) * (tMax - tMin);
                    hullStartNear = Near(tMin, tMax);
                }
                else
                {
                    hullStartNear = Near(cMin, cMax);

                    //Debug.Assert(cMax < tMax); numerical exceptions possible
                    tMax = cMax;
                }
            }
            else if (u1 > 1 && u0 <= 1)
            {
                if (SegmentUtils.CutLineCircle(p0, l0, p1 + l1, r2, out cMin, out cMax) == false)
                {
                    //throw new InvalidProgramException(
                    //	"error in software design assumption"); numerical exceptions possible
                    tMax        = tMin + (1 - u0) / (u1 - u0) * (tMax - tMin);
                    hullEndNear = Near(tMin, tMax);
                }
                else
                {
                    hullEndNear = Near(cMin, cMax);

                    //Debug.Assert(cMax < tMax); numerical exceptions possible
                    tMax = cMax;
                }
            }

            return(true);
        }
예제 #3
0
 protected abstract bool CutCurveHullDetailed(double tolerance,
                                              [NotNull] out IList <double[]> limits,
                                              out NearSegment hullStartNear,
                                              out NearSegment hullEndNear,
                                              out bool coincident);
예제 #4
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);
        }