Exemple #1
0
        /// <summary>
        /// Updates info on the longest horizontal span that crosses this polygon (used
        /// by <see cref="GetLabelPosition"/>)
        /// </summary>
        /// <param name="y">The Y-value of the scan line.</param>
        /// <param name="minx">The X-value for the western end of the scan line.</param>
        /// <param name="maxx">The X-value for the eastern end of the scan line.</param>
        /// <param name="weight">Weighting factor to use when comparing span lengths versus
        /// the initial best length.</param>
        /// <param name="beststart">The position of the start of the best span.</param>
        /// <param name="bestend">The position of the end of the best span.</param>
        /// <param name="bestlen">The weighted length of the best span. This is what defines
        /// the meaning of "best".</param>
        void GetLabelSpan(double y, double minx, double maxx, double weight,
                          ref IPosition beststart, ref IPosition bestend, ref double bestlen)
        {
            // Define scan line.
            ITerminal       sloc = new FloatingTerminal(minx, y);
            ITerminal       eloc = new FloatingTerminal(maxx, y);
            SegmentGeometry seg  = new SegmentGeometry(sloc, eloc);

            // Intersect with the map
            IntersectionFinder xseg = new IntersectionFinder(seg, true);

            // Arrange intersections along the scan line.
            IntersectionResult xres = new IntersectionResult(xseg);

            xres.Sort(true);

            // Define start of the first span
            IPosition start = sloc;
            IPosition end   = null;

            // Go through each successive intersection, to locate spans
            // that run through the interior of the polygon.
            foreach (IntersectionData d in xres.Intersections)
            {
                // If the intersection is a graze
                if (d.IsGraze)
                {
                    // Just define the end of the graze as the end point (there's
                    // no point in trying to locate a label along the graze).
                    end = d.P2;
                }
                else
                {
                    // Simple intersection...

                    // Get the next intersection
                    end = d.P1;

                    // Get the midpoint of the span.
                    IPosition mid = Position.CreateMidpoint(start, end);

                    // If the midpoint really falls inside this polygon, see whether the span
                    // length is bigger than what we already have (if anything).

                    if (this.IsEnclosing(mid))
                    {
                        double len = (end.X - start.X) / weight;
                        if (len > bestlen)
                        {
                            bestlen   = len;
                            beststart = start;
                            bestend   = end;
                        }
                    }
                }

                start = end;
            }
        }
