Пример #1
0
        /// <summary>
        /// Computes the centre of the circumcircle of this vertex and two others.
        /// </summary>
        /// <param name="b" />
        /// <param name="c" />
        /// <returns>the Coordinate which is the circumcircle of the 3 points.</returns>
        public Vertex CircleCenter(Vertex b, Vertex c)
        {
            var a = new Vertex(X, Y);
            // compute the perpendicular bisector of cord ab
            var cab = Bisector(a, b);
            // compute the perpendicular bisector of cord bc
            var cbc = Bisector(b, c);
            // compute the intersection of the bisectors (circle radii)
            var    hcc = new HCoordinate(cab, cbc);
            Vertex cc  = null;

            try
            {
                cc = new Vertex(hcc.GetX(), hcc.GetY());
            }
            catch (NotRepresentableException nre)
            {
#if !PCL
                Debug.WriteLine("a: " + a + "  b: " + b + "  c: " + c);
                Debug.WriteLine(nre);
#endif
                //throw;
            }
            return(cc);
        }
Пример #2
0
 /// <summary> 
 /// Computes the (approximate) intersection point between two line segments
 /// using homogeneous coordinates.
 /// Note that this algorithm is
 /// not numerically stable; i.e. it can produce intersection points which
 /// lie outside the envelope of the line segments themselves.  In order
 /// to increase the precision of the calculation input points should be normalized
 /// before passing them to this routine.
 /// </summary>
 /// <param name="p1"></param>
 /// <param name="p2"></param>
 /// <param name="q1"></param>
 /// <param name="q2"></param>
 /// <returns></returns>
 public static ICoordinate Intersection(ICoordinate p1, ICoordinate p2, ICoordinate q1, ICoordinate q2)            
 {
     HCoordinate l1 = new HCoordinate(new HCoordinate(p1), new HCoordinate(p2));
     HCoordinate l2 = new HCoordinate(new HCoordinate(q1), new HCoordinate(q2));
     HCoordinate intHCoord = new HCoordinate(l1, l2);
     ICoordinate intPt = intHCoord.Coordinate;
     return intPt;
 }
Пример #3
0
 ///<summary>
 /// Computes the line which is the perpendicular bisector of the
 ///</summary>
 /// <param name="a">A point</param>
 /// <param name="b">Another point</param>
 /// <returns>The perpendicular bisector, as an HCoordinate line segment a-b.</returns>
 public static HCoordinate PerpendicularBisector(Coordinate a, Coordinate b)
 {
     // returns the perpendicular bisector of the line segment ab
     double dx = b.X - a.X;
     double dy = b.Y - a.Y;
     HCoordinate l1 = new HCoordinate(a.X + dx / 2.0, a.Y + dy / 2.0, 1.0);
     HCoordinate l2 = new HCoordinate(a.X - dy + dx / 2.0, a.Y + dx + dy / 2.0, 1.0);
     return new HCoordinate(l1, l2);
 }
Пример #4
0
        ///<summary>
        /// Computes the line which is the perpendicular bisector of the
        ///</summary>
        /// <param name="a">A point</param>
        /// <param name="b">Another point</param>
        /// <returns>The perpendicular bisector, as an HCoordinate line segment a-b.</returns>
        public static HCoordinate PerpendicularBisector(Coordinate a, Coordinate b)
        {
            // returns the perpendicular bisector of the line segment ab
            double      dx = b.X - a.X;
            double      dy = b.Y - a.Y;
            HCoordinate l1 = new HCoordinate(a.X + dx / 2.0, a.Y + dy / 2.0, 1.0);
            HCoordinate l2 = new HCoordinate(a.X - dy + dx / 2.0, a.Y + dx + dy / 2.0, 1.0);

            return(new HCoordinate(l1, l2));
        }
