예제 #1
0
        /// <summary>Calculates the orientation of the triangle formed by p-&gt;q-&gt;r.</summary>
        /// <remarks>
        /// Calculates the orientation of the triangle formed by p-&gt;q-&gt;r. Returns 1
        /// for counter-clockwise, -1 for clockwise, and 0 for collinear. May use
        /// high precision arithmetics for some special degenerate cases.
        /// </remarks>
        public static int OrientationRobust(com.epl.geometry.Point2D p, com.epl.geometry.Point2D q, com.epl.geometry.Point2D r)
        {
            com.epl.geometry.ECoordinate det_ec = new com.epl.geometry.ECoordinate();
            det_ec.Set(q.x);
            det_ec.Sub(p.x);
            com.epl.geometry.ECoordinate rp_y_ec = new com.epl.geometry.ECoordinate();
            rp_y_ec.Set(r.y);
            rp_y_ec.Sub(p.y);
            com.epl.geometry.ECoordinate qp_y_ec = new com.epl.geometry.ECoordinate();
            qp_y_ec.Set(q.y);
            qp_y_ec.Sub(p.y);
            com.epl.geometry.ECoordinate rp_x_ec = new com.epl.geometry.ECoordinate();
            rp_x_ec.Set(r.x);
            rp_x_ec.Sub(p.x);
            det_ec.Mul(rp_y_ec);
            qp_y_ec.Mul(rp_x_ec);
            det_ec.Sub(qp_y_ec);
            if (!det_ec.IsFuzzyZero())
            {
                double det_ec_value = det_ec.Value();
                if (det_ec_value < 0.0)
                {
                    return(-1);
                }
                if (det_ec_value > 0.0)
                {
                    return(1);
                }
                return(0);
            }
            // Need extended precision
            decimal det_mp = new decimal(q.x);
            decimal px_mp  = new decimal(p.x);
            decimal py_mp  = new decimal(p.y);

            det_mp = decimal.Subtract(det_mp, px_mp);
            decimal rp_y_mp = new decimal(r.y);

            rp_y_mp = decimal.Subtract(rp_y_mp, py_mp);
            decimal qp_y_mp = new decimal(q.y);

            qp_y_mp = decimal.Subtract(qp_y_mp, py_mp);
            decimal rp_x_mp = new decimal(r.x);

            rp_x_mp = decimal.Subtract(rp_x_mp, px_mp);
            det_mp  = decimal.Multiply(det_mp, rp_y_mp);
            qp_y_mp = decimal.Multiply(qp_y_mp, rp_x_mp);
            det_mp  = decimal.Subtract(det_mp, qp_y_mp);
            return(System.Math.Sign(det_mp));
        }
예제 #2
0
 // Orientation predicates
 private static com.epl.geometry.ECoordinate Determinant_(com.epl.geometry.Point2D p, com.epl.geometry.Point2D q, com.epl.geometry.Point2D r)
 {
     com.epl.geometry.ECoordinate det_ec = new com.epl.geometry.ECoordinate();
     det_ec.Set(q.x);
     det_ec.Sub(p.x);
     com.epl.geometry.ECoordinate rp_y_ec = new com.epl.geometry.ECoordinate();
     rp_y_ec.Set(r.y);
     rp_y_ec.Sub(p.y);
     com.epl.geometry.ECoordinate qp_y_ec = new com.epl.geometry.ECoordinate();
     qp_y_ec.Set(q.y);
     qp_y_ec.Sub(p.y);
     com.epl.geometry.ECoordinate rp_x_ec = new com.epl.geometry.ECoordinate();
     rp_x_ec.Set(r.x);
     rp_x_ec.Sub(p.x);
     det_ec.Mul(rp_y_ec);
     qp_y_ec.Mul(rp_x_ec);
     det_ec.Sub(qp_y_ec);
     return(det_ec);
 }