Exemple #2
0
        /// <summary>
        /// Checks whether this closed shape intersects (overlaps) a line.
        /// This assumes that a window-window overlap has already been checked for.
        /// </summary>
        /// <param name="line">The line to compare with the shape</param>
        /// <returns>True if intersection found.</returns>
        bool IsIntersect(LineGeometry line)
        {
            //IntersectionResult xres = new IntersectionResult(line);
            //return (xres.IntersectMultiSegment(this) > 0);

            IntersectionResult xres = new IntersectionResult(line);

            // Intersect each segment of this shape with the line.
            IPointGeometry[] data = this.Data;
            for (int i = 1; i < data.Length; i++)
            {
                LineSegmentGeometry thisSeg = new LineSegmentGeometry(data[i - 1], data[i]);
                if (xres.IntersectSegment(thisSeg) > 0)
                {
                    return(true);
                }
            }

            return(false);
        }
 internal override uint IntersectSegment(IntersectionResult results, ILineSegmentGeometry seg)
 {
     return Make().IntersectSegment(results, seg);
 }
 internal override uint IntersectCircle(IntersectionResult results, ICircleGeometry circle)
 {
     return Make().IntersectCircle(results, circle);
 }
 internal override uint IntersectArc(IntersectionResult results, ICircularArcGeometry that)
 {
     return(IntersectionHelper.Intersect(results, (ILineSegmentGeometry)this, that));
 }
        /// <summary>
        /// Intersects this segment with another segment, where at least one end of the
        /// segment exactly coincides with one end of the other segment. 
        /// </summary>
        /// <param name="xsect">The intersection results.</param>
        /// <param name="start">The start of the other segment.</param>
        /// <param name="end">The end of the other segment.</param>
        /// <param name="xend">The end of THIS segment that coincides with one end
        /// of the other one (the geometry for either m_Start or m_End).</param>
        /// <param name="othend">The other end of THIS segment (may or may not coincide
        /// with one end of the other segment).</param>
        /// <returns>The number of intersections (always 1).</returns>
        static uint EndIntersect( IntersectionResult xsect
            , IPointGeometry start
            , IPointGeometry end
            , IPointGeometry xend
            , IPointGeometry othend)
        {
            // If the other end of this segment coincides with either end
            // of the other segment, we've got a total graze.
            if (othend.IsCoincident(start) || othend.IsCoincident(end))
            {
                xsect.Append(start, end);
                return 1;
            }

            // Get the locations that define the longer segment, together
            // with the location that is different from the exactly matching end.

            IPointGeometry startLong;
            IPointGeometry endLong;
            IPointGeometry test;

            if (Geom.DistanceSquared(xend, othend) < Geom.DistanceSquared(start, end))
            {
                test = othend;
                startLong = start;
                endLong = end;
            }
            else
            {
                startLong = xend;
                endLong = othend;

                if (xend.IsCoincident(start))
                    test = end;
                else
                    test = start;
            }

            // If it is coincident (to within the resolution) AND the
            // position ratio of the perpendicular point is ON this
            // segment, it's a graze.

            double tolsq = (Constants.XYRES * Constants.XYRES);

            if (PointGeometry.IsCoincidentWith(test, startLong, endLong, tolsq))
            {
                double prat = Geom.GetPositionRatio(test.X
                                                   , test.Y
                                                   , startLong.X
                                                   , startLong.Y
                                                   , endLong.X
                                                   , endLong.Y);

                if (prat>0.0 && prat<1.0)
                {
                    xsect.Append(xend, test);
                    return 1;
                }
            }

            // ONE intersection at the end that exactly matches.
            xsect.Append(xend);
            return 1;
        }
        internal static uint Intersect( IntersectionResult results
            , IPointGeometry a
            , IPointGeometry b
            , IPointGeometry p
            , IPointGeometry q)
        {
            // 04-APR-2003: This isn't supposed to happen, but if we've somehow
            // got a null segment, it NEVER intersects anything.
            if (a.IsCoincident(b))
                return 0;

            // If the segment EXACTLY meets either end of the other segment,
            // it gets handled seperately.
            if (a.IsCoincident(p) || a.IsCoincident(q))
                return EndIntersect(results, p, q, a, b);

            if (b.IsCoincident(p) || b.IsCoincident(q))
                return EndIntersect(results, p, q, b, a);

            // Return if the windows don't overlap.
            Window winab = new Window(a, b);
            Window winpq = new Window(p, q);
            if (!winab.IsOverlap(winpq))
                return 0;

            // Check whether this line is completely coincident with the other one.
            // double tolsq = Constants.XYTOLSQ;
            double tolsq = (Constants.XYRES*Constants.XYRES);

            uint xcase = 0;
            if (PointGeometry.IsCoincidentWith(a, p, q, tolsq))
                xcase |= 0x08;
            if (PointGeometry.IsCoincidentWith(b, p, q, tolsq))
                xcase |= 0x04;

            if (xcase==12) // bits 1100
            {
                results.Append(a, b);
                return 1;
            }

            // Check the end points of the other line to this one.
            if (PointGeometry.IsCoincidentWith(p, a, b, tolsq))
                xcase |= 0x02;
            if (PointGeometry.IsCoincidentWith(q, a, b, tolsq))
                xcase |= 0x01;

            // Return intersections. Note that in cases 3,7,11, the intersections
            // are not necessarily ordered with respect to THIS segment.

            switch (xcase)
            {
                case 0:
                    {
                        // Try to get a simple intersection. Do not accept
                        // virtual intersections, since they should have been
                        // trapped via the calculation of the xcase.

                        double xi, yi;
                        int xcode = Geom.CalcIntersect(a.X, a.Y, b.X, b.Y, p.X, p.Y, q.X, q.Y, out xi, out yi, true);

                        if (xcode < 0)
                        {
                            results.Append(xi, yi, 0.0);
                            return 1;
                        }

                        return 0;
                    }

                case 1:
                    {
                        results.Append(q);
                        return 1;
                    }

                case 2:
                    {
                        results.Append(p);
                        return 1;
                    }

                case 3:
                    {
                        results.Append(p, q);	// order?
                        return 1;
                    }

                case 4:
                    {
                        results.Append(b);
                        return 1;
                    }

                case 5:
                    {
                        results.Append(q, b);
                        return 1;
                    }

                case 6:
                    {
                        results.Append(p, b);
                        return 1;
                    }

                case 7:
                    {
                        results.Append(p, q);	// order?
                        return 1;
                    }

                case 8:
                    {
                        results.Append(a);
                        return 1;
                    }

                case 9:
                    {
                        results.Append(a, q);
                        return 1;
                    }

                case 10:
                    {
                        results.Append(a, p);
                        return 1;
                    }

                case 11:
                    {
                        results.Append(p, q);	// order?
                        return 1;
                    }

            } // end switch

            throw new Exception("LineSegmentFeature.Intersect - Unexpected case");
        }
        /// <summary>
        /// Intersects a pair of circular arcs.
        /// </summary>
        /// <param name="results">Where to stick the results</param>
        /// <param name="a">The first arc</param>
        /// <param name="b">The second arc</param>
        /// <returns></returns>
        internal static uint Intersect(IntersectionResult results, ICircularArcGeometry ab, ICircularArcGeometry pq)
        {
            // Special handling if the two arcs share the same circle
            if (CircleGeometry.IsCoincident(ab.Circle, pq.Circle, Constants.XYRES))
                return ArcIntersect(results, ab, pq);

            // Arcs that meet exactly end to end get handled seperately.
            IPointGeometry a = ab.First;
            IPointGeometry b = ab.Second;
            IPointGeometry p = pq.First;
            IPointGeometry q = pq.Second;

            if (a.IsCoincident(p) || a.IsCoincident(q))
                return EndIntersect(results, ab, pq, true);

            if (b.IsCoincident(p) || b.IsCoincident(q))
                return EndIntersect(results, ab, pq, false);

            // Intersect the circle for the two arcs
            IPosition x1, x2;
            uint nx = Intersect(ab.Circle, pq.Circle, out x1, out x2);

            // Return if the circles don't intersect.
            if (nx==0)
                return 0;

            // Remember the intersection(s) if they fall in BOTH curve sectors.

            IPointGeometry thiscen = ab.Circle.Center;
            IPointGeometry othrcen = pq.Circle.Center;

            if (nx==1)
            {
                // If we got 1 intersection, it may be VERY close to the end
                // points. Make sure we also consider the precise check made up top.
                // Otherwise check if the intersection is in both sectors.

                IPointGeometry loc = PointGeometry.Create(x1); // rounded to nearest micron

                if (Geom.IsInSector(loc, thiscen, a, b, 0.0) &&
                    Geom.IsInSector(loc, othrcen, p, q, 0.0))
                {
                    results.Append(loc);
                    return 1;
                }

                return 0;
            }
            else
            {
                // Two intersections. They are valid if they fall within the arc's sector.
                // Again, make sure we consider any precise end-point check made above.

                uint nok=0;
                IPointGeometry loc1 = PointGeometry.Create(x1);
                IPointGeometry loc2 = PointGeometry.Create(x2);

                if (Geom.IsInSector(loc1, thiscen, a, b, 0.0) &&
                    Geom.IsInSector(loc1, othrcen, p, q, 0.0))
                {
                    results.Append(loc1);
                    nok++;
                }

                if (Geom.IsInSector(loc2, thiscen, a, b, 0.0) &&
                    Geom.IsInSector(loc2, othrcen, p, q, 0.0))
                {
                    results.Append(loc2);
                    nok++;
                }

                return nok;
            }
        }
 internal static uint Intersect(IntersectionResult result, ILineSegmentGeometry seg, ICircleGeometry circle)
 {
     return Intersect(result, seg.Start, seg.End, circle.Center, circle.Radius);
 }
Exemple #10
0
 internal override uint Intersect(IntersectionResult results)
 {
     return(Make().Intersect(results));
 }
Exemple #11
0
 internal override uint IntersectCircle(IntersectionResult results, ICircleGeometry circle)
 {
     return(Make().IntersectCircle(results, circle));
 }
Exemple #12
0
 internal override uint IntersectArc(IntersectionResult results, ICircularArcGeometry arc)
 {
     return(Make().IntersectArc(results, arc));
 }
Exemple #13
0
 internal override uint IntersectMultiSegment(IntersectionResult results, IMultiSegmentGeometry line)
 {
     return(Make().IntersectMultiSegment(results, line));
 }
