33 #ifdef OGDF_INCLUDE_CGAL
40 # include <CGAL/Aff_transformation_2.h>
41 # include <CGAL/Cartesian.h>
42 # include <CGAL/Vector_2.h>
43 # include <CGAL/aff_transformation_tags.h>
50 using namespace tools;
52 template<
typename kernel>
53 using Vector_t = CGAL::Vector_2<kernel>;
55 template<
typename kernel>
56 inline bool is_the_same(
const Vector_t<kernel>& v1,
const Vector_t<kernel>& v2) {
57 return v1.x() == v2.x() && v1.y() == v2.y();
60 template<
typename kernel>
61 inline Vector_t<kernel> rotate(
const Vector_t<kernel>& v,
const double angle) {
62 CGAL::Aff_transformation_2<kernel> rotation(CGAL::ROTATION, std::sin(angle), std::cos(angle));
66 template<
typename kernel>
67 inline typename kernel::FT dot(
const Vector_t<kernel>& v1,
const Vector_t<kernel>& v2) {
71 template<
typename kernel>
72 inline typename kernel::FT cross(
const Vector_t<kernel>& v1,
const Vector_t<kernel>& v2) {
73 return CGAL::determinant(v1, v2);
76 template<
typename kernel>
77 inline bool turn(
const Vector_t<kernel>& v1,
const Vector_t<kernel>& v2) {
78 return cross(v1, v2) >= 0;
81 template<
typename kernel>
82 inline bool left_turn(
const Vector_t<kernel>& v1,
const Vector_t<kernel>& v2) {
86 template<
typename kernel>
87 inline bool right_turn(
const Vector_t<kernel>& v1,
const Vector_t<kernel>& v2) {
91 template<
typename kernel>
92 inline bool parallel(
const Vector_t<kernel>& v1,
const Vector_t<kernel>& v2) {
96 template<
typename kernel>
97 inline Vector_t<kernel> normalize(
const Vector_t<kernel>& v) {
99 return v * CGAL::inverse(tools::approx_sqrt(v.squared_length()));
102 template<
typename kernel>
103 inline Vector_t<kernel> normal(
const Vector_t<kernel>& v) {
104 return v.perpendicular(CGAL::POSITIVE);
107 template<
typename kernel>
108 inline Vector_t<kernel> bisect(
const Vector_t<kernel> v1,
const Vector_t<kernel>& v2) {
109 if ((-v1).direction() == v2.direction()) {
110 return normalize(normal(v1));
112 return (normalize(v1) + normalize(v2)) * 0.5;
115 template<
typename kernel>
116 inline typename kernel::FT cos_angle(
const Vector_t<kernel>& v1,
const Vector_t<kernel>& v2) {
117 OGDF_ASSERT(!isZero(v1.squared_length()) && !isZero(v2.squared_length()));
118 typename kernel::FT v = v1 * v2;
119 return v * CGAL::inverse(tools::approx_sqrt(v1.squared_length() * v2.squared_length()));
122 template<
typename kernel>
123 inline typename kernel::FT angle(
const Vector_t<kernel>& v1,
const Vector_t<kernel>& v2) {
124 return tools::acos(cos_angle(v1, v2));
128 template<
typename kernel>
129 inline typename kernel::FT full_angle(
const Vector_t<kernel>& v1,
const Vector_t<kernel>& v2) {
130 using type =
typename kernel::FT;
131 const type alpha = geometry::angle(v1, v2);
132 const bool left = left_turn(v1, v2);
133 return (
type)left * alpha + (
type)(1.0 - left) * ((
type)2.0 * tools::const_pi<type>() - alpha);
136 template<
typename kernel>
137 inline bool is_valid(
const Vector_t<kernel>& v) {
138 return !
isinf(v.x()) && !
isinf(v.y()) && !isnan(v.x()) && !isnan(v.y());
141 template<
typename kernel>
142 void serialize(
const Vector_t<kernel>& v, std::ostream& os) {
143 os.write(
reinterpret_cast<const char*
>(&v.x()),
sizeof(v.x()));
144 os.write(
reinterpret_cast<const char*
>(&v.y()),
sizeof(v.y()));
147 template<
typename kernel>
148 void deserialize(Vector_t<kernel>& v, std::istream& in) {
149 in.read(
reinterpret_cast<char*
>(&v.x()),
sizeof(v.x()));
150 in.read(
reinterpret_cast<char*
>(&v.y()),
sizeof(v.y()));
153 template<
typename Vector>
154 struct VectorExactLess {
155 bool operator()(
const Vector& a,
const Vector& b)
const {
156 return a.x() < b.x() || (a.x() == b.x() && a.y() < b.y());