Esempio n. 1
0
 /// <summary>
 /// Creates a new vector from a line segment, assuming that the direction is from the start point to the end point
 /// </summary>
 /// <param name="LineLineSegment">A Topology.LineSegment object to turn into a vector</param>
 public Vector(LineSegment LineLineSegment)
 {
     X = LineLineSegment.X2 - LineLineSegment.X1;
     Y = LineLineSegment.Y2 - LineLineSegment.Y1;
     Z = LineLineSegment.Z2 - LineLineSegment.Z1;
 }
Esempio n. 2
0
        /// <summary>
        /// Checks whether the borders of a polygon shape, lines of line shapes, or points of point shapes touch.
        /// </summary>
        /// <param name="Shape1">A MapWinGIS.Shape object to test</param>
        /// <param name="Shape2">A MapWinGIS.Shape object to test</param>
        /// <returns>True if the boundaries touch</returns>
        public static bool ShapeBoundariesTouch(MapWinGIS.Shape Shape1, MapWinGIS.Shape Shape2)
        {
            if (Shape1 == null || Shape1.ShapeType == MapWinGIS.ShpfileType.SHP_NULLSHAPE)
            {
                throw new ArgumentException("Argument Shape1 cannot be null");
            }
            if (Shape2 == null || Shape2.ShapeType == MapWinGIS.ShpfileType.SHP_NULLSHAPE)
            {
                throw new ArgumentException("Argument Shape2 cannot be null");
            }
            if (Shape1.ShapeType == MapWinGIS.ShpfileType.SHP_MULTIPATCH)
            {
                throw new ArgumentException("Multipatch is not supported");
            }
            if (Shape2.ShapeType == MapWinGIS.ShpfileType.SHP_MULTIPATCH)
            {
                throw new ArgumentException("Multipatch is not supported");
            }

            ShapeCategories Typ1, Typ2;

            Typ1 = GetCategory(Shape1);
            Typ2 = GetCategory(Shape2);

            // for single points, simply show if these specific points overlap
            if (Typ1 == ShapeCategories.Point &&
                Typ2 == ShapeCategories.Point)
            {
                Point p1 = new Point(Shape1.get_Point(0));
                Point p2 = new Point(Shape2.get_Point(0));
                if (p1.Intersects(p2))
                {
                    return(true);
                }
                return(false);
            }

            // Point to Non-point
            if (Typ1 == ShapeCategories.Point)
            {
                Point p1 = new Point(Shape1.get_Point(0));

                if (Typ2 == ShapeCategories.MultiPoint)
                {
                    for (int I = 0; I < Shape2.numPoints; I++)
                    {
                        Point p2 = new Point(Shape2.get_Point(I));
                        if (p1.Intersects(p2))
                        {
                            return(true);
                        }
                    }
                    return(false);
                }
                else
                {
                    for (int I = 0; I < Shape2.numPoints - 1; I++)
                    {
                        LineSegment seg = new LineSegment(Shape2.get_Point(I), Shape2.get_Point(I + 1));
                        if (seg.Intersects(p1))
                        {
                            return(true);
                        }
                    }
                    return(false);
                }
            }

            // Point2 to non-point
            if (Typ2 == ShapeCategories.Point)
            {
                Point p2 = new Point(Shape2.get_Point(0));

                if (Typ1 == ShapeCategories.MultiPoint)
                {
                    for (int I = 0; I < Shape1.numPoints; I++)
                    {
                        Point p1 = new Point(Shape1.get_Point(I));
                        if (p2.Intersects(p1))
                        {
                            return(true);
                        }
                    }
                    return(false);
                }
                else
                {
                    for (int I = 0; I < Shape1.numPoints - 1; I++)
                    {
                        LineSegment seg = new LineSegment(Shape1.get_Point(I), Shape1.get_Point(I + 1));
                        if (seg.Intersects(p2))
                        {
                            return(true);
                        }
                    }
                    return(false);
                }
            }

            // for multipoint, test every point for intersection.
            if (Typ1 == ShapeCategories.MultiPoint &&
                Typ2 == ShapeCategories.MultiPoint)
            {
                List <int> Points1 = PointsWithinEnvelope(Shape1, Shape2.Extents);
                List <int> Points2 = PointsWithinEnvelope(Shape2, Shape1.Extents);
                for (int I = 0; I < Points1.Count; I++)
                {
                    for (int J = 0; J < Points2.Count; J++)
                    {
                        Point p1 = new Point(Shape1.get_Point(I));
                        Point p2 = new Point(Shape2.get_Point(J));
                        if (p1.Intersects(p2))
                        {
                            return(true);
                        }
                    }
                }
                return(false);
            }
            // For lines and polygons simply test line segments in the area of interrest to see if they touch
            // (touching in this case just equates to having a minimum distance of 0.
            if ((Typ1 == ShapeCategories.Line || Typ1 == ShapeCategories.Polygon) &&
                (Typ2 == ShapeCategories.Line || Typ2 == ShapeCategories.Polygon))
            {
                List <LineSegment> Segs1 = LineSegmentsWithinEnvelope(Shape1, Shape2.Extents);
                List <LineSegment> Segs2 = LineSegmentsWithinEnvelope(Shape2, Shape1.Extents);
                for (int I = 0; I < Segs1.Count; I++)
                {
                    for (int J = 0; J < Segs2.Count; J++)
                    {
                        if (Segs1[I].Intersects(Segs2[J]))
                        {
                            return(true);
                        }
                    }
                }
                return(false);
            }

            // multi-point to polygon
            if (Typ1 == ShapeCategories.MultiPoint)
            {
                List <int>         Points1 = PointsWithinEnvelope(Shape1, Shape2.Extents);
                List <LineSegment> Segs2   = LineSegmentsWithinEnvelope(Shape2, Shape1.Extents);
                for (int I = 0; I < Points1.Count; I++)
                {
                    for (int J = 0; J < Segs2.Count; J++)
                    {
                        if (Segs2[J].Intersects(Shape1.get_Point(Points1[I])))
                        {
                            return(true);
                        }
                    }
                }
                return(false);
            }

            if (Typ2 == ShapeCategories.MultiPoint)
            {
                List <int>         Points2 = PointsWithinEnvelope(Shape2, Shape1.Extents);
                List <LineSegment> Segs1   = LineSegmentsWithinEnvelope(Shape1, Shape2.Extents);
                for (int I = 0; I < Points2.Count; I++)
                {
                    for (int J = 0; J < Segs1.Count; J++)
                    {
                        if (Segs1[J].Intersects(Shape2.get_Point(Points2[I])))
                        {
                            return(true);
                        }
                    }
                }
                return(false);
            }



            return(false);
        }