Exemple #14
0
 internal override uint IntersectSegment(IntersectionResult results, ILineSegmentGeometry seg)
 {
     return(Make().IntersectSegment(results, seg));
 }
        /// <summary>
        /// Intersects a line segment with a circle
        /// </summary>
        /// <param name="result"></param>
        /// <param name="a">The start of the line segment</param>
        /// <param name="b">The end  of the line segment</param>
        /// <param name="c">The center of the circle</param>
        /// <param name="r">The radius of the circle</param>
        /// <returns></returns>
        static uint Intersect(IntersectionResult result, IPointGeometry a, IPointGeometry b, IPointGeometry c, double r)
        {
            // Get intersections (if any). Return if nothing.
            IPosition x1, x2;
            bool isGraze;
            uint nx = GetXCircle(a, b, c, r, out x1, out x2, out isGraze);
            if (nx==0)
                return 0;

            // If we got just one intersection, it's a simple intersect (even
            // if it's a tangent to the circle).
            if (nx==1)
            {
                result.Append(x1);
                return 1;
            }

            // That leaves us with two intersections, which may or may
            // not be grazing the circle.

            if (isGraze)
            {
                result.Append(x1, x2);
                return 1;
            }

            result.Append(x1);
            result.Append(x2);
            return 2;
        }
        internal static uint Intersect(IntersectionResult result, ILineSegmentGeometry seg, IMultiSegmentGeometry line)
        {
            uint nx=0;

            IPointGeometry a = seg.Start;
            IPointGeometry b = seg.End;
            IPointGeometry[] data = line.Data;

            for (int i=1; i<data.Length; i++)
                nx += Intersect(result, a, b, data[i-1], data[i]);

            return nx;
        }
        /// <summary>
        /// Delegate that's called whenever the index finds an object with an extent that
        /// overlaps the query window.
        /// </summary>
        /// <param name="item">The item to process (expected to be some sort of <c>LineFeature</c>)</param>
        /// <returns>True (always), indicating that the query should continue.</returns>
        private bool OnQueryHit(ISpatialObject item)
        {
            Debug.Assert(item is LineFeature);

            // Ignore if we're intersecting a line feature & the line we've found is that line
            LineFeature f = (LineFeature)item;

            if (Object.ReferenceEquals(m_Feature, f))
            {
                return(true);
            }

            // Ignore lines that don't have any topology
            Topology t = f.Topology;

            if (t == null)
            {
                return(true);
            }

            Debug.Assert(f.IsTopological);

            // Ignore lines that are marked as "moved"
            if (f.IsMoved)
            {
                return(true);
            }

            // Intersect each divider
            foreach (IDivider d in t)
            {
                // Ignore divider overlaps (regarded as non-topological)
                if (d.IsOverlap)
                {
                    continue;
                }

                // Search for intersections
                IntersectionResult other = new IntersectionResult(d);
                m_Geom.Intersect(other);

                if (other.IntersectCount > 0)
                {
                    // Determine the context of each intersection.
                    other.SetContext(m_Geom);

                    // If end-to-end simple intersections are not required, weed them out.
                    if (!m_WantEndEnd)
                    {
                        other.CutEndEnd();
                    }

                    if (other.IntersectCount > 0)
                    {
                        m_Result.Add(other);
                    }
                }
            }

            return(true);
        }
        internal static uint Intersect(IntersectionResult results, IMultiSegmentGeometry line, ICircularArcGeometry arc)
        {
            uint nx=0;

            IPointGeometry[] segs = line.Data;
            IPointGeometry f = arc.First;
            IPointGeometry s = arc.Second;
            ICircleGeometry circle = arc.Circle;

            for (int i=1; i<segs.Length; i++)
                nx += Intersect(results, segs[i-1], segs[i], f, s, circle);

            return nx;
        }
Exemple #19
0
 abstract internal uint Intersect(IntersectionResult results);
        internal static uint Intersect(IntersectionResult results, ICircleGeometry a, ICircleGeometry b)
        {
            IPointGeometry centre1 = a.Center;
            IPointGeometry centre2 = b.Center;
            double radius1 = a.Radius;
            double radius2 = b.Radius;

            // The following looks pretty similar to Geom.IntersectCircles (some tolerance values are
            // a bit more relaxed here).

            // Pull out the XY's for the 2 centres.
            double xc1 = centre1.X;
            double yc1 = centre1.Y;
            double xc2 = centre2.X;
            double yc2 = centre2.Y;

            // Get distance (squared) between the 2 centres.
            double dx = xc2 - xc1;
            double dy = yc2 - yc1;
            double distsq = dx*dx + dy*dy;

            //	If the two circles have the same centre, check whether
            //	the radii match (if so, we have an overlap case).

            if (distsq < Constants.TINY)
            {
                if (Math.Abs(radius1-radius2) < Constants.XYRES)
                {
                    double xi = xc1;
                    double yi = yc1 + radius1;
                    results.Append(xi, yi, xi, yi);
                    return 1;
                }
                else
                    return 0;
            }

            // We'll need the radii squared
            double rsq1 = radius1 * radius1;
            double rsq2 = radius2 * radius2;

            // Now some mathematical magic I got out a book.
            double delrsq = rsq2 - rsq1;
            double sumrsq = rsq1 + rsq2;
            double root = 2.0*sumrsq*distsq - distsq*distsq - delrsq*delrsq;

            //	Check for no intersection.
            if (root < Constants.TINY)
                return 0;

            // We have at least one intersection.
            double dstinv = 0.5 / distsq;
            double scl = 0.5 - delrsq*dstinv;
            double x = dx*scl + xc1;
            double y = dy*scl + yc1;

            //	Is it tangential?
            if (root < Constants.TINY)
            {
                results.Append(x, y, 0.0);
                return 1;
            }

            // Figure out 2 intersections.
            root = dstinv * Math.Sqrt(root);
            double xfac = dx*root;
            double yfac = dy*root;

            results.Append(x-yfac, y+xfac, 0.0);
            results.Append(x+yfac, y-xfac, 0.0);
            return 2;
        }
Exemple #21
0
 abstract internal uint IntersectSegment(IntersectionResult results, ILineSegmentGeometry seg);
        static uint ArcIntersect(IntersectionResult results, ICircularArcGeometry ab, ICircularArcGeometry pq)
        {
            // Arcs that meet exactly end to end get handled seperately.
            IPointGeometry a = ab.First;
            IPointGeometry b = ab.Second;
            IPointGeometry p = pq.First;
            IPointGeometry q = pq.Second;

            if (a.IsCoincident(p) || a.IsCoincident(q))
                //return ArcEndIntersect(results, pq.Circle, p, q, a, b);
                return ArcEndIntersect(results, pq.Circle, p, q, a, b, true);

            if (b.IsCoincident(p) || b.IsCoincident(q))
                //return ArcEndIntersect(results, pq.Circle, p, q, b, a);
                return ArcEndIntersect(results, pq.Circle, p, q, a, b, false);

            return ArcIntersect(results, pq.Circle, p, q, a, b);
        }