Пример #5
0
 /// <summary>
 /// Computes the intersection point of the lines defined by two segments, if there is one.
 /// </summary>
 /// <remarks>
 /// There may be 0, 1 or an infinite number of intersection points between two lines.
 /// If there is a unique intersection point, it is returned.
 /// Otherwise, <c>null</c> is returned.
 /// If more information is required about the details of the intersection,
 /// the <see cref="RobustLineIntersector"/> class should be used.
 /// </remarks>
 /// <param name="line">A line segment defining a straight line</param>
 /// <returns>An intersection point, or <c>null</c> if there is none or an infinite number</returns>
 /// <seealso cref="RobustLineIntersector"/>
 public Coordinate LineIntersection(LineSegment line)
 {
     try
     {
         var intPt = HCoordinate.Intersection(_p0, _p1, line._p0, line._p1);
         return(intPt);
     }
     catch (NotRepresentableException ex)
     {
         // eat this exception, and return null;
     }
     return(null);
 }
Пример #6
0
        /// <summary>
        /// Adds a mitre join connecting the two reflex offset segments.
        /// The mitre will be beveled if it exceeds the mitre ratio limit.
        /// </summary>
        /// <param name="p"></param>
        /// <param name="offset0">The first offset segment</param>
        /// <param name="offset1">The second offset segment</param>
        /// <param name="distance">The offset distance</param>
        private void AddMitreJoin(Coordinate p,
                                  LineSegment offset0,
                                  LineSegment offset1,
                                  double distance)
        {
            bool       isMitreWithinLimit = true;
            Coordinate intPt;

            /**
             * This computation is unstable if the offset segments are nearly collinear.
             * However, this situation should have been eliminated earlier by the check for
             * whether the offset segment endpoints are almost coincident
             */
            try
            {
                intPt = HCoordinate.Intersection(offset0.P0,
                                                 offset0.P1, offset1.P0, offset1.P1);

                double mitreRatio = distance <= 0.0 ? 1.0
                    : intPt.Distance(p) / Math.Abs(distance);

                if (mitreRatio > _bufParams.MitreLimit)
                {
                    isMitreWithinLimit = false;
                }
            }
            catch (NotRepresentableException ex)
            {
                intPt = new Coordinate(0, 0);
                isMitreWithinLimit = false;
            }

            if (isMitreWithinLimit)
            {
                _segList.AddPt(intPt);
            }
            else
            {
                AddLimitedMitreJoin(offset0, offset1, distance, _bufParams.MitreLimit);
                //      addBevelJoin(offset0, offset1);
            }
        }
Пример #7
0
            /// <summary>
            /// Calculate the intermediate coordinate
            /// </summary>
            private void CalculateIntermediate()
            {
                double angle = Base.Angle + MathSE.HalfPI;

                try
                {
                    // Interaction calculation using cross products
                    var a  = Base.Start;
                    var b  = Base.End;
                    var c  = Coordinate.NewAtDistanceAngleFrom(End, 50, angle);
                    var d  = Coordinate.NewAtDistanceAngleFrom(End, 50, angle + Math.PI);
                    var l1 = new HCoordinate(a).HCross(new HCoordinate(b));
                    var l2 = new HCoordinate(c).HCross(new HCoordinate(d));
                    Intermediate = new Coordinate(l1.HCross(l2));
                }
                catch
                {
                    // Backstop in case of not being able to calculate the intersection point
                    Intermediate = Start;
                }
            }