Esempio n. 3
0
        /// <summary>
        /// Determines the shortest distance between two segments
        /// </summary>
        /// <param name="LineLineSegment">LineSegment, The line segment to test against this segment</param>
        /// <returns>Double, the shortest distance between two segments</returns>
        public double Distance(LineSegment LineLineSegment)
        {
            //http://www.geometryalgorithms.com/Archive/algorithm_0106/algorithm_0106.htm
            const double SMALL_NUM = 0.00000001;
            Vector       u = new Vector(this);            // LineSegment 1
            Vector       v = new Vector(LineLineSegment); // LineSegment 2
            Vector       w = new Vector(this.StartPoint, LineLineSegment.StartPoint);
            double       a = u.Dot(u);                    // length of segment 1
            double       b = u.Dot(v);                    // length of segment 2 projected onto line 1
            double       c = v.Dot(v);                    // length of segment 2
            double       d = u.Dot(w);                    //
            double       e = v.Dot(w);
            double       D = a * c - b * b;
            double       sc, sN, sD = D;
            double       tc, tN, tD = D;

            // compute the line parameters of the two closest points
            if (D < SMALL_NUM) // the lines are almost parallel
            {                  // force using point P0 on segment 1
                sN = 0.0;      // to prevent possible division by 0 later
                sD = 1.0;
                tN = e;
                tD = c;
            }
            else // get the closest points on the infinite lines
            {
                sN = (b * e - c * d);
                tN = (a * e - b * d);
                if (sN < 0.0) // sc < 0 => the s=0 edge is visible
                {
                    sN = 0.0;
                    tN = e;
                    tD = c;
                }
                else if (sN > sD) // sc > 1 => the s=1 edge is visible
                {
                    sN = sD;
                    tN = e + b;
                    tD = c;
                }
            }
            if (tN < 0.0) // tc < 0 => the t=0 edge is visible
            {
                tN = 0.0;
                // recompute sc for this edge
                if (-d < 0.0)
                {
                    sN = 0.0;
                }
                else if (-d > a)
                {
                    sN = sD;
                }
                else
                {
                    sN = -d;
                    sD = a;
                }
            }
            else if (tN > tD) // tc > 1 => the t = 1 edge is visible
            {
                // recompute sc for this edge
                if ((-d + b) < 0.0)
                {
                    sN = 0;
                }
                else if ((-d + b) > a)
                {
                    sN = sD;
                }
                else
                {
                    sN = (-d + b);
                    sD = a;
                }
            }
            // finally do the division to get sc and tc
            if (Math.Abs(sN) < SMALL_NUM)
            {
                sc = 0.0;
            }
            else
            {
                sc = sN / sD;
            }
            if (Math.Abs(tN) < SMALL_NUM)
            {
                tc = 0.0;
            }
            else
            {
                tc = tN / tD;
            }
            // get the difference of the two closest points
            Vector dU = u.Times(sc);
            Vector dV = v.Times(tc);
            Vector dP = (w.Plus(dU)).Minus(dV);

            // S1(sc) - S2(tc)
            return(dP.Magnitude);
        }