Exemple #23
0
 abstract internal uint IntersectMultiSegment(IntersectionResult results, IMultiSegmentGeometry line);
        /// <summary>
        /// Intersects a pair of clockwise arcs, where one of the ends exactly coincides with the
        /// other arc. The two arcs are assumed to sit on different circles.
        /// </summary>
        /// <param name="xsect">The intersection results.</param>
        /// <param name="bc">The start of the other arc.</param>
        /// <param name="ec">The end of the other arc.</param>
        /// <param name="circle">The circle that the other arc sits on.</param>
        /// <param name="xend">The end of THIS arc that coincides with one end of the other one.</param>
        /// <param name="othend">The other end of THIS arc (may or may not coincide with one end of
        /// the other arc).</param>
        /// <param name="xCircle">The circle for THIS arc</param>
        /// <returns>The number of intersections (1 or 2).</returns>
        static uint EndIntersect( IntersectionResult xsect
            , ICircularArcGeometry ab
            , ICircularArcGeometry pq
            , bool isFirstEndCoincident)
        {
            IPointGeometry bc = pq.First;
            IPointGeometry ec = pq.Second;
            ICircleGeometry circle = pq.Circle;
            IPointGeometry xend = (isFirstEndCoincident ? ab.First : ab.Second);
            IPointGeometry othend = (isFirstEndCoincident ? ab.Second : ab.First);
            ICircleGeometry xCircle = ab.Circle;

            // The two curves sit on different circles, so do a precise intersection of the circles.
            IPointGeometry c1 = xCircle.Center;
            IPointGeometry c2 = circle.Center;
            double r1 = xCircle.Radius;
            double r2 = circle.Radius;
            IPosition x1, x2;
            uint nx = Geom.IntersectCircles(c1, r1, c2, r2, out x1, out x2);

            // If we didn't get ANY intersections, that's a bit unusual
            // seeing how one of the ends matches. However, it's possible
            // due to roundoff of the end locations. So in that case, just
            // return a single intersection at the matching end.
            if (nx==0)
            {
                xsect.Append(xend);
                return 1;
            }

            // @devnote If we got 1 intersection (i.e. the 2 circles just
            // touch), you might be tempted to think that it must be close
            // to the matching end location. That is NOT the case if the
            // circles are big.

            // If we got 2 intersections, pick the one that's further away
            // than the matching end.
            if (nx==2 && Geom.DistanceSquared(x2, xend) > Geom.DistanceSquared(x1, xend))
                x1 = x2;

            // That leaves us with ONE intersection with the circle ... now
            // confirm that it actually intersects both curves!

            // Does it fall in the sector defined by the clockwise curve?

            IPointGeometry centre = c2;
            Turn reft = new Turn(centre, bc);
            double eangle = reft.GetAngleInRadians(ec);
            double xangle = reft.GetAngleInRadians(x1);
            if (xangle > eangle)
            {
                xsect.Append(xend);
                return 1;
            }

            // Does it fall in the sector defined by this curve (NO tolerance allowed).
            PointGeometry xloc = PointGeometry.Create(x1);
            bool isxthis = Geom.IsInSector(xloc, c1, ab.First, ab.Second, 0.0);
            if (!isxthis)
            {
                xsect.Append(xend);
                return 1;
            }

            // Get the midpoint of the segment that connects the intersection to the matching end.
            IPosition midx = Position.CreateMidpoint(xend, x1);

            // If the midpoint does NOT graze the circle, we've got 2 distinct intersections.

            // 25-NOV-99: Be realistic about it (avoid meaningless sliver
            // polygons that are less than 0.1mm wide on the ground). Also,
            // the old way used 'centre' which may refer to r1 OR r2, so
            // you would have got the correct result only half of the time!
            // if ( fabs(midx.Distance(centre) - r1) > XYTOL ) {

            double rdiff = Geom.Distance(midx, c1) - r1;
            if (Math.Abs(rdiff) > 0.0001)
            {
                xsect.Append(xend);
                xsect.Append(x1);
                return 2;
            }

            // We've got a graze, but possibly one that can be ignored(!). To
            // understand the reasoning here, bear in mind that lines get cut
            // only so that network topology can be formed. To do that, 2
            // orientation points are obtained for the lines incident on xend.
            // For curves, it's a position 5 metres along the curve (or the
            // total curve length if it's not that long). So if the graze is
            // closer than the point that will be used to get the orientation
            // point, we can ignore the graze, since it does not provide any
            // useful info.

            // Given that it's a graze, assume that it's ok to work out
            // the arc distance as if it was straight.
            double dsqx = Geom.DistanceSquared(xend, x1);

            // If it's closer than 4m (allow some leeway, seeing how we've
            // just done an approximation), ignore the intersection. If it's
            // actually between 4 and 5 metres, it shouldn't do any harm
            // to make a split there (although it's kind of redundant).
            if (dsqx < 16.0)
            {
                xsect.Append(xend);
                return 1;
            }

            // It's a graze.
            xsect.Append(xend, x1);
            return 1;
        }
Exemple #25
0
 abstract internal uint IntersectArc(IntersectionResult results, ICircularArcGeometry arc);
 internal override uint IntersectArc(IntersectionResult results, ICircularArcGeometry arc)
 {
     return Make().IntersectArc(results, arc);
 }
