1 // Copyright (c) 1999 2 // Utrecht University (The Netherlands), 3 // ETH Zurich (Switzerland), 4 // INRIA Sophia-Antipolis (France), 5 // Max-Planck-Institute Saarbruecken (Germany), 6 // and Tel-Aviv University (Israel). All rights reserved. 7 // 8 // This file is part of CGAL (www.cgal.org) 9 // 10 // $URL: https://github.com/CGAL/cgal/blob/v5.3/Kernel_23/include/CGAL/Triangle_2.h $ 11 // $Id: Triangle_2.h 4e519a3 2021-05-05T13:15:37+02:00 Sébastien Loriot 12 // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial 13 // 14 // 15 // Author(s) : Andreas Fabri 16 17 #ifndef CGAL_TRIANGLE_2_H 18 #define CGAL_TRIANGLE_2_H 19 20 #include <CGAL/assertions.h> 21 #include <boost/type_traits/is_same.hpp> 22 #include <CGAL/Kernel/Return_base_tag.h> 23 #include <CGAL/Bbox_2.h> 24 #include <CGAL/Dimension.h> 25 #include <CGAL/IO/io.h> 26 27 namespace CGAL { 28 29 template <class R_> 30 class Triangle_2 : public R_::Kernel_base::Triangle_2 31 { 32 typedef typename R_::Point_2 Point_2; 33 typedef typename R_::Aff_transformation_2 Aff_transformation_2; 34 typedef typename R_::Kernel_base::Triangle_2 RTriangle_2; 35 36 typedef Triangle_2 Self; 37 CGAL_static_assertion((boost::is_same<Self, typename R_::Triangle_2>::value)); 38 39 public: 40 41 typedef Dimension_tag<2> Ambient_dimension; 42 typedef Dimension_tag<2> Feature_dimension; 43 44 typedef RTriangle_2 Rep; 45 rep()46 const Rep& rep() const 47 { 48 return *this; 49 } 50 rep()51 Rep& rep() 52 { 53 return *this; 54 } 55 56 typedef R_ R; 57 typedef typename R::FT FT; 58 Triangle_2()59 Triangle_2() {} 60 Triangle_2(const RTriangle_2 & t)61 Triangle_2(const RTriangle_2& t) 62 : RTriangle_2(t) {} 63 Triangle_2(const Point_2 & p,const Point_2 & q,const Point_2 & r)64 Triangle_2(const Point_2 &p, const Point_2 &q, const Point_2 &r) 65 : RTriangle_2(typename R::Construct_triangle_2()(Return_base_tag(), p,q,r)) {} 66 67 FT area()68 area() const 69 { 70 return R().compute_area_2_object()(vertex(0), vertex(1), vertex(2)); 71 } 72 73 typename R::Orientation orientation()74 orientation() const 75 { 76 return R().orientation_2_object()(vertex(0), vertex(1), vertex(2)); 77 } 78 79 typename R::Bounded_side bounded_side(const Point_2 & p)80 bounded_side(const Point_2 &p) const 81 { 82 return R().bounded_side_2_object()(*this,p); 83 } 84 85 typename R::Oriented_side oriented_side(const Point_2 & p)86 oriented_side(const Point_2 &p) const 87 { 88 return R().oriented_side_2_object()(*this,p); 89 } 90 91 typename R::Boolean 92 operator==(const Triangle_2 &t) const 93 { 94 return R().equal_2_object()(*this,t); 95 } 96 97 typename R::Boolean 98 operator!=(const Triangle_2 &t) const 99 { 100 return !(*this == t); 101 } 102 103 decltype(auto) vertex(int i)104 vertex(int i) const 105 { 106 return R().construct_vertex_2_object()(*this,i); 107 } 108 decltype(auto)109 decltype(auto) 110 operator[](int i) const 111 { 112 return vertex(i); 113 } 114 115 typename R::Boolean has_on_bounded_side(const Point_2 & p)116 has_on_bounded_side(const Point_2 &p) const 117 { 118 return bounded_side(p) == ON_BOUNDED_SIDE; 119 } 120 121 typename R::Boolean has_on_unbounded_side(const Point_2 & p)122 has_on_unbounded_side(const Point_2 &p) const 123 { 124 return bounded_side(p) == ON_UNBOUNDED_SIDE; 125 } 126 127 typename R::Boolean has_on_boundary(const Point_2 & p)128 has_on_boundary(const Point_2 &p) const 129 { 130 return bounded_side(p) == ON_BOUNDARY; 131 } 132 133 typename R::Boolean has_on_negative_side(const Point_2 & p)134 has_on_negative_side(const Point_2 &p) const 135 { 136 return oriented_side(p) == ON_NEGATIVE_SIDE; 137 } 138 139 typename R::Boolean has_on_positive_side(const Point_2 & p)140 has_on_positive_side(const Point_2 &p) const 141 { 142 return oriented_side(p) == ON_POSITIVE_SIDE; 143 } 144 145 typename R::Boolean is_degenerate()146 is_degenerate() const 147 { 148 return R().collinear_2_object()(vertex(0), vertex(1), vertex(2)); 149 } 150 151 Bbox_2 bbox()152 bbox() const 153 { 154 return R().construct_bbox_2_object()(*this); 155 } 156 157 Triangle_2 opposite()158 opposite() const 159 { 160 return R().construct_opposite_triangle_2_object()(*this); 161 } 162 163 Triangle_2 transform(const Aff_transformation_2 & t)164 transform(const Aff_transformation_2 &t) const 165 { 166 return Triangle_2(t.transform(vertex(0)), 167 t.transform(vertex(1)), 168 t.transform(vertex(2))); 169 } 170 171 }; 172 173 174 template < class R > 175 std::ostream & 176 operator<<(std::ostream &os, const Triangle_2<R> &t) 177 { 178 switch(IO::get_mode(os)) { 179 case IO::ASCII : 180 return os << t[0] << ' ' << t[1] << ' ' << t[2]; 181 case IO::BINARY : 182 return os << t[0] << t[1] << t[2]; 183 default: 184 return os<< "Triangle_2(" << t[0] << ", " 185 << t[1] << ", " << t[2] <<")"; 186 } 187 } 188 189 template < class R > 190 std::istream & 191 operator>>(std::istream &is, Triangle_2<R> &t) 192 { 193 typename R::Point_2 p, q, r; 194 195 is >> p >> q >> r; 196 197 if (is) 198 t = Triangle_2<R>(p, q, r); 199 return is; 200 } 201 202 } //namespace CGAL 203 204 #endif // CGAL_TRIANGLE_2_H 205