예제 #3
0
 /// <summary>Calculates if the point s is inside of the circumcircle inscribed by the clockwise oriented triangle p-q-r.</summary>
 /// <remarks>
 /// Calculates if the point s is inside of the circumcircle inscribed by the clockwise oriented triangle p-q-r.
 /// Returns 1 for outside, -1 for inside, and 0 for cocircular.
 /// Note that the convention used here differs from what is commonly found in literature, which can define the relation
 /// in terms of a counter-clockwise oriented circle, and this flips the sign (think of the signed volume of the tetrahedron).
 /// May use high precision arithmetics for some special cases.
 /// </remarks>
 internal static int InCircleRobust(com.epl.geometry.Point2D p, com.epl.geometry.Point2D q, com.epl.geometry.Point2D r, com.epl.geometry.Point2D s)
 {
     com.epl.geometry.ECoordinate psx_ec = new com.epl.geometry.ECoordinate();
     com.epl.geometry.ECoordinate psy_ec = new com.epl.geometry.ECoordinate();
     psx_ec.Set(p.x);
     psx_ec.Sub(s.x);
     psy_ec.Set(p.y);
     psy_ec.Sub(s.y);
     com.epl.geometry.ECoordinate qsx_ec = new com.epl.geometry.ECoordinate();
     com.epl.geometry.ECoordinate qsy_ec = new com.epl.geometry.ECoordinate();
     qsx_ec.Set(q.x);
     qsx_ec.Sub(s.x);
     qsy_ec.Set(q.y);
     qsy_ec.Sub(s.y);
     com.epl.geometry.ECoordinate rsx_ec = new com.epl.geometry.ECoordinate();
     com.epl.geometry.ECoordinate rsy_ec = new com.epl.geometry.ECoordinate();
     rsx_ec.Set(r.x);
     rsx_ec.Sub(s.x);
     rsy_ec.Set(r.y);
     rsy_ec.Sub(s.y);
     com.epl.geometry.ECoordinate psx_ec_qsy_ec = new com.epl.geometry.ECoordinate();
     psx_ec_qsy_ec.Set(psx_ec);
     psx_ec_qsy_ec.Mul(qsy_ec);
     com.epl.geometry.ECoordinate psy_ec_qsx_ec = new com.epl.geometry.ECoordinate();
     psy_ec_qsx_ec.Set(psy_ec);
     psy_ec_qsx_ec.Mul(qsx_ec);
     com.epl.geometry.ECoordinate qsx_ec_rsy_ec = new com.epl.geometry.ECoordinate();
     qsx_ec_rsy_ec.Set(qsx_ec);
     qsx_ec_rsy_ec.Mul(rsy_ec);
     com.epl.geometry.ECoordinate qsy_ec_rsx_ec = new com.epl.geometry.ECoordinate();
     qsy_ec_rsx_ec.Set(qsy_ec);
     qsy_ec_rsx_ec.Mul(rsx_ec);
     com.epl.geometry.ECoordinate psx_ec_rsy_ec = new com.epl.geometry.ECoordinate();
     psx_ec_rsy_ec.Set(psx_ec);
     psx_ec_rsy_ec.Mul(rsy_ec);
     com.epl.geometry.ECoordinate psy_ec_rsx_ec = new com.epl.geometry.ECoordinate();
     psy_ec_rsx_ec.Set(psy_ec);
     psy_ec_rsx_ec.Mul(rsx_ec);
     com.epl.geometry.ECoordinate pq_det_ec = new com.epl.geometry.ECoordinate();
     pq_det_ec.Set(psx_ec_qsy_ec);
     pq_det_ec.Sub(psy_ec_qsx_ec);
     com.epl.geometry.ECoordinate qr_det_ec = new com.epl.geometry.ECoordinate();
     qr_det_ec.Set(qsx_ec_rsy_ec);
     qr_det_ec.Sub(qsy_ec_rsx_ec);
     com.epl.geometry.ECoordinate pr_det_ec = new com.epl.geometry.ECoordinate();
     pr_det_ec.Set(psx_ec_rsy_ec);
     pr_det_ec.Sub(psy_ec_rsx_ec);
     com.epl.geometry.ECoordinate psx_ec_psx_ec = new com.epl.geometry.ECoordinate();
     psx_ec_psx_ec.Set(psx_ec);
     psx_ec_psx_ec.Mul(psx_ec);
     com.epl.geometry.ECoordinate psy_ec_psy_ec = new com.epl.geometry.ECoordinate();
     psy_ec_psy_ec.Set(psy_ec);
     psy_ec_psy_ec.Mul(psy_ec);
     com.epl.geometry.ECoordinate qsx_ec_qsx_ec = new com.epl.geometry.ECoordinate();
     qsx_ec_qsx_ec.Set(qsx_ec);
     qsx_ec_qsx_ec.Mul(qsx_ec);
     com.epl.geometry.ECoordinate qsy_ec_qsy_ec = new com.epl.geometry.ECoordinate();
     qsy_ec_qsy_ec.Set(qsy_ec);
     qsy_ec_qsy_ec.Mul(qsy_ec);
     com.epl.geometry.ECoordinate rsx_ec_rsx_ec = new com.epl.geometry.ECoordinate();
     rsx_ec_rsx_ec.Set(rsx_ec);
     rsx_ec_rsx_ec.Mul(rsx_ec);
     com.epl.geometry.ECoordinate rsy_ec_rsy_ec = new com.epl.geometry.ECoordinate();
     rsy_ec_rsy_ec.Set(rsy_ec);
     rsy_ec_rsy_ec.Mul(rsy_ec);
     com.epl.geometry.ECoordinate p_parab_ec = new com.epl.geometry.ECoordinate();
     p_parab_ec.Set(psx_ec_psx_ec);
     p_parab_ec.Add(psy_ec_psy_ec);
     com.epl.geometry.ECoordinate q_parab_ec = new com.epl.geometry.ECoordinate();
     q_parab_ec.Set(qsx_ec_qsx_ec);
     q_parab_ec.Add(qsy_ec_qsy_ec);
     com.epl.geometry.ECoordinate r_parab_ec = new com.epl.geometry.ECoordinate();
     r_parab_ec.Set(rsx_ec_rsx_ec);
     r_parab_ec.Add(rsy_ec_rsy_ec);
     p_parab_ec.Mul(qr_det_ec);
     q_parab_ec.Mul(pr_det_ec);
     r_parab_ec.Mul(pq_det_ec);
     com.epl.geometry.ECoordinate det_ec = new com.epl.geometry.ECoordinate();
     det_ec.Set(p_parab_ec);
     det_ec.Sub(q_parab_ec);
     det_ec.Add(r_parab_ec);
     if (!det_ec.IsFuzzyZero())
     {
         double det_ec_value = det_ec.Value();
         if (det_ec_value < 0.0)
         {
             return(-1);
         }
         if (det_ec_value > 0.0)
         {
             return(1);
         }
         return(0);
     }
     return(InCircleRobustMP_(p, q, r, s));
 }