Exemple #27
0
 abstract internal uint IntersectCircle(IntersectionResult results, ICircleGeometry circle);
 internal override uint IntersectMultiSegment(IntersectionResult results, IMultiSegmentGeometry line)
 {
     return Make().IntersectMultiSegment(results, line);
 }
 internal override uint Intersect(IntersectionResult results)
 {
     return(results.IntersectMultiSegment(this));
 }
        /// <summary>
        /// Intersects a line segment with the data describing a clockwise curve.
        /// </summary>
        /// <param name="result">The intersection results.</param>
        /// <param name="a">The start of the line segment</param>
        /// <param name="b">The end of the line segment</param>
        /// <param name="start">The start of the clockwise arc.</param>
        /// <param name="end">The end of the clockwise arc.</param>
        /// <param name="circle">The circle on which the arc lies.</param>
        /// <returns></returns>
        static uint Intersect( IntersectionResult result
            , IPointGeometry a
            , IPointGeometry b
            , IPointGeometry start
            , IPointGeometry end
            , ICircleGeometry circle)
        {
            // If the segment exactly meets either end of the curve, it gets handled seperately.
            if (a.IsCoincident(start) || a.IsCoincident(end))
                return EndIntersect(result, start, end, circle, a, b);

            if (b.IsCoincident(start) || b.IsCoincident(end))
                return EndIntersect(result, start, end, circle, b, a);

            // Get circle definition.
            IPointGeometry centre = circle.Center;
            double radius = circle.Radius;

            // Get up to 2 intersections with the circle.
            IPosition x1, x2;
            bool isGraze;
            uint nx = GetXCircle(a, b, centre, radius, out x1, out x2, out isGraze);

            // Return if no intersections with the circle.
            if (nx==0)
                return 0;

            // If an intersection is really close to the end of an arc, force it to be there.
            if (Geom.DistanceSquared(start, x1) < Constants.XYTOLSQ)
                x1 = start;
            else if (Geom.DistanceSquared(end, x1) < Constants.XYTOLSQ)
                x1 = end;

            if (nx==2)
            {
                if (Geom.DistanceSquared(start, x2) < Constants.XYTOLSQ)
                    x2 = start;
                else if (Geom.DistanceSquared(end, x2) < Constants.XYTOLSQ)
                    x2 = end;
            }

            // Determine whether the intersections fall within the sector
            // that's defined by the clockwise curve (grazes need a bit
            // more handling, so do that after we see how to do the non-
            // grazing case.

            if ( !isGraze )
            {
                PointGeometry xloc1 = PointGeometry.Create(x1);
                double lintol = Constants.XYTOL / radius;

                // If we only got one intersect, and it's out of sector, that's us done.
                if (nx==1)
                {
                    if (!BasicGeom.IsInSector(xloc1, centre, start, end, lintol))
                        return 0;

                    result.Append(x1);
                    return 1;
                }

                // Two intersections with the circle ...

                if (BasicGeom.IsInSector(xloc1, centre, start, end, lintol))
                    result.Append(x1);
                else
                    nx--;

                PointGeometry xloc2 = PointGeometry.Create(x2);

                if (BasicGeom.IsInSector(xloc2, centre, start, end, lintol))
                    result.Append(x2);
                else
                    nx--;

                return nx;
            }

            // That leaves us with the case where this segment grazes the
            // circle. GetXCircle is always supposed to return nx==2 in that
            // case (they're also supposed to be arranged in the same
            // direction as this segment).
            Debug.Assert(nx==2);

            // Get the clockwise angle subtended by the circular arc. Add
            // on a tiny bit to cover numerical comparison problems.
            Turn reft = new Turn(centre, start);
            double maxangle = reft.GetAngleInRadians(end) + Constants.TINY;

            // Get the clockwise angles to both intersections.
            double a1 = reft.GetAngleInRadians(x1);
            double a2 = reft.GetAngleInRadians(x2);

            // No graze if both are beyond the arc sector.
            if (a1>maxangle && a2>maxangle)
                return 0;

            // If both intersects are within sector, the only thing to watch
            // out for is a case where the graze apparently occupies more
            // than half a circle. In that case, we've actually got 2 grazes.

            if (a1<maxangle &&  a2<maxangle)
            {
                if (a2>a1 && (a2-a1)>Constants.PI)
                {
                    result.Append(x1, start);
                    result.Append(end, x2);
                    return 2;
                }

                if (a1>a2 && (a1-a2)>Constants.PI)
                {
                    result.Append(start, x2);
                    result.Append(x1, end);
                    return 2;
                }

                // So it's just a regular graze.
                result.Append(x1, x2);
                return 1;
            }

            // That's covered the cases where both intersects are either
            // both in sector, or both out. Return the intersection that's
            // in sector as a simple intersection (NOT a graze).

            // This is a cop-out. We should really try to figure out which
            // portion of the curve is grazing, but the logic for doing so
            // is surprisingly complex, being subject to a variety of special
            // cases. By returning the intersect as a simple intersect, I'm
            // hoping it covers most cases.

            if (a1 < maxangle)
                result.Append(x1);
            else
                result.Append(x2);

            return 1;
        }
        /// <summary>
        /// Intersects this multi-segment with itself. Only SIMPLE intersections will be
        /// found. There are no special checks for multi-segments that graze themselves.
        /// </summary>
        /// <param name="xsect">The intersection results.</param>
        /// <returns>The number of self-intersections found.</returns>
        uint SelfIntersect(IntersectionResult xsect)
        {
            uint nx = 0;

            // Get an array of cumulative distances for each segment.
            IPointGeometry[] data    = this.Data;
            double[]         cumdist = GetCumDist(data);

            // Note start of initial segment (treat as the end of some imaginary line prior to the start).
            double xs;
            double ys;
            double xe = data[0].X;
            double ye = data[0].Y;

            // How many line segments have we got?
            int nseg = data.Length - 1;

            // Loop through each segment, intersecting it with all subsequent
            // segments, except for the one that immediately follows.
            for (int iseg = 1; iseg <= (nseg - 2); iseg++)
            {
                // The start of this segment is the end of the previous one.
                xs = xe;
                ys = ye;

                // Get the position of the end of the test segment
                xe = data[iseg].X;
                ye = data[iseg].Y;

                // Compare against subsequent segments (except the next one)
                for (int jseg = iseg + 2; jseg <= nseg; jseg++)
                {
                    IPointGeometry start = data[jseg - 1];
                    IPointGeometry end = data[jseg];
                    double         xi, yi;

                    if (Geom.CalcIntersect(start.X, start.Y, end.X, end.Y, xs, ys, xe, ye, out xi, out yi, true) != 0)
                    {
                        // Define distance to the intersection on the i-segment
                        double dx   = xi - xs;
                        double dy   = yi - ys;
                        double ilen = cumdist[iseg - 1] + Math.Sqrt(dx * dx + dy * dy);

                        // Likewise for the j-segment
                        dx = xi - start.X;
                        dy = yi - start.Y;
                        double jlen = cumdist[jseg - 1] + Math.Sqrt(dx * dx + dy * dy);

                        // Append TWO intersections.
                        xsect.Append(xi, yi, ilen);
                        xsect.Append(xi, yi, jlen);
                        nx += 2;
                    }
                }
            }

            // Sort the intersections (DON'T set new sort values).
            xsect.Sort(false);

            // Return the number of intersections
            return(nx);
        }
        /// <summary>
        /// Intersects a circle with a clockwise arc
        /// </summary>
        /// <param name="results"></param>
        /// <param name="c"></param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <param name="arcCircle"></param>
        /// <returns></returns>
        static uint Intersect(IntersectionResult xsect, ICircleGeometry c, IPointGeometry start, IPointGeometry end, ICircleGeometry arcCircle)
        {
            // If the circles are IDENTICAL, we've got a graze.
            if (CircleGeometry.IsCoincident(c, arcCircle, Constants.XYRES))
            {
                xsect.Append(start, end);
                return 1;

            }

            // Intersect the 2 circles.
            IPosition x1, x2;
            uint nx = Intersect(c, arcCircle, out x1, out x2);

            // Return if no intersection.
            if (nx==0)
                return 0;

            // Remember the intersection(s) if they fall in the
            // curve's sector. Use a tolerance which is based on
            // the circle with the smaller radius (=> bigger angular
            // tolerance).

            IPointGeometry centre;
            double minrad;

            if (c.Radius < arcCircle.Radius)
            {
                minrad = c.Radius;
                centre = c.Center;
            }
            else
            {
                minrad = arcCircle.Radius;
                centre = arcCircle.Center;
            }

            //	const FLOAT8 angtol = XYTOL/minrad;
            //	const FLOAT8 angtol = 0.00002/minrad;	// 20 microns
            double angtol = 0.002/minrad;		// 2mm

            if (nx==1)
            {
                IPointGeometry loc = PointGeometry.Create(x1);
                if (Geom.IsInSector(loc, centre, start, end, angtol))
                {
                    xsect.Append(loc);
                    return 1;
                }

                return 0;
            }
            else
            {
                // Two intersections. They are valid if they fall within the curve's sector.
                IPointGeometry loc1 = PointGeometry.Create(x1);
                IPointGeometry loc2 = PointGeometry.Create(x2);
                uint nok=0;

                if (Geom.IsInSector(loc1, centre, start, end, angtol))
                {
                    xsect.Append(loc1);
                    nok++;
                }

                if (Geom.IsInSector(loc2, centre, start, end, angtol))
                {
                    xsect.Append(loc2);
                    nok++;
                }

                return nok;
            }
        }
        /// <summary>
        /// Intersect this line with another line.
        /// </summary>
        /// <param name="line">The line to intersect with (not equal to THIS line)</param>
        /// <param name="closeTo">The point that the intersection should be closest to.
        /// Specify null if you don't care. In that case, if there are multiple intersections,
        /// you get the intersection that is closest to one of 3 points: the start of the
        /// direction line, the start of the line, or the end of the line.</param>
        /// <param name="xsect">The position of the intersection (if any). Null if not found.</param>
        /// <param name="closest">The default point that is closest to the intersection. Null if
        /// intersection wasn't found.</param>
        /// <returns>True if intersection was found.</returns>
        internal bool Intersect( LineFeature line
            , PointFeature closeTo
            , out IPosition xsect
            , out PointFeature closest)
        {
            // Initialize results
            xsect = null;
            closest = null;

            // Don't intersect a line with itself.
            if (Object.ReferenceEquals(this, line))
                throw new Exception("Cannot intersect a line with itself.");

            // Intersect this line with the other one.
            IntersectionResult xres = new IntersectionResult(this);
            uint nx = line.LineGeometry.Intersect(xres);
            if (nx==0)
                return false;

            // Determine which terminal point is the best.
            double mindsq = Double.MaxValue;

            if (xres.GetCloserPoint(this.StartPoint, ref mindsq, ref xsect))
                closest = this.StartPoint;

            if (xres.GetCloserPoint(this.EndPoint, ref mindsq, ref xsect))
                closest = this.EndPoint;

            if (xres.GetCloserPoint(line.StartPoint, ref mindsq, ref xsect))
                closest = line.StartPoint;

            if (xres.GetCloserPoint(line.EndPoint, ref mindsq, ref xsect))
                closest = line.EndPoint;

            // If a close-to point has been specified, that overrides
            // everything else (however, doing the above has the desired
            // effect of defining the best of the default points). In
            // this case, we allow an intersection that coincides with
            // the line being intersected.

            if (closeTo!=null)
                xres.GetClosest(closeTo, out xsect, 0.0);

            return (xsect!=null);
        }
 internal static uint Intersect(IntersectionResult result, ILineSegmentGeometry seg, ICircularArcGeometry arc)
 {
     if (CircularArcGeometry.IsCircle(arc))
         return Intersect(result, seg, arc.Circle);
     else
         return Intersect(result, seg.Start, seg.End, arc.First, arc.Second, arc.Circle);
 }
 internal override uint Intersect(IntersectionResult results)
 {
     return results.IntersectSegment(this);
 }
        internal static uint Intersect(IntersectionResult result, IMultiSegmentGeometry line1, IMultiSegmentGeometry line2)
        {
            uint nx=0;
            IPointGeometry[] pa = line1.Data;
            IPointGeometry[] pb = line2.Data;

            for (int i=1; i<pa.Length; i++)
            {
                IPointGeometry a = pa[i-1];
                IPointGeometry b = pa[i];

                for(int j=1; j<pb.Length; j++)
                    nx += Intersect(result, a, b, pb[j-1], pb[j]);
            }

            return nx;
        }
 internal override uint IntersectSegment(IntersectionResult results, ILineSegmentGeometry that)
 {
     return IntersectionHelper.Intersect(results, (ILineSegmentGeometry)this, that);
 }
        internal static uint Intersect(IntersectionResult results, IMultiSegmentGeometry line, ICircleGeometry circle)
        {
            uint nx=0;

            IPointGeometry[] segs = line.Data;
            IPointGeometry c = circle.Center;
            double r = circle.Radius;

            for (int i=1; i<segs.Length; i++)
                nx += Intersect(results, segs[i-1], segs[i], c, r);

            return nx;
        }
 /// <summary>
 /// Appends intersection info to this object.
 /// </summary>
 /// <param name="xsect">The intersection info to append.</param>
 void Append(IntersectionResult xsect)
 {
     m_Intersects.Add(xsect);
 }
 internal static uint Intersect(IntersectionResult results, ICircularArcGeometry a, ICircleGeometry b)
 {
     if (CircularArcGeometry.IsCircle(a))
         return Intersect(results, a.Circle, b);
     else
         return Intersect(results, b, a.First, a.Second, a.Circle);
 }
 /// <summary>
 /// Appends intersection info to this object.
 /// </summary>
 /// <param name="xsect">The intersection info to append.</param>
 void Append(IntersectionResult xsect)
 {
     m_Intersects.Add(xsect);
 }
 internal static uint Intersect(IntersectionResult results, ILineSegmentGeometry ab, ILineSegmentGeometry pq)
 {
     return Intersect(results, ab.Start, ab.End, pq.Start, pq.End);
 }
