mirror of https://github.com/CGAL/cgal
263 lines
6.4 KiB
C++
263 lines
6.4 KiB
C++
// ======================================================================
|
|
//
|
|
// Copyright (c) 2000 The CGAL Consortium
|
|
//
|
|
// This software and related documentation is part of an INTERNAL release
|
|
// of the Computational Geometry Algorithms Library (CGAL). It is not
|
|
// intended for general use.
|
|
//
|
|
// ----------------------------------------------------------------------
|
|
//
|
|
// release :
|
|
// release_date :
|
|
//
|
|
// file : include/CGAL/constructions/kernel_ftC2.h
|
|
// revision : $Revision$
|
|
// revision_date : $Date$
|
|
// author(s) : Sven Schoenherr, Hervé Brönnimann, Sylvain Pion
|
|
// coordinator : INRIA Sophia-Antipolis (Mariette.Yvinec@sophia.inria.fr)
|
|
//
|
|
// ======================================================================
|
|
|
|
#ifndef CGAL_CONSTRUCTIONS_KERNEL_FTC2_H
|
|
#define CGAL_CONSTRUCTIONS_KERNEL_FTC2_H
|
|
|
|
#include <CGAL/determinant.h>
|
|
|
|
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 = CGAL_NTS square(drx) + CGAL_NTS square(dry);
|
|
FT q2 = CGAL_NTS square(dqx) + CGAL_NTS 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 ( den != FT(0) );
|
|
|
|
// 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;
|
|
// Suggested by Serge Pashkov (psw@rt.kiam.ru) for better numeric stability.
|
|
c = -px*a - py*b;
|
|
// 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 >
|
|
CGAL_KERNEL_INLINE
|
|
void
|
|
bisector_of_pointsC2(const FT &px, const FT &py,
|
|
const FT &qx, const FT &qy,
|
|
FT &a, FT &b, FT& c )
|
|
{
|
|
a = FT(2)*(px - qx);
|
|
b = FT(2)*(py - qy);
|
|
c = CGAL_NTS square(qx) + CGAL_NTS square(qy) -
|
|
CGAL_NTS square(px) - CGAL_NTS square(py);
|
|
}
|
|
|
|
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
|
|
void
|
|
perpendicular_through_pointC2(const FT &la, const FT &lb,
|
|
const FT &px, const FT &py,
|
|
FT &a, FT &b, FT &c)
|
|
{
|
|
a = -lb;
|
|
b = la;
|
|
c = lb * px - la * py;
|
|
}
|
|
|
|
template < class FT >
|
|
CGAL_KERNEL_MEDIUM_INLINE
|
|
void
|
|
line_project_pointC2(const FT &la, const FT &lb, const FT &lc,
|
|
const FT &px, const FT &py,
|
|
FT &x, FT &y)
|
|
{
|
|
#if 1
|
|
// Original old version
|
|
if (la==FT(0)) // horizontal line
|
|
{
|
|
x = px;
|
|
y = -lc/lb;
|
|
}
|
|
else if (lb==FT(0)) // vertical line
|
|
{
|
|
x = -lc/la;
|
|
y = py;
|
|
}
|
|
else
|
|
{
|
|
FT ab = la/lb, ba = lb/la, ca = lc/la;
|
|
y = ( -px + ab*py - ca ) / ( ba + ab );
|
|
x = -ba * y - ca;
|
|
}
|
|
#else
|
|
// New version, with more multiplications, but less divisions and tests.
|
|
// Let's compare the results of the 2, benchmark them, as well as check
|
|
// the precision with the intervals.
|
|
FT a2 = CGAL_NTS square(la);
|
|
FT b2 = CGAL_NTS square(lb);
|
|
FT d = a2 + b2;
|
|
x = (la * (lb * py - lc) - px * b2) / d;
|
|
y = (lb * (lc - la * px) + py * a2) / d;
|
|
#endif
|
|
}
|
|
|
|
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 = CGAL_NTS square(x) + CGAL_NTS 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 CGAL_NTS square(x) + CGAL_NTS square(y);
|
|
}
|
|
|
|
template < class FT >
|
|
CGAL_KERNEL_INLINE
|
|
FT
|
|
squared_distanceC2( const FT &px, const FT &py,
|
|
const FT &qx, const FT &qy)
|
|
{
|
|
return CGAL_NTS square(px-qx) + CGAL_NTS 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
|