72 const S unitX = 1 / std::sqrt(1 + phi * phi);
73 const S unitZ = unitX * phi;
75 const S x = radius * unitX;
76 const S z = radius * unitZ;
78 std::vector<Vector3> vertices = {{{-x, 0, z},
91 static std::vector<Triangle> triangles
92 = {{{0, 4, 1}, {0, 9, 4}, {9, 5, 4}, {4, 5, 8}, {4, 8, 1},
93 {8, 10, 1}, {8, 3, 10}, {5, 3, 8}, {5, 2, 3}, {2, 7, 3},
94 {7, 10, 3}, {7, 6, 10}, {7, 11, 6}, {11, 0, 6}, {0, 1, 6},
95 {6, 1, 10}, {9, 0, 11}, {9, 11, 2}, {9, 2, 5}, {7, 2, 11}}};
97 return std::make_pair(vertices, triangles);
134 std::tie(this->mVertices, this->mTriangles) = computeIcosahedron(mRadius);
137 if (mSubdivisions == 0)
141 using IndexMap = std::map<std::pair<std::size_t, std::size_t>, std::size_t>;
142 IndexMap midVertexIndices;
145 std::vector<Triangle> tmpFaces;
146 if (mSubdivisions % 2)
148 this->mTriangles.reserve(getNumTriangles(mSubdivisions - 1));
149 tmpFaces.reserve(getNumTriangles(mSubdivisions));
153 this->mTriangles.reserve(getNumTriangles(mSubdivisions));
154 tmpFaces.reserve(getNumTriangles(mSubdivisions - 1));
158 std::vector<Triangle>* currFaces = &(this->mTriangles);
159 std::vector<Triangle>* newFaces = &tmpFaces;
160 std::array<std::size_t, 3> mid;
164 for (std::size_t i = 0; i < mSubdivisions; ++i)
170 midVertexIndices.clear();
174 for (std::size_t j = 0; j < (*currFaces).size(); ++j)
176 const auto& outter = (*currFaces)[j];
179 for (std::size_t k = 0; k < 3; ++k)
181 auto indexA = outter[k];
182 auto indexB = outter[(k + 1) % 3];
187 std::swap(indexA, indexB);
190 const auto result = midVertexIndices.insert(
191 {{indexA, indexB}, this->mVertices.size()});
192 const auto& inserted =
result.second;
197 const auto& v1 = this->mVertices[indexA];
198 const auto& v2 = this->mVertices[indexB];
199 this->mVertices.emplace_back(mRadius * (v1 + v2).normalized());
202 mid[k] =
result.first->second;
206 (*newFaces).emplace_back(
Triangle(outter[0], mid[0], mid[2]));
207 (*newFaces).emplace_back(
Triangle(mid[0], outter[1], mid[1]));
208 (*newFaces).emplace_back(
Triangle(mid[0], mid[1], mid[2]));
209 (*newFaces).emplace_back(
Triangle(mid[2], mid[1], outter[2]));
213 std::swap(currFaces, newFaces);
217 this->mTriangles = *currFaces;
static std::size_t getNumVertices(std::size_t subdivisions)
Returns the number of vertices of icosphere given subdivisions.
Definition Icosphere-impl.hpp:44
static std::size_t getNumEdges(std::size_t subdivisions)
Returns the number of edges of icosphere given subdivisions.
Definition Icosphere-impl.hpp:54
static std::pair< Vertices, Triangles > computeIcosahedron(S radius)
Returns vertices and faces of icosahedron given radius.
Definition Icosphere-impl.hpp:69
Icosphere(S radius, std::size_t subdivisions)
Construct an icosphere given radius and subdivisions.
Definition Icosphere-impl.hpp:102
static std::size_t getNumTriangles(std::size_t subdivisions)
Returns the number of triangles of icosphere given subdivisions.
Definition Icosphere-impl.hpp:61