Exemple #43
0
 internal override uint IntersectMultiSegment(IntersectionResult results, IMultiSegmentGeometry that)
 {
     return(IntersectionHelper.Intersect(results, that, (ICircularArcGeometry)this));
 }
        /// <summary>
        /// Intersects a pair of clockwise arcs that sit on the same circle, and where ONE of
        /// the end points exactly matches.
        /// </summary>
        /// <param name="xsect">The intersection results.</param>
        /// <param name="circle">The circle the arcs coincide with</param>
        /// <param name="bc1">The BC of the 1st arc</param>
        /// <param name="ec1">The EC of the 1st arc</param>
        /// <param name="bc2">The BC of the 2nd arc -- the matching end</param>
        /// <param name="ec2">The EC of the 2nd arc</param>
        /// <param name="isStartMatch">Specify <c>true</c> if <paramref name="bc2"/> matches an end
        /// point of the 1st arc. Specify <c>false</c> if <paramref name="ec2"/> matches an end
        /// point of the 1st arc.</param>
        /// <returns>The number of intersections (always 1).</returns>
        static uint ArcEndIntersect( IntersectionResult xsect
            , ICircleGeometry circle
            , IPointGeometry bc1
            , IPointGeometry ec1
            , IPointGeometry bc2
            , IPointGeometry ec2
            , bool isStartMatch)
        {
            bool bmatch = bc1.IsCoincident(bc2);
            bool ematch = ec1.IsCoincident(ec2);

            // If the two curves share the same BC or same EC
            if (bmatch || ematch)
            {
                // We've got some sort of graze ...

                // Check for total graze.
                if (bmatch && ematch)
                    xsect.Append(bc1, ec1);
                else
                {
                    // We've therefore got a partial graze.

                    // If the length of this arc is longer than the other one, the graze is over the
                    // length of the other one, and vice versa. Since the two curves share the same
                    // radius and direction, the comparison just involves a comparison of the clockwise
                    // angles subtended by the arcs.

                    IPointGeometry centre = circle.Center;
                    double ang1 = new Turn(centre, bc1).GetAngleInRadians(ec1);
                    double ang2 = new Turn(centre, bc2).GetAngleInRadians(ec2);
                    bool isThisGraze = (ang1 < ang2);

                    if (isThisGraze)
                        xsect.Append(bc1, ec1);
                    else
                        xsect.Append(bc2, ec2);
                }
            }
            else
            {
                // The only intersection is at the common end.
                if (bc1.IsCoincident(bc2) || ec1.IsCoincident(bc2))
                    xsect.Append(bc2);
                else
                    xsect.Append(ec2);
            }

            return 1;
        }
