// revision : $Revision$ // revision_date : $Date$ // author(s) : Sven Schoenherr, Hervé Brönnimann, Sylvain Pion #ifndef CGAL_CONSTRUCTIONS_KERNEL_FTC2_H #define CGAL_CONSTRUCTIONS_KERNEL_FTC2_H #include CGAL_BEGIN_NAMESPACE template < class FT > CGAL_KERNEL_INLINE void midpointC2( const FT &px, const FT &py, const FT &qx, const FT &qy, FT &x, FT &y ) { x = (px+qx) / FT(2); y = (py+qy) / FT(2); } template < class FT > CGAL_KERNEL_LARGE_INLINE void circumcenter_translateC2(const FT &dqx, const FT &dqy, const FT &drx, const FT &dry, FT &dcx, FT &dcy) { // Given 3 points P, Q, R, this function takes as input: // qx-px, qy-py, rx-px, ry-py. And returns cx-px, cy-py, // where (cx, cy) are the coordinates of the circumcenter C. // What we do is intersect the bisectors. FT r2 = square(drx) + square(dry); FT q2 = square(dqx) + square(dqy); FT den = FT(2) * det2x2_by_formula(dqx, dqy, drx, dry); // The 3 points aren't collinear. // Hopefully, this is already checked at the upper level. CGAL_kernel_assertion ( ! is_zero(den) ); // One possible optimization here is to precompute 1/den, to avoid one // division. However, we loose precision, and it's maybe not worth it (?). dcx = det2x2_by_formula (dry, dqy, r2, q2) / den; dcy = - det2x2_by_formula (drx, dqx, r2, q2) / den; } template < class FT > CGAL_KERNEL_MEDIUM_INLINE void circumcenterC2( const FT &px, const FT &py, const FT &qx, const FT &qy, const FT &rx, const FT &ry, FT &x, FT &y ) { circumcenter_translateC2(qx-px, qy-py, rx-px, ry-py, x, y); x += px; y += py; } template < class FT > inline void line_from_pointsC2(const FT &px, const FT &py, const FT &qx, const FT &qy, FT &a, FT &b, FT &c) { a = py - qy; b = qx - px; c = px*qy - py*qx; } template < class FT > inline void line_from_point_directionC2(const FT &px, const FT &py, const FT &dx, const FT &dy, FT &a, FT &b, FT &c) { a = - dy; b = dx; c = px*dy - py*dx; } template < class FT > inline FT line_y_at_xC2(const FT &a, const FT &b, const FT &c, const FT &x) { return (-a*x-c) / b; } template < class FT > inline void line_get_pointC2(const FT &a, const FT &b, const FT &c, int i, FT &x, FT &y) { if (b==FT(0)) { x = (-b-c)/a + FT(i)*b; y = FT(1) - FT(i)*a; } else { x = FT(1) + FT(i)*b; y = -(a+c)/b - FT(i)*a; } } template < class FT > inline Oriented_side side_of_oriented_lineC2(const FT &a, const FT &b, const FT &c, const FT &x, const FT &y) { return Oriented_side(CGAL::sign(a*x+b*y+c)); } template < class FT > CGAL_KERNEL_MEDIUM_INLINE FT squared_circumradiusC2(const FT &px, const FT &py, const FT &qx, const FT &qy, const FT &rx, const FT &ry, FT &x, FT &y ) { circumcenter_translateC2(qx-px, qy-py, rx-px, ry-py, x, y); FT r2 = square(x) + square(y); x += px; y += py; return r2; } template < class FT > CGAL_KERNEL_MEDIUM_INLINE FT squared_circumradiusC2(const FT &px, const FT &py, const FT &qx, const FT &qy, const FT &rx, const FT &ry) { FT x, y; circumcenter_translateC2(qx-px, qy-py, rx-px, ry-py, x, y); return square(x) + square(y); } template < class FT > CGAL_KERNEL_INLINE FT squared_distanceC2( const FT &px, const FT &py, const FT &qx, const FT &qy) { return square(px-qx) + square(py-qy); } template < class FT > CGAL_KERNEL_INLINE FT scaled_distance_to_lineC2( const FT &la, const FT &lb, const FT &lc, const FT &px, const FT &py) { // for comparisons, use distance_to_directionsC2 instead // since lc is irrelevant return la*px + lb*py + lc; } template < class FT > CGAL_KERNEL_INLINE FT scaled_distance_to_directionC2( const FT &la, const FT &lb, const FT &px, const FT &py) { // scalar product with direction return la*px + lb*py; } template < class FT > CGAL_KERNEL_MEDIUM_INLINE FT scaled_distance_to_lineC2( const FT &px, const FT &py, const FT &qx, const FT &qy, const FT &rx, const FT &ry) { return det2x2_by_formula(px-rx,py-ry,qx-rx,qy-ry); } CGAL_END_NAMESPACE #endif // CGAL_CONSTRUCTIONS_KERNEL_FTC2_H