Пример #8
0
        ///<summary>Computes the circumcentre of a triangle.</summary>
        /// <remarks>
        /// The circumcentre is the centre of the circumcircle,
        /// the smallest circle which encloses the triangle.
        /// It is also the common intersection point of the
        /// perpendicular bisectors of the sides of the triangle,
        /// and is the only point which has equal distance to all three
        /// vertices of the triangle.
        /// </remarks>
        /// <param name="a">A vertex of the triangle</param>
        /// <param name="b">A vertex of the triangle</param>
        /// <param name="c">A vertex of the triangle</param>
        /// <returns>The circumcentre of the triangle</returns>
        public static Coordinate Circumcentre(Coordinate a, Coordinate b, Coordinate c)
        {
            // compute the perpendicular bisector of chord ab
            HCoordinate cab = PerpendicularBisector(a, b);
            // compute the perpendicular bisector of chord bc
            HCoordinate cbc = PerpendicularBisector(b, c);
            // compute the intersection of the bisectors (circle radii)
            HCoordinate hcc = new HCoordinate(cab, cbc);
            Coordinate  cc;

            try
            {
                cc = new Coordinate(hcc.GetX(), hcc.GetY());
            }
            catch (NotRepresentableException ex)
            {
                // MD - not sure what we can do to prevent this (robustness problem)
                // Idea - can we condition which edges we choose?
                throw new InvalidOperationException(ex.Message);
            }
            return(cc);
        }
Пример #9
0
        /// <summary>
        /// Computes the centre of the circumcircle of this vertex and two others.
        /// </summary>
        /// <param name="b" />
        /// <param name="c" />
        /// <returns>the Coordinate which is the circumcircle of the 3 points.</returns>
        public Vertex CircleCenter(Vertex b, Vertex c)
        {
            Vertex a = new Vertex(this.X, this.Y);
            // compute the perpendicular bisector of cord ab
            HCoordinate cab = Bisector(a, b);
            // compute the perpendicular bisector of cord bc
            HCoordinate cbc = Bisector(b, c);
            // compute the intersection of the bisectors (circle radii)
            HCoordinate hcc = new HCoordinate(cab, cbc);
            Vertex      cc  = null;

            try
            {
                cc = new Vertex(hcc.GetX(), hcc.GetY());
            }
            catch (NotRepresentableException nre)
            {
                System.Console.WriteLine("a: " + a + "  b: " + b + "  c: " + c);
                System.Console.WriteLine(nre);
            }
            return(cc);
        }
Пример #10
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="p1"></param>
 /// <param name="p2"></param>
 public HCoordinate(HCoordinate p1, HCoordinate p2) 
 {
     x = p1.y * p2.w - p2.y * p1.w;
     y = p2.x * p1.w - p1.x * p2.w;
     w = p1.x * p2.y - p2.x * p1.y;
 }
Пример #11
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="p1"></param>
 /// <param name="p2"></param>
 public HCoordinate(HCoordinate p1, HCoordinate p2)
 {
     _x = p1._y * p2._w - p2._y * p1._w;
     _y = p2._x * p1._w - p1._x * p2._w;
     _w = p1._x * p2._y - p2._x * p1._y;
 }
Пример #12
0
 ///<summary>Computes the circumcentre of a triangle.</summary>
 /// <remarks>
 /// The circumcentre is the centre of the circumcircle, 
 /// the smallest circle which encloses the triangle.
 /// It is also the common intersection point of the
 /// perpendicular bisectors of the sides of the triangle,
 /// and is the only point which has equal distance to all three
 /// vertices of the triangle.
 /// </remarks>
 /// <param name="a">A vertex of the triangle</param>
 /// <param name="b">A vertex of the triangle</param>
 /// <param name="c">A vertex of the triangle</param>
 /// <returns>The circumcentre of the triangle</returns>
 public static Coordinate Circumcentre(Coordinate a, Coordinate b, Coordinate c)
 {
     // compute the perpendicular bisector of chord ab
     HCoordinate cab = PerpendicularBisector(a, b);
     // compute the perpendicular bisector of chord bc
     HCoordinate cbc = PerpendicularBisector(b, c);
     // compute the intersection of the bisectors (circle radii)
     HCoordinate hcc = new HCoordinate(cab, cbc);
     Coordinate cc;
     try
     {
         cc = new Coordinate(hcc.GetX(), hcc.GetY());
     }
     catch (NotRepresentableException ex)
     {
         // MD - not sure what we can do to prevent this (robustness problem)
         // Idea - can we condition which edges we choose?
         throw new InvalidOperationException(ex.Message);
     }
     return cc;
 }