Exemple #45
0
 internal override uint IntersectCircle(IntersectionResult results, ICircleGeometry that)
 {
     return(IntersectionHelper.Intersect(results, (ICircularArcGeometry)this, that));
 }
        /// <summary>
        /// Intersects 2 clockwise arcs that coincide with the perimeter of a circle.
        /// </summary>
        /// <param name="xsect">Intersection results.</param>
        /// <param name="circle">The circle the arcs coincide with</param>
        /// <param name="bc1">BC for 1st arc.</param>
        /// <param name="ec1">EC for 1st arc.</param>
        /// <param name="bc2">BC for 2nd arc.</param>
        /// <param name="ec2">EC for 2nd arc.</param>
        /// <returns>The number of intersections (0, 1, or 2). If non-zero, the intersections
        /// will be grazes.</returns>
        static uint ArcIntersect( IntersectionResult xsect
            , ICircleGeometry circle
            , IPointGeometry bc1
            , IPointGeometry ec1
            , IPointGeometry bc2
            , IPointGeometry ec2)
        {
            // Define the start of the clockwise arc as a reference line,
            // and get the clockwise angle to it's EC.
            Turn reft = new Turn(circle.Center, bc1);
            double sector = reft.GetAngleInRadians(ec1);

            // Where do the BC and EC of the 2nd curve fall with respect
            // to the 1st curve's arc sector?
            double bcang = reft.GetAngleInRadians(bc2);
            double ecang = reft.GetAngleInRadians(ec2);

            if (bcang<sector)
            {
                if (ecang<bcang)
                {
                    xsect.Append(bc2, ec1);
                    xsect.Append(bc1, ec2);
                    return 2;
                }

                if (ecang<sector)
                    xsect.Append(bc2, ec2);
                else
                    xsect.Append(bc2, ec1);

                return 1;
            }

            // The BC of the 2nd curve falls beyond the sector of the 1st ...
            // so we can't have any graze if the EC is even further on.
            if (ecang>bcang)
                return 0;

            // One graze ...

            if (ecang<sector)
                xsect.Append(bc1, ec2);
            else
                xsect.Append(bc1, ec1);

            return 1;
        }
