mirror of https://github.com/CGAL/cgal
131 lines
5.9 KiB
TeX
131 lines
5.9 KiB
TeX
\section{Predicates and Constructions}
|
|
|
|
\subsection{Predicates}
|
|
Predicates are at the heart of a geometry kernel. They are basic units
|
|
for the composition of geometric algorithms and encapsulate decisions.
|
|
Hence their correctness is crucial for the control flow and hence for
|
|
the correctness of an implementation of a geometric algorithm. \cgal\ uses
|
|
the term predicate in a generalized sense. Not only components returning a
|
|
Boolean value are called predicates but also components returning an
|
|
enumeration type like a \ccc{Comparison_result} or an \ccc{Orientation}.
|
|
We say components, because predicates are implemented both as functions and
|
|
function objects (provided by a kernel class).
|
|
|
|
\cgal\ provides predicates for the \ccHtmlNoLinksFrom{orientation} of point
|
|
sets (\ccc{orientation}, \ccc{leftturn}, \ccc{rightturn}, \ccc{collinear},
|
|
\ccc{coplanar}), for comparing points according to some given order,
|
|
especially for comparing \ccHtmlNoLinksFrom{Cartesian} coordinates
|
|
(e.g.~\ccc{lexicographically_xy_smaller}), in-circle and in-sphere tests,
|
|
and predicates to compare distances.
|
|
|
|
\subsection{Constructions}
|
|
Functions and function objects that generate objects that are neither
|
|
of type \ccc{bool} nor enum types are called constructions.
|
|
Constructions involve computation of new numerical values and may be
|
|
imprecise due to rounding errors unless a kernel with an exact number type is
|
|
used.
|
|
|
|
Affine transformations (\ccc{Aff_transformation_2<Kernel>},
|
|
\ccc{Aff_transformation_3<Kernel>}) allow to generate new object instances under
|
|
arbitrary affine transformations. These transformations include translations,
|
|
rotations (in 2D only) and scaling. Most of the geometric objects in a
|
|
kernel have a member function \ccc{transform(Aff_transformation t)}
|
|
which applies the transformation to the object instance.
|
|
|
|
{\cgal} also provides a set of functions that detect or compute the
|
|
\ccHtmlNoLinksFrom{intersection}\ccIndexMainItem{intersection}
|
|
between objects of the 2D kernel, and many objects in the 3D kernel,
|
|
and functions to calculate their
|
|
squared distance\ccIndexMainItem{distance}\ccIndexSubitem{distance}{squared}.
|
|
Moreover, some member functions of kernel objects are constructions.
|
|
|
|
So there are routines that compute the square of the Euclidean distance, but no
|
|
routines that compute the distance itself. Why?
|
|
First of all, the two values can be derived from each other quite easily (by
|
|
taking the square root or taking the square). So, supplying only the one and
|
|
not the other is only a minor inconvenience for the user.
|
|
Second, often either value can be used. This is for example the case when
|
|
(squared) distances are compared.
|
|
Third, the library wants to stimulate the use of the squared distance instead
|
|
of the distance. The squared distance can be computed in more cases and the
|
|
computation is cheaper.
|
|
We do this by not providing the perhaps more natural routine,
|
|
The problem of a distance routine is that it needs the \ccStyle{sqrt}
|
|
operation.
|
|
This has two drawbacks:
|
|
\begin{itemize}
|
|
\item
|
|
The \ccStyle{sqrt} operation can be costly. Even if it is not very costly for
|
|
a specific number type and platform, avoiding it is always cheaper.
|
|
\item
|
|
There are number types on which no \ccStyle{sqrt} operation is defined,
|
|
especially integer types and rationals.
|
|
\end{itemize}
|
|
|
|
\subsection{Intersections and variant return types}
|
|
Some functions can return different types of objects. To achieve this
|
|
in a type safe way {\cgal} uses return values of type
|
|
\ccStyle{boost::optional< boost::variant< T \ldots\ > >} were T... is a
|
|
list of all possible resulting geometric objects. The exact result
|
|
type of an intersection can be determined through the metafunction
|
|
\ccc{cpp11::result_of<Kernel::Intersect_2(Type1, Type2)>} or
|
|
\ccc{cpp11::result_of<Kernel::Intersect_3(Type1, Type2)>}, where
|
|
\ccc{Type1} and \ccc{Type2} are the types of the objects used in the
|
|
intersection computation. See
|
|
\ccAnchor{http://www.boost.org/libs/utility/utility.htm#result_of}{boost::result\_of}
|
|
for more information about this mechanism.
|
|
|
|
\ccExample
|
|
|
|
In the following example, \ccc{result_of} is used to query the return
|
|
value for the \ccHtmlNoLinksFrom{intersection} computation:
|
|
|
|
\ccHtmlLinksOff%
|
|
\begin{cprog}
|
|
typedef Cartesian<double> K;
|
|
typedef K::Point_2 Point_2;
|
|
typedef K::Segment_2 Segment_2;
|
|
|
|
Segment_2 segment_1, segment_2;
|
|
|
|
std::cin >> segment_1 >> segment_2;
|
|
|
|
/* C++11 */
|
|
auto v = intersection(segment_1, segment_2);
|
|
|
|
/* C++03 */
|
|
/*cpp11::result_of<K::Intersect_2(Segment_2, Segment_2)>::type */
|
|
/* v = intersection(segment_1, segment_2); */
|
|
if(v) {
|
|
/* not empty */
|
|
if (const Point_2 *p = boost::get<Point_2>(&*v) ) {
|
|
/* do something with *p */
|
|
} else if (const Segment_2 *s = boost::get<Segment_2>(&*v) ) {
|
|
/* do something with *s */
|
|
}
|
|
} else {
|
|
/* empty intersection */
|
|
}
|
|
\end{cprog}
|
|
\ccHtmlLinksOn%
|
|
|
|
\subsection{Constructive Predicates}
|
|
For testing where a point $p$ lies with respect to a plane defined by three
|
|
points $q$, $r$ and $s$, one may be tempted to construct the plane
|
|
\ccc{Plane_3<Kernel>(q,r,s)} and use the method \ccc{oriented_side(p)}.
|
|
This may pay off if many tests with respect to the plane are made.
|
|
Nevertheless, unless the number type is exact, the constructed plane
|
|
is only approximated, and round-off errors may lead
|
|
\ccc{oriented_side(p)} to return an \ccHtmlNoLinksFrom{orientation}
|
|
which is different from the \ccHtmlNoLinksFrom{orientation} of $p$, $q$, $r$,
|
|
and $s$.
|
|
|
|
In {\cgal}, we provide predicates in which such
|
|
geometric decisions are made directly with a reference to the input points
|
|
$p$, $q$, $r$, $s$, without an intermediary object like a plane.
|
|
For the above test, the recommended way to get the result is to use
|
|
\ccc{orientation(p,q,r,s)}. For exact number types, the situation is different.
|
|
If several tests are to be made with the same
|
|
plane, it pays off to construct the plane and to use \ccc{oriented_side(p)}.
|
|
|