示例#1
0
        /// <summary>
        /// Returns the projection of this UV as a point from a specified line.
        /// </summary>
        /// <param name="line">The line.</param>
        /// <returns>UV.</returns>
        public UV Projection(UVLine line)
        {
            double u = (line.End - line.Start).DotProduct(this - line.Start);

            u /= line.GetLength();
            return(line.FindPoint(u));
        }
示例#2
0
        /// <summary>
        /// Return ths distance of the UV as a point from a line.
        /// </summary>
        /// <param name="line">The line.</param>
        /// <returns>System.Double.</returns>
        public double DistanceTo(UVLine line)
        {
            double area = (line.Start - line.End).CrossProductValue(line.Start - this);

            area = Math.Abs(area);
            return(area / line.GetLength());
        }
示例#3
0
        /// <summary>
        /// Returns a parameter at the intersection point with another line if found. This function takes the length of this line if it is available for performance optimization.
        /// </summary>
        /// <param name="line">The line.</param>
        /// <param name="length">The length of this line.</param>
        /// <param name="tolerance">The tolerance.</param>
        /// <returns>System.Nullable&lt;System.Double&gt;.</returns>
        public double?Intersection(UVLine line, double length, double tolerance = .000001f)
        {
            UV     lineVector = this.End - this.Start;
            double area1      = lineVector.CrossProductValue(line.Start - this.Start);
            double area2      = lineVector.CrossProductValue(line.End - this.Start);

            if (area1 * area2 > tolerance)
            {
                lineVector = null;
                return(null);
            }
            lineVector = line.End - line.Start;
            area1      = lineVector.CrossProductValue(this.Start - line.Start);
            area2      = lineVector.CrossProductValue(this.End - line.Start);
            if (area1 * area2 > tolerance)
            {
                lineVector = null;
                return(null);
            }
            double a1 = (line.Start - this.Start).CrossProductValue(line.End - this.Start);

            if (a1 == 0)
            {
                return(Math.Min(line.Start.DistanceTo(this.Start), line.End.DistanceTo(this.Start)));
            }
            lineVector = null;
            double u = length * Math.Abs(a1) / (Math.Abs(area1) + Math.Abs(area2));

            return(u);
        }
示例#4
0
        /// <summary>
        /// Returns a parameter at the intersection point with another line if found.
        /// </summary>
        /// <param name="l">The l.</param>
        /// <param name="tolerance">The tolerance.</param>
        /// <returns>System.Nullable&lt;System.Double&gt;.</returns>
        public double?Intersection(UVLine l, double tolerance = OSMDocument.AbsoluteTolerance)
        {
            UV     lineVector = this.End - this.Start;
            double area1      = lineVector.CrossProductValue(l.Start - this.Start);
            double area2      = lineVector.CrossProductValue(l.End - this.Start);

            if (area1 * area2 > tolerance)
            {
                lineVector = null;
                return(null);
            }
            lineVector = l.End - l.Start;
            area1      = lineVector.CrossProductValue(this.Start - l.Start);
            area2      = lineVector.CrossProductValue(this.End - l.Start);
            if (area1 * area2 > tolerance)
            {
                lineVector = null;
                return(null);
            }
            //double lengthL = l.GetLength();
            double a1 = (l.Start - this.Start).CrossProductValue(l.End - this.Start);

            if (a1 == 0)
            {
                return(Math.Min(l.Start.DistanceTo(this.Start), l.End.DistanceTo(this.Start)));
            }
            lineVector = null;
            double u = this.GetLength() * Math.Abs(a1) / (Math.Abs(area1) + Math.Abs(area2));

            return(u);
        }