Exemple #47
0
 internal override uint Intersect(IntersectionResult results)
 {
     return(results.IntersectArc(this));
 }
        /// <summary>
        /// Intersects a line segment with a clockwise arc, where at least one end of the
        /// segment exactly coincides with one end of the arc.
        /// </summary>
        /// <param name="xsect">The intersection results.</param>
        /// <param name="bc">The start of the clockwise arc.</param>
        /// <param name="ec">The end of the clockwise arc.</param>
        /// <param name="circle">The circle on which the arc lies.</param>
        /// <param name="xend">The end of the segment that coincides with one end of the arc.</param>
        /// <param name="othend">The other end of the segment (may or may not coincide
        /// with one end of the arc).</param>
        /// <returns>The number of intersections (either 1 or 2).</returns>
        static uint EndIntersect( IntersectionResult xsect
            , IPointGeometry bc
            , IPointGeometry ec
            , ICircleGeometry circle
            , IPointGeometry xend
            , IPointGeometry othend)
        {
            // If the other end is INSIDE the circle, the matching end
            // location is the one and only intersection. Allow a tolerance
            // that is consistent with the resolution of data (3 microns).
            IPointGeometry centre = circle.Center;
            double radius = circle.Radius;
            double minrad = (radius-Constants.XYTOL);
            double minrsq = (minrad*minrad);
            double othdsq = Geom.DistanceSquared(othend, centre);

            if (othdsq < minrsq)
            {
                xsect.Append(xend);
                return 1;
            }

            // If the other end of the segment also coincides with either
            // end of the curve, the segment is a chord of the circle that
            // the curve lies on. However, if it's REAL close, we need to
            // return it as a graze ...

            if (othend.IsCoincident(bc) || othend.IsCoincident(ec))
            {
                // Get the midpoint of the chord.
                IPosition midseg = Position.CreateMidpoint(xend, othend);

                // If the distance from the centre of the circle to the
                // midpoint is REAL close to the curve, we've got a graze.

                if (Geom.DistanceSquared(midseg, centre) > minrsq)
                {
                    xsect.Append(xend, othend);
                    return 1;
                }

                // Two distinct intersections.
                xsect.Append(xend);
                xsect.Append(othend);
                return 2;
            }

            // If the other end is within tolerance of the circle, project
            // it to the circle and see if it's within the curve's sector.
            // If not, it's not really an intersect.

            double maxrad = (radius+Constants.XYTOL);
            double maxrsq = (maxrad*maxrad);

            if ( othdsq < maxrsq )
            {
                // Check if the angle to the other end is prior to the EC.
                // If not, it's somewhere off the curve.
                Turn reft = new Turn(centre, bc);
                if (reft.GetAngleInRadians(othend) > reft.GetAngleInRadians(ec))
                {
                    xsect.Append(xend);
                    return 1;
                }

                // And, like above, see if the segment grazes or not ...

                // Get the midpoint of the chord.
                IPosition midseg = Position.CreateMidpoint(xend, othend);

                // If the distance from the centre of the circle to the
                // midpoint is REAL close to the curve, we've got a graze.

                if (Geom.DistanceSquared(midseg, centre) > minrsq)
                {
                    xsect.Append(xend, othend);
                    return 1;
                }

                // Two distinct intersections.
                xsect.Append(xend);
                xsect.Append(othend);
                return 2;
            }

            // That leaves us with the other end lying somewhere clearly
            // outside the circle. However, we could still have a graze.

            // Make sure the BC/EC are EXACTLY coincident with the circle (they
            // may have been rounded off if the curve has been intersected
            // with a location that's within tolerance of the circle).

            IPosition trueBC, trueEC;
            Position.GetCirclePosition(bc, centre, radius, out trueBC);
            Position.GetCirclePosition(ec, centre, radius, out trueEC);

            // As well as the end of the segment that meets the curve.
            IPosition trueXend = (xend.IsCoincident(bc) ? trueBC : trueEC);

            // Intersect the segment with the complete circle (this does
            // NOT return an intersection at the other end, even if it is
            // really close ... we took care of that above).

            // The intersection must lie ON the segment (not sure about this though).

            IPosition othvtx = othend;
            IPosition x1, x2;
            bool isTangent;
            uint nx = Geom.IntersectCircle(centre, radius, trueXend, othvtx, out x1, out x2, out isTangent, true);

            // If we got NOTHING, that's unexpected, since one end exactly coincides
            // with the circle. In that case, just return the matching end (NOT
            // projected to the true position).
            if (nx==0)
            {
                xsect.Append(xend);
                return 1;
            }

            // If we got 2 intersections, pick the one that's further away than the matching end.
            if (nx==2 && Geom.DistanceSquared(x2, trueXend) > Geom.DistanceSquared(x1, trueXend))
                x1 = x2;

            // That leaves us with ONE intersection with the circle ... now
            // confirm that it actually intersects the arc!

            Turn refbc = new Turn(centre, trueBC);
            double eangle = refbc.GetAngleInRadians(trueEC);
            double xangle = refbc.GetAngleInRadians(x1);

            if (xangle > eangle)
            {
                xsect.Append(xend);
                return 1;
            }

            // Get the midpoint of the segment that connects the intersection to the true end.
            IPosition midx = Position.CreateMidpoint(trueXend, x1);

            // If the midpoint does NOT graze the circle, we've got 2 distinct intersections.
            // 25-NOV-99: Be realistic about it (avoid meaningless sliver polygons that are
            // less than 0.1mm wide on the ground).

            // if ( midx.DistanceSquared(centre) < minrsq ) {
            double rdiff = Geom.Distance(midx, centre) - radius;
            if (Math.Abs(rdiff) > 0.0001)
            {
                xsect.Append(xend);
                xsect.Append(x1);
                return 2;
            }

            // We've got a graze, but possibly one that can be ignored(!). To
            // understand the reasoning here, bear in mind that lines get cut
            // only so that network topology can be formed. To do that, 2
            // orientation points are obtained for the lines incident on xend.
            // For the segment, the orientation point is the other end of the
            // segment. For the curve, it's a position 5 metres along the
            // curve (or the total curve length if it's not that long). So
            // if the graze is closer than the point that will be used to
            // get the orientation point, we can ignore the graze, since it
            // does not provide any useful info.

            // Given that it's a graze, assume that it's ok to work out
            // the arc distance as if it was straight.
            double dsqx = Geom.DistanceSquared(trueXend, x1);

            // If it's closer than 4m (allow some leeway, seeing how we've
            // just done an approximation), ignore the intersection. If it's
            // actually between 4 and 5 metres, it shouldn't do any harm
            // to make a split there (although it's kind of redundant).
            if (dsqx < 16.0)
            {
                xsect.Append(xend);
                return 1;
            }

            // It's a graze.
            //CeVertex vxend(xend);	// wants a vertex
            xsect.Append(xend, x1);
            return 1;
        }
 internal override uint Intersect(IntersectionResult results)
 {
     return Make().Intersect(results);
 }
        /// <summary>
        /// Delegate that's called whenever the index finds an object with an extent that
        /// overlaps the query window.
        /// </summary>
        /// <param name="item">The item to process (expected to be some sort of <c>LineFeature</c>)</param>
        /// <returns>True (always), indicating that the query should continue.</returns>
        private bool OnQueryHit(ISpatialObject item)
        {
            Debug.Assert(item is LineFeature);

            // Ignore if we're intersecting a line feature & the line we've found is that line
            LineFeature f = (LineFeature)item;
            if (Object.ReferenceEquals(m_Feature, f))
                return true;

            // Ignore lines that don't have any topology
            Topology t = f.Topology;
            if (t == null)
                return true;

            Debug.Assert(f.IsTopological);

            // Ignore lines that are marked as "moved"
            if (f.IsMoved)
                return true;

            // Intersect each divider
            foreach (IDivider d in t)
            {
                // Ignore divider overlaps (regarded as non-topological)
                if (d.IsOverlap)
                    continue;

                // Search for intersections
                IntersectionResult other = new IntersectionResult(d);
                m_Geom.Intersect(other);

                if (other.IntersectCount>0)
                {
                    // Determine the context of each intersection.
                    other.SetContext(m_Geom);

                    // If end-to-end simple intersections are not required, weed them out.
                    if (!m_WantEndEnd)
                        other.CutEndEnd();

                    if (other.IntersectCount>0)
                        m_Result.Add(other);
                }
            }

            return true;
        }
Exemple #51
0
 internal override uint IntersectMultiSegment(IntersectionResult results, IMultiSegmentGeometry that)
 {
     return(IntersectionHelper.Intersect(results, (ILineSegmentGeometry)this, that));
 }