OpenWalnut  1.5.0dev
WGeometryFunctions.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <vector>
26 #include <map>
27 
28 #include "WGeometryFunctions.h"
29 
30 void tesselateIcosahedron( std::vector< WVector3d >* vertices, std::vector< unsigned int >* triangles, unsigned int level )
31 {
32  WAssert( vertices, "Missing input vector." );
33  WAssert( triangles, "Missing input vector." );
34  vertices->clear();
35  triangles->clear();
36 
37  unsigned int nv = 12;
38  unsigned int nt = 20;
39  for( unsigned int t = 1; t <= level; ++t )
40  {
41  nv += 3 * nt / 2;
42  nt *= 4;
43  }
44  vertices->reserve( nv );
45  triangles->reserve( nt );
46 
47  // add icosahedron vertices
48  double phi = 0.5 * ( 1.0 + sqrt( 5.0 ) );
49 
50  std::vector< WVector3d > g;
51 
52  vertices->push_back( WVector3d( phi, 1, 0 ) ); // 0
53  vertices->push_back( WVector3d( -phi, 1, 0 ) ); // 1
54  vertices->push_back( WVector3d( phi, -1, 0 ) ); // 2
55  vertices->push_back( WVector3d( -phi, -1, 0 ) ); // 3
56 
57  vertices->push_back( WVector3d( 1, 0, phi ) ); // 4
58  vertices->push_back( WVector3d( -1, 0, phi ) ); // 5
59  vertices->push_back( WVector3d( 1, 0, -phi ) ); // 6
60  vertices->push_back( WVector3d( -1, 0, -phi ) ); // 7
61 
62  vertices->push_back( WVector3d( 0, phi, 1 ) ); // 8
63  vertices->push_back( WVector3d( 0, -phi, 1 ) ); // 9
64  vertices->push_back( WVector3d( 0, phi, -1 ) ); // 10
65  vertices->push_back( WVector3d( 0, -phi, -1 ) ); // 11
66 
67  for( std::vector< WVector3d >::iterator it = vertices->begin(); it != vertices->end(); ++it )
68  {
69  *it = normalize( *it );
70  }
71 
72  // add triangle indices
73  unsigned int inc[ 60 ] =
74  {
75  8, 5, 4,
76  8, 4, 0,
77  8, 0, 10,
78  8, 10, 1,
79  8, 1, 5,
80  5, 9, 4,
81  4, 2, 0,
82  0, 6, 10,
83  10, 7, 1,
84  1, 3, 5,
85  4, 9, 2,
86  0, 2, 6,
87  10, 6, 7,
88  1, 7, 3,
89  5, 3, 9,
90  9, 11, 2,
91  2, 11, 6,
92  6, 11, 7,
93  7, 11, 3,
94  3, 11, 9
95  };
96  triangles->assign( inc, inc + 60 );
97 
98  std::map< utility::Edge, unsigned int > edgeVertices;
99 
100  for( unsigned int t = 0; t < level; ++t )
101  {
102  // for every triangle
103  std::size_t numTriangles = triangles->size() / 3;
104  for( std::size_t k = 0; k < numTriangles; ++k )
105  {
106  unsigned int idx[ 3 ];
107  // generate a new vertex for every edge (if there is no vertex yet)
108 
109  for( int i = 0; i < 3; ++i )
110  {
111  utility::Edge e( ( *triangles )[ 3 * k + i ], ( *triangles )[ 3 * k + ( i + 1 ) % 3 ] );
112  if( edgeVertices.find( e ) == edgeVertices.end() )
113  {
114  WVector3d v0 = vertices->at( e.first );
115  WVector3d v1 = vertices->at( e.second );
116  WVector3d v = v0 + v1;
117  v = normalize( v );
118  vertices->push_back( v );
119  edgeVertices[ e ] = vertices->size() - 1;
120  }
121  idx[ i ] = edgeVertices[ e ];
122  }
123 
124  // make 4 triangles from the current one
125  // add 1st triangle
126  triangles->push_back( ( *triangles )[ 3 * k + 0 ] );
127  triangles->push_back( idx[ 0 ] );
128  triangles->push_back( idx[ 2 ] );
129 
130  // add 2nd triangle
131  triangles->push_back( ( *triangles )[ 3 * k + 1 ] );
132  triangles->push_back( idx[ 1 ] );
133  triangles->push_back( idx[ 0 ] );
134 
135  // add 3rd triangle
136  triangles->push_back( ( *triangles )[ 3 * k + 2 ] );
137  triangles->push_back( idx[ 2 ] );
138  triangles->push_back( idx[ 1 ] );
139 
140  // changed indices of this triangle to the indices of the 4th triangle
141  ( *triangles )[ 3 * k + 0 ] = idx[ 0 ];
142  ( *triangles )[ 3 * k + 1 ] = idx[ 1 ];
143  ( *triangles )[ 3 * k + 2 ] = idx[ 2 ];
144  }
145  edgeVertices.clear();
146  }
147 }
ValueT & at(size_t row, size_t col)
Returns a reference to the component of an row and column in order to provide access to the component...
A helper class that is used to store edges as pairs of vertex indices.