00001
00002
00008 #if !defined(__geom_Simplex_h__)
00009 #define __geom_Simplex_h__
00010
00011 #if defined(DEBUG_geom) && !defined(DEBUG_Simplex)
00012 #define DEBUG_Simplex
00013 #endif
00014
00015 #include "../../defs.h"
00016
00017 #include "../../kernel/content.h"
00018 #include "../../kernel/BBox.h"
00019
00020 #include "../../../ads/array/FixedArray.h"
00021
00022 #include <cassert>
00023
00024 BEGIN_NAMESPACE_GEOM
00025
00027
00052 template<int N, typename V, typename T = double>
00053 class Simplex {
00054
00055
00056
00057
00058 public:
00059
00061 typedef V Vertex;
00062
00064 typedef T Number;
00065
00067 typedef ads::FixedArray<N+1,Vertex> VertexContainer;
00068
00070 typedef typename VertexContainer::value_type Value;
00071
00073 typedef typename VertexContainer::iterator Iterator;
00074
00076 typedef typename VertexContainer::const_iterator ConstIterator;
00077
00079 typedef typename VertexContainer::reference Reference;
00080
00082 typedef typename VertexContainer::const_reference ConstReference;
00083
00085 typedef typename VertexContainer::parameter_type Parameter;
00086
00088 typedef Simplex<N-1,V,T> Face;
00089
00090 private:
00091
00092
00093
00094
00095
00096 VertexContainer _vertices;
00097
00098 public:
00099
00100
00103
00105 Simplex() :
00106 _vertices()
00107 {}
00108
00110 Simplex(const Simplex& other) :
00111 _vertices(other._vertices)
00112 {}
00113
00115 explicit
00116 Simplex(const VertexContainer& vertices) :
00117 _vertices(vertices)
00118 {}
00119
00121 void
00122 build(const VertexContainer& vertices) {
00123 _vertices = vertices;
00124 }
00125
00127 explicit
00128 Simplex(Parameter v) :
00129 _vertices(v) {
00130 LOKI_STATIC_CHECK(N == 0, N_is_0);
00131 }
00132
00134 void
00135 build(Parameter v) {
00136 LOKI_STATIC_CHECK(N == 0, N_is_0);
00137 _vertices[0] = v;
00138 }
00139
00141 Simplex(Parameter v0, Parameter v1) :
00142 _vertices(v0, v1) {
00143 LOKI_STATIC_CHECK(N == 1, N_is_1);
00144 }
00145
00147 void
00148 build(Parameter v0, Parameter v1) {
00149 LOKI_STATIC_CHECK(N == 1, N_is_1);
00150 _vertices[0] = v0;
00151 _vertices[1] = v1;
00152 }
00153
00155 Simplex(Parameter v0, Parameter v1, Parameter v2) :
00156 _vertices(v0, v1, v2) {
00157 LOKI_STATIC_CHECK(N == 2, N_is_2);
00158 }
00159
00161 void
00162 build(Parameter v0, Parameter v1, Parameter v2) {
00163 LOKI_STATIC_CHECK(N == 2, N_is_2);
00164 _vertices[0] = v0;
00165 _vertices[1] = v1;
00166 _vertices[2] = v2;
00167 }
00168
00170 Simplex(Parameter v0, Parameter v1, Parameter v2, Parameter v3) :
00171 _vertices(v0, v1, v2, v3) {
00172 LOKI_STATIC_CHECK(N == 3, N_is_3);
00173 }
00174
00176 void
00177 build(Parameter v0, Parameter v1, Parameter v2, Parameter v3) {
00178 LOKI_STATIC_CHECK(N == 3, N_is_3);
00179 _vertices[0] = v0;
00180 _vertices[1] = v1;
00181 _vertices[2] = v2;
00182 _vertices[3] = v3;
00183 }
00184
00186 template<typename VertRAIter, typename IndSimp>
00187 Simplex(VertRAIter vertices, const IndSimp& indexed_simplex) :
00188 _vertices() {
00189 for (int n = 0; n != N + 1; ++n) {
00190 _vertices[n] = vertices[indexed_simplex[n]];
00191 }
00192 }
00193
00195 template<typename VertRAIter, typename IndSimp>
00196 void
00197 build(VertRAIter vertices, const IndSimp& indexed_simplex) {
00198 for (int n = 0; n != N + 1; ++n) {
00199 _vertices[n] = vertices[indexed_simplex[n]];
00200 }
00201 }
00202
00204 Simplex&
00205 operator=(const Simplex& other) {
00206 if (&other != this) {
00207 _vertices = other._vertices;
00208 }
00209 return *this;
00210 }
00211
00213 ~Simplex()
00214 {}
00215
00217
00220
00222 ConstIterator
00223 begin() const {
00224 return _vertices.begin();
00225 }
00226
00228 ConstIterator
00229 end() const {
00230 return _vertices.end();
00231 }
00232
00234 int
00235 size() const {
00236 return N + 1;
00237 }
00238
00240
00243
00245 const VertexContainer&
00246 getVertices() const {
00247 return _vertices;
00248 }
00249
00251 Parameter
00252 operator[](const int n) const {
00253 return _vertices[n];
00254 }
00255
00257 ConstIterator
00258 getBeginning() const {
00259 return _vertices.begin();
00260 }
00261
00263 ConstIterator
00264 getEnd() const {
00265 return _vertices.end();
00266 }
00267
00269 int
00270 getSize() const {
00271 return N + 1;
00272 }
00273
00275 template<typename Comparable>
00276 bool
00277 hasVertex(const Comparable& v) const;
00278
00280
00283 template<typename Comparable>
00284 bool
00285 hasVertex(const Comparable& v, int* n) const;
00286
00288
00292 template<int M>
00293 bool
00294 hasFace(const Simplex<M,V,T>& f) const;
00295
00297 template<typename Comparable>
00298 int
00299 getVertexIndex(const Comparable& v) const;
00300
00302
00306 Face
00307 getFace(const int n) const {
00308 Face f;
00309 getFace(n, &f);
00310 return f;
00311 }
00312
00314
00318 void
00319 getFace(const int n, Face* f) const;
00320
00322 void
00323 computeBBox(BBox<N,Number>* bb) const {
00324 bb->bound(begin(), end());
00325 }
00326
00328 void
00329 computeCentroid(Vertex* centroid) const {
00330 *centroid = Number(0);
00331 for (int n = 0; n != N+1; ++n) {
00332 *centroid += _vertices[n];
00333 }
00334 *centroid /= Number(N + 1);
00335 }
00336
00338
00341
00343 Iterator
00344 begin() {
00345 return _vertices.begin();
00346 }
00347
00349 Iterator
00350 end() {
00351 return _vertices.end();
00352 }
00353
00355
00358
00359
00360 #if 0
00362 VertexContainer&
00363 vertices() {
00364 return _vertices;
00365 }
00366 #endif
00367
00369 Reference
00370 operator[](const int n) {
00371 return _vertices[n];
00372 }
00373
00375 Iterator
00376 getBeginning() {
00377 return _vertices.begin();
00378 }
00379
00381 Iterator
00382 getEnd() {
00383 return _vertices.end();
00384 }
00385
00387 void
00388 set(const VertexContainer& vertices) {
00389 _vertices = vertices;
00390 }
00391
00393 void
00394 setEach(Parameter value) {
00395 _vertices = value;
00396 }
00397
00399 void
00400 negate() {
00401 if (N > 0) {
00402 std::swap(_vertices[0], _vertices[1]);
00403 }
00404 }
00405
00407 };
00408
00409
00410
00411
00412
00414
00420 template<int N, typename V, typename T>
00421 bool
00422 operator==(const Simplex<N,V,T>& x, const Simplex<N,V,T>& y) {
00423 return (x.getVertices() == y.getVertices());
00424 }
00425
00427
00430 template<int N, typename V, typename T>
00431 bool
00432 operator!=(const Simplex<N,V,T>& x, const Simplex<N,V,T>& y) {
00433 return !(x == y);
00434 }
00435
00437
00442 template<typename V, typename T>
00443 bool
00444 haveSameOrientation(const Simplex<0,V,T>& x, const Simplex<0,V,T>& y) {
00445 #ifdef DEBUG_geom
00446 assert(x[0] == y[0]);
00447 #endif
00448 return true;
00449 }
00450
00452
00457 template<typename V, typename T>
00458 bool
00459 haveSameOrientation(const Simplex<1,V,T>& x, const Simplex<1,V,T>& y) {
00460 #ifdef DEBUG_geom
00461 assert(x.hasVertex(y[0]) && x.hasVertex(y[1]));
00462 #endif
00463 return x[0] == y[0];
00464 }
00465
00467
00472 template<typename V, typename T>
00473 bool
00474 haveSameOrientation(const Simplex<2,V,T>& x, const Simplex<2,V,T>& y) {
00475 #ifdef DEBUG_geom
00476 assert(x.hasVertex(y[0]) && x.hasVertex(y[1]) && x.hasVertex(y[2]));
00477 #endif
00478 if (x[0] == y[0]) {
00479 return x[1] == y[1];
00480 }
00481 else if (x[0] == y[1]) {
00482 return x[1] == y[2];
00483 }
00484
00485 return x[1] == y[0];
00486 }
00487
00488
00489
00490
00491
00492
00494
00497 template<int N, typename V, typename T>
00498 inline
00499 std::ostream&
00500 operator<<(std::ostream& out, const Simplex<N,V,T>& x) {
00501 return out << x.getVertices();
00502 }
00503
00505
00508 template<int N, typename V, typename T>
00509 inline
00510 std::istream&
00511 operator>>(std::istream& in, Simplex<N,V,T>& x) {
00512 for (int n = 0; n != N + 1; ++n) {
00513 in >> x[n];
00514 }
00515 return in;
00516 }
00517
00518 END_NAMESPACE_GEOM
00519
00520 #define __geom_Simplex_ipp__
00521 #include "Simplex.ipp"
00522 #undef __geom_Simplex_ipp__
00523
00524 #endif