Main Page | Modules | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

geometry.hpp

Go to the documentation of this file.
00001 #ifndef _GEOMETRY_HPP
00002 #define _GEOMETRY_HPP
00003 
00004 #include <algorithm>
00005 #include "global.hpp"
00006 
00007 /* A crucial decision when implementing algorithms that perform
00008  * geometric reasoning is what type of numeric representation to use.
00009  * Standard floating point has errors that often lead to
00010  * inconsistencies and bugs.  The CGAL library offers many choices,
00011  * but the crucial decisions seem to be whether the following are
00012  * supported:
00013  *
00014  *   - exact constructions (e.g., construct a point on this line)
00015  *   - exact predicates (e.g., is this point on that line?)
00016  * 
00017  * The code base has been written so that most portions rely on
00018  * neither of these.  Thus, we can use floating point representations
00019  * without (evident) problems.  The notable exceptions are
00020  *
00021  *   - sanity checking code makes extensive use of exact predicates, 
00022  *     and some isolated sanity checking code uses requires 
00023  *     constructions
00024  *   - using a triangulation to check for edge crossings
00025  *     (coloring.cpp) requires exact predicates
00026  *
00027  * Exact constructions may be used for debugging purposes, but they
00028  * lead to very slow programs.  By default, we use neither.  If an
00029  * inexplicable bug arises, the first action should be to turn on
00030  * exact geometric predicates.
00031  */
00032 
00033 // #define EXACT_GEOM_PRED // Use exact predicates (~20% slower)
00034 // #define EXACT_GEOM_CXN  // Use exact constructions (very slow)
00035 
00036 /*
00037  * This file serves as an interface to the CGAL geometry library.
00038  */
00039 
00040 #include <CGAL/basic.h>
00041 #include <CGAL/Cartesian.h>
00042 #include <CGAL/Simple_cartesian.h>
00043 #include <CGAL/Gmpq.h>
00044 #include <CGAL/Homogeneous.h>
00045 #include <CGAL/Simple_homogeneous.h>
00046 #include <CGAL/Filtered_kernel.h>
00047 #include <CGAL/Iso_rectangle_2_Segment_2_intersection.h>
00048 #include <CGAL/Segment_2_Segment_2_intersection.h>
00049 #include <CGAL/Triangle_2.h>
00050 #include <CGAL/Polygon_2.h>
00051 #include <CGAL/Bbox_2.h>
00052 
00053 namespace Arak {
00054   namespace Geometry {
00055 
00056     // This is a rational number represented by two arbitrary size
00057     // integers.  Computations are exact, but extremely slow.
00058     typedef CGAL::Cartesian<CGAL::Gmpq>          ExactCxnKernel;
00059 
00060     // The kernel below is inexact in its predicates and
00061     // constructions.
00062     typedef CGAL::Simple_cartesian<double>       InexactKernel;
00063 
00064     // This is a wrapper around a double representation that guarantees
00065     // exact predicates, but not exact constructions.  Exact predicates
00066     // are used in many parts of the code.
00067     typedef CGAL::Filtered_kernel<InexactKernel> ExactPredKernel;
00068 
00069 #ifdef EXACT_GEOM_CXN
00070     #define EXACT_GEOM_PRED
00071     typedef ExactCxnKernel                       Kernel;
00072 #elif defined(EXACT_GEOM_PRED)
00073     typedef ExactPredKernel                      Kernel;
00074 #else
00075     typedef InexactKernel                        Kernel;
00076 #endif
00077     typedef Kernel::Point_2                      Point;
00078     typedef Kernel::Line_2                       Line;
00079     typedef Kernel::Segment_2                    Segment;
00080     typedef Kernel::Direction_2                  Direction;
00081     typedef Kernel::Vector_2                     Vector;
00082     typedef Kernel::Ray_2                        Ray;
00083     typedef Kernel::Iso_rectangle_2              Rectangle;
00084     typedef Kernel::Triangle_2                   Triangle;
00085     typedef CGAL::Polygon_2<Kernel>                    Polygon;
00086 
00091     inline bool crosses(const Segment& s, const Point& a, const Point& b) {
00092       if ((s.source() == a) xor (s.target() == b)) 
00093   return false;
00094       else if ((s.source() == b) xor (s.target() == a)) 
00095   return false;
00096       else {
00097   // First do a quick bounding box check?
00098   Segment r(a, b);
00099   return CGAL::do_intersect(s, r);
00100       }
00101     }
00102 
00107     inline Rectangle boundingRectangle(const Point& u, 
00108                const Point& v, 
00109                const Point& w) {
00110       const Kernel::FT& xmin = 
00111   std::min(std::min(u.x(), v.x()), w.x());
00112       const Kernel::FT& xmax = 
00113   std::max(std::max(u.x(), v.x()), w.x());
00114       const Kernel::FT& ymin = 
00115   std::min(std::min(u.y(), v.y()), w.y());
00116       const Kernel::FT& ymax = 
00117   std::max(std::max(u.y(), v.y()), w.y());
00118       return Rectangle(xmin, ymin, xmax, ymax);
00119     }
00120     
00125     inline Rectangle boundingRectangle(const Point& t,
00126                const Point& u, 
00127                const Point& v, 
00128                const Point& w) {
00129       const Kernel::FT& xmin = 
00130   std::min(std::min(std::min(t.x(), u.x()), v.x()), w.x());
00131       const Kernel::FT& xmax = 
00132   std::max(std::max(std::max(t.x(), u.x()), v.x()), w.x());
00133       const Kernel::FT& ymin = 
00134   std::min(std::min(std::min(t.y(), u.y()), v.y()), w.y());
00135       const Kernel::FT& ymax = 
00136   std::max(std::max(std::max(t.y(), u.y()), v.y()), w.y());
00137       return Rectangle(xmin, ymin, xmax, ymax);
00138     }
00139 
00161     inline double logSineB(const Point& a, 
00162          const Point& b, 
00163          const Point& c) {
00164       Kernel::FT area = CGAL::abs(CGAL::area(a, b, c));
00165       Kernel::FT ab_len_sq = CGAL::squared_distance(a, b);
00166       Kernel::FT bc_len_sq = CGAL::squared_distance(b, c);
00167       return (ln(2.0 * CGAL::to_double(area))
00168         - ln(CGAL::to_double(ab_len_sq * bc_len_sq)) / 2.0);
00169     }
00170 
00180     inline Geometry::Point project(const Geometry::Point& p,
00181            const Geometry::Rectangle& r) {
00182       Geometry::Kernel::FT x = p.x();
00183       Geometry::Kernel::FT y = p.y();
00184       x = std::max<Geometry::Kernel::FT>(x, r.xmin());
00185       x = std::min<Geometry::Kernel::FT>(x, r.xmax());
00186       y = std::max<Geometry::Kernel::FT>(y, r.ymin());
00187       y = std::min<Geometry::Kernel::FT>(y, r.ymax());
00188       return Geometry::Point(x, y);
00189     }
00190     
00195     void n_gon(int n, double radius, Polygon& poly);
00196 
00197   }
00198 }
00199 
00200 #endif

Generated on Wed May 25 14:39:16 2005 for Arak by doxygen 1.3.6