示例#5
0
        /// <summary>
        /// Finds the closest point on the polygon from a given point
        /// </summary>
        /// <param name="points">The points that represent a polygon.</param>
        /// <param name="p">The point from which the closest point should be found.</param>
        /// <param name="closed">if set to <c>true</c> the polygon is closed.</param>
        /// <returns>UV.</returns>
        public static UV ClosestPoint(UV[] points, UV p, bool closed)
        {
            UV[]     vecs       = new UV[points.Length];
            double[] vecLengths = new double[points.Length];
            for (int i = 0; i < points.Length; i++)
            {
                vecs[i]       = points[i] - p;
                vecLengths[i] = vecs[i].GetLengthSquared();
            }
            double minDistSquared = double.PositiveInfinity;
            int    index          = 0;

            for (int i = 0; i < points.Length - 1; i++)
            {
                double area = vecs[i].CrossProductValue(vecs[i + 1]);
                area *= area;
                double d1          = UV.GetLengthSquared(points[i], points[i + 1]);
                double distSquared = area / d1;
                if (distSquared < vecLengths[i] - d1 || distSquared < vecLengths[i + 1] - d1)
                {
                    distSquared = Math.Min(vecLengths[i + 1], vecLengths[i]);
                }
                if (minDistSquared > distSquared)
                {
                    minDistSquared = distSquared;
                    index          = i;
                }
            }
            if (closed)
            {
                double area = vecs[points.Length - 1].CrossProductValue(vecs[0]);
                area *= area;
                double d1          = UV.GetLengthSquared(points[points.Length - 1], points[0]);
                double distSquared = area / d1;
                if (distSquared < vecLengths[0] - d1 || distSquared < vecLengths[points.Length - 1] - d1)
                {
                    distSquared = Math.Min(vecLengths[0], vecLengths[points.Length - 1]);
                }
                if (minDistSquared > distSquared)
                {
                    minDistSquared = distSquared;
                    index          = points.Length - 1;
                }
            }
            int j = index + 1;

            if (j == points.Length)
            {
                j = 0;
            }
            UVLine line = new UVLine(points[index], points[j]);

            return(p.GetClosestPoint(line));
        }
示例#6
0
        /// <summary>
        /// Gets the reflection of this UV as a vector from a line.
        /// </summary>
        /// <param name="line">The line.</param>
        /// <returns>UV.</returns>
        public UV GetReflection(UVLine line)
        {
            var vector = line.GetDirection();

            vector.Unitize();
            double dotPro = this.DotProduct(vector);
            UV     horizontal_Component = vector * dotPro;
            UV     normal_Component     = this - horizontal_Component;
            var    result = horizontal_Component - normal_Component;

            return(result);
        }
示例#7
0
        /// <summary>
        /// Gets the closest point of this UV as a point from a line.
        /// </summary>
        /// <param name="line">The line.</param>
        /// <returns>UV.</returns>
        public UV GetClosestPoint(UVLine line)
        {
            double length = line.GetLength();
            double u      = (line.End - line.Start).DotProduct(this - line.Start);

            u /= length;
            if (u < 0)
            {
                return(line.Start);
            }
            if (u > length)
            {
                return(line.End);
            }
            return(line.FindPoint(u));
        }
示例#8
0
        /// <summary>
        /// Gets the distance squared of this UV as a point from a line.
        /// </summary>
        /// <param name="line">The line.</param>
        /// <returns>System.Double.</returns>
        public double GetDistanceSquared(UVLine line)
        {
            UV     vs   = this - line.Start;
            double vs2  = vs.GetLengthSquared();
            UV     ve   = this - line.End;
            double ve2  = ve.GetLengthSquared();
            double area = vs.CrossProductValue(ve);

            area *= area;
            double d           = UV.GetLengthSquared(line.Start, line.End);
            double distSquared = area / d;

            if (distSquared < vs2 - d || distSquared < ve2 - d)
            {
                distSquared = Math.Min(vs2, ve2);
            }
            return(distSquared);
        }
示例#9
0
        public override bool Equals(object obj)
        {
            UVLine l = obj as UVLine;

            if (l == null)
            {
                return(false);
            }
            else
            {
                if ((l.Start == this.Start && l.End == this.End) ||
                    (l.End == this.Start && l.Start == this.End))
                {
                    return(true);
                }
            }
            return(false);
        }
示例#10
0
        /// <summary>
        /// Gets the closest point of this UV as a point from a line.
        /// </summary>
        /// <param name="line">The line.</param>
        /// <param name="isEndPoint">if set to <c>true</c> the closest point is the end point of the line.</param>
        /// <returns>UV.</returns>
        public UV GetClosestPoint(UVLine line, ref bool isEndPoint)
        {
            double length = line.GetLength();
            double u      = (line.End - line.Start).DotProduct(this - line.Start);

            u /= length;
            if (u < 0)
            {
                isEndPoint = true;
                return(line.Start);
            }
            if (u > length)
            {
                isEndPoint = true;
                return(line.End);
            }
            isEndPoint = false;
            return(line.FindPoint(u));
        }
