00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <vector>
00026 #include <map>
00027
00028 #include "WGeometryFunctions.h"
00029
00030 void tesselateIcosahedron( std::vector< WVector3d >* vertices, std::vector< unsigned int >* triangles, unsigned int level )
00031 {
00032 WAssert( vertices, "Missing input vector." );
00033 WAssert( triangles, "Missing input vector." );
00034 vertices->clear();
00035 triangles->clear();
00036
00037 unsigned int nv = 12;
00038 unsigned int nt = 20;
00039 for( unsigned int t = 1; t <= level; ++t )
00040 {
00041 nv += 3 * nt / 2;
00042 nt *= 4;
00043 }
00044 vertices->reserve( nv );
00045 triangles->reserve( nt );
00046
00047
00048 double phi = 0.5 * ( 1.0 + sqrt( 5.0 ) );
00049
00050 std::vector< WVector3d > g;
00051
00052 vertices->push_back( WVector3d( phi, 1, 0 ) );
00053 vertices->push_back( WVector3d( -phi, 1, 0 ) );
00054 vertices->push_back( WVector3d( phi, -1, 0 ) );
00055 vertices->push_back( WVector3d( -phi, -1, 0 ) );
00056
00057 vertices->push_back( WVector3d( 1, 0, phi ) );
00058 vertices->push_back( WVector3d( -1, 0, phi ) );
00059 vertices->push_back( WVector3d( 1, 0, -phi ) );
00060 vertices->push_back( WVector3d( -1, 0, -phi ) );
00061
00062 vertices->push_back( WVector3d( 0, phi, 1 ) );
00063 vertices->push_back( WVector3d( 0, -phi, 1 ) );
00064 vertices->push_back( WVector3d( 0, phi, -1 ) );
00065 vertices->push_back( WVector3d( 0, -phi, -1 ) );
00066
00067 for( std::vector< WVector3d >::iterator it = vertices->begin(); it != vertices->end(); ++it )
00068 {
00069 *it = normalize( *it );
00070 }
00071
00072
00073 unsigned int inc[ 60 ] =
00074 {
00075 8, 5, 4,
00076 8, 4, 0,
00077 8, 0, 10,
00078 8, 10, 1,
00079 8, 1, 5,
00080 5, 9, 4,
00081 4, 2, 0,
00082 0, 6, 10,
00083 10, 7, 1,
00084 1, 3, 5,
00085 4, 9, 2,
00086 0, 2, 6,
00087 10, 6, 7,
00088 1, 7, 3,
00089 5, 3, 9,
00090 9, 11, 2,
00091 2, 11, 6,
00092 6, 11, 7,
00093 7, 11, 3,
00094 3, 11, 9
00095 };
00096 triangles->assign( inc, inc + 60 );
00097
00098 std::map< utility::Edge, unsigned int > edgeVertices;
00099
00100 for( unsigned int t = 0; t < level; ++t )
00101 {
00102
00103 std::size_t numTriangles = triangles->size() / 3;
00104 for( std::size_t k = 0; k < numTriangles; ++k )
00105 {
00106 unsigned int idx[ 3 ];
00107
00108
00109 for( int i = 0; i < 3; ++i )
00110 {
00111 utility::Edge e( ( *triangles )[ 3 * k + i ], ( *triangles )[ 3 * k + ( i + 1 ) % 3 ] );
00112 if( edgeVertices.find( e ) == edgeVertices.end() )
00113 {
00114 WVector3d v0 = vertices->at( e.first );
00115 WVector3d v1 = vertices->at( e.second );
00116 WVector3d v = v0 + v1;
00117 v = normalize( v );
00118 vertices->push_back( v );
00119 edgeVertices[ e ] = vertices->size() - 1;
00120 }
00121 idx[ i ] = edgeVertices[ e ];
00122 }
00123
00124
00125
00126 triangles->push_back( ( *triangles )[ 3 * k + 0 ] );
00127 triangles->push_back( idx[ 0 ] );
00128 triangles->push_back( idx[ 2 ] );
00129
00130
00131 triangles->push_back( ( *triangles )[ 3 * k + 1 ] );
00132 triangles->push_back( idx[ 1 ] );
00133 triangles->push_back( idx[ 0 ] );
00134
00135
00136 triangles->push_back( ( *triangles )[ 3 * k + 2 ] );
00137 triangles->push_back( idx[ 2 ] );
00138 triangles->push_back( idx[ 1 ] );
00139
00140
00141 ( *triangles )[ 3 * k + 0 ] = idx[ 0 ];
00142 ( *triangles )[ 3 * k + 1 ] = idx[ 1 ];
00143 ( *triangles )[ 3 * k + 2 ] = idx[ 2 ];
00144 }
00145 edgeVertices.clear();
00146 }
00147 }