示例#11
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PLine"/> class.
 /// </summary>
 /// <param name="line">A line to start with.</param>
 /// <param name="numberOfFractionalDigits">The number of fractional digits used as the tolerance of equality.</param>
 /// <exception cref="ArgumentException">Line length is zero</exception>
 public PLine(UVLine line, int numberOfFractionalDigits = 5, double tolerance = OSMDocument.AbsoluteTolerance)
 {
     if (line.End == line.Start)
     {
         throw new ArgumentException("Line length is zero");
     }
     this._end     = line.End;
     this._start   = line.Start;
     this._pntList = new List <UV>()
     {
         this._start,
         this._end,
     };
     this._comparer = new UVComparer(numberOfFractionalDigits, tolerance);
     this._pntSet   = new HashSet <UV>(this._comparer)
     {
         this._end,
         this._start
     };
     this.Closed = false;
 }
示例#12
0
        /// <summary>
        /// Returns the closest distance of this UV as a point from a line .
        /// </summary>
        /// <param name="line">The line.</param>
        /// <returns>System.Double.</returns>
        public double ClosestDistance(UVLine line)
        {
            UV     p      = new UV();
            double length = line.GetLength();
            double u      = (line.End - line.Start).DotProduct(this - line.Start);

            u /= length;
            if (u < 0)
            {
                p = line.Start;
            }
            else if (u > length)
            {
                p = line.End;
            }
            else
            {
                p = this.GetClosestPoint(line);
            }
            return(p.DistanceTo(this));
        }
示例#13
0
        /// <summary>
        /// Determines if this line intersects with another line.
        /// </summary>
        /// <param name="l">The l.</param>
        /// <param name="tolerance">The tolerance.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        public bool Intersects(UVLine l, double tolerance = OSMDocument.AbsoluteTolerance)
        {
            UV     lineVector = this.End - this.Start;
            double area1      = lineVector.CrossProductValue(l.Start - this.Start);
            double area2      = lineVector.CrossProductValue(l.End - this.Start);

            if (area1 * area2 > tolerance)
            {
                lineVector = null;
                return(false);
            }
            lineVector = l.End - l.Start;
            area1      = lineVector.CrossProductValue(this.Start - l.Start);
            area2      = lineVector.CrossProductValue(this.End - l.Start);
            if (area1 * area2 > tolerance)
            {
                lineVector = null;
                return(false);
            }
            return(true);
        }
示例#14
0
        /// <summary>
        /// Extracts a list of polylines from an arbitrary collection of lines. NOTE: There might be different possibilities for this operation.
        /// </summary>
        /// <param name="lines">The lines.</param>
        /// <param name="fractionalDigits">The fractional digits used for hashing.</param>
        /// <param name="tolerance">The tolerance of point equality.</param>
        /// <returns>List&lt;PLine&gt;.</returns>
        public static List <PLine> ExtractPLines(ICollection <UVLine> lines, int fractionalDigits = 5, double tolerance = OSMDocument.AbsoluteTolerance)
        {
            Dictionary <UV, HashSet <UVLine> > pntToLine = new Dictionary <UV, HashSet <UVLine> >(new UVComparer(fractionalDigits, tolerance));

            foreach (var item in lines)
            {
                if (item.GetLengthSquared() > 0)
                {
                    if (pntToLine.ContainsKey(item.Start))
                    {
                        pntToLine[item.Start].Add(item);
                    }
                    else
                    {
                        var set = new HashSet <UVLine>()
                        {
                            item
                        };
                        pntToLine.Add(item.Start, set);
                    }
                    if (pntToLine.ContainsKey(item.End))
                    {
                        pntToLine[item.End].Add(item);
                    }
                    else
                    {
                        var list = new HashSet <UVLine>()
                        {
                            item
                        };
                        pntToLine.Add(item.End, list);
                    }
                }
                else
                {
                    MessageBox.Show("Line with zero length cannot be added to a polyLine!");
                }
            }
            List <PLine> pLines = new List <PLine>();

            while (pntToLine.Count != 0)
            {
                UVLine line = null;
                try
                {
                    line = pntToLine.First().Value.First();
                }
                catch (Exception e)
                {
                    MessageBox.Show("Failed at 3\n" + e.Report());
                }
                PLine pLine = new PLine(line, fractionalDigits);
                //lines.Remove(line);
                pntToLine[line.Start].Remove(line);
                if (pntToLine[line.Start].Count == 0)
                {
                    pntToLine.Remove(line.Start);
                }
                pntToLine[line.End].Remove(line);
                if (pntToLine[line.End].Count == 0)
                {
                    pntToLine.Remove(line.End);
                }
                bool iterate = true;
                while (iterate)
                {
                    iterate = false;
                    if (pntToLine.ContainsKey(pLine._start))
                    {
                        UVLine line_ = null;
                        try
                        {
                            line_ = pntToLine[pLine._start].First();
                        }
                        catch (Exception e)
                        {
                            MessageBox.Show("Failed at 1\n" + e.Report());
                        }
                        pLine.addSegment(line_);
                        pntToLine[line_.Start].Remove(line_);
                        if (pntToLine[line_.Start].Count == 0)
                        {
                            pntToLine.Remove(line_.Start);
                        }
                        pntToLine[line_.End].Remove(line_);
                        if (pntToLine[line_.End].Count == 0)
                        {
                            pntToLine.Remove(line_.End);
                        }
                        //lines.Remove(line);
                        if (pLine.Closed)
                        {
                            break;
                        }
                        iterate = true;
                    }
                    if (pntToLine.Count == 0)
                    {
                        break;
                    }
                    if (pntToLine.ContainsKey(pLine._end))
                    {
                        UVLine line_ = null;
                        try
                        {
                            line_ = pntToLine[pLine._end].First();
                        }
                        catch (Exception e)
                        {
                            MessageBox.Show("Failed at 2\n" + e.Report());
                            try
                            {
                                line_ = pntToLine[pLine._end].First();
                            }
                            catch (Exception)
                            {
                            }
                        }
                        pLine.addSegment(line_);
                        pntToLine[line_.Start].Remove(line_);
                        if (pntToLine[line_.Start].Count == 0)
                        {
                            pntToLine.Remove(line_.Start);
                        }
                        pntToLine[line_.End].Remove(line_);
                        if (pntToLine[line_.End].Count == 0)
                        {
                            pntToLine.Remove(line_.End);
                        }
                        //lines.Remove(line);
                        if (pLine.Closed)
                        {
                            break;
                        }
                        iterate = true;
                    }
                }
                pLines.Add(pLine);
            }
            return(pLines);
        }
示例#15
0
        private bool addSegment(UVLine line)
        {
            try
            {
                if (this.Closed)
                {
                    return(false);
                }
                else
                {
                    if (this._pntSet.Contains(line.Start) && this._pntSet.Contains(line.End))
                    {
                        if (this._comparer.Equals(this._start, line.Start) && this._comparer.Equals(this._end, line.End))
                        {
                            this.Closed = true;
                            return(true);
                        }
                        else if (this._comparer.Equals(this._start, line.End) && this._comparer.Equals(this._end, line.Start))
                        {
                            this.Closed = true;
                            return(true);
                        }
                        else
                        {
                            /*
                             * StringBuilder sb = new StringBuilder();
                             * sb.AppendLine("POINTS:");
                             * foreach (var item in this._pntList)
                             * {
                             *  sb.AppendLine(item.ToString());
                             * }
                             * sb.AppendLine("\nAdded Line:");
                             * sb.AppendLine(line.Start.ToString());
                             * sb.AppendLine(line.End.ToString());
                             * MessageBox.Show(sb.ToString());
                             * sb.Clear();
                             * sb = null;
                             * throw new ArgumentException("Self intersection");
                             */
                        }
                    }

                    if (this._comparer.Equals(this._start, line.Start))

                    {
                        this.addStart(line.End);
                        return(true);
                    }
                    if (this._comparer.Equals(this._start, line.End))
                    {
                        this.addStart(line.Start);
                        return(true);
                    }
                    if (this._comparer.Equals(this._end, line.End))
                    {
                        this.addEnd(line.Start);
                        return(true);
                    }
                    if (this._comparer.Equals(this._end, line.Start))
                    {
                        this.addEnd(line.End);
                        return(true);
                    }
                }
                return(false);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Report());
            }
            return(false);
        }