71 const S unitX = 1 / std::sqrt(1 + phi * phi);
72 const S unitZ = unitX * phi;
74 const S x = radius * unitX;
75 const S z = radius * unitZ;
77 std::vector<Vector3> vertices = {{-x, 0, z},
90 static std::vector<Triangle> triangles
91 = {{0, 4, 1}, {0, 9, 4}, {9, 5, 4}, {4, 5, 8}, {4, 8, 1},
92 {8, 10, 1}, {8, 3, 10}, {5, 3, 8}, {5, 2, 3}, {2, 7, 3},
93 {7, 10, 3}, {7, 6, 10}, {7, 11, 6}, {11, 0, 6}, {0, 1, 6},
94 {6, 1, 10}, {9, 0, 11}, {9, 11, 2}, {9, 2, 5}, {7, 2, 11}};
96 return std::make_pair(vertices, triangles);
133 std::tie(this->mVertices, this->mTriangles) = computeIcosahedron(mRadius);
136 if (mSubdivisions == 0)
140 using IndexMap = std::map<std::pair<std::size_t, std::size_t>, std::size_t>;
141 IndexMap midVertexIndices;
144 std::vector<Triangle> tmpFaces;
145 if (mSubdivisions % 2)
147 this->mTriangles.reserve(getNumTriangles(mSubdivisions - 1));
148 tmpFaces.reserve(getNumTriangles(mSubdivisions));
152 this->mTriangles.reserve(getNumTriangles(mSubdivisions));
153 tmpFaces.reserve(getNumTriangles(mSubdivisions - 1));
157 std::vector<Triangle>* currFaces = &(this->mTriangles);
158 std::vector<Triangle>* newFaces = &tmpFaces;
159 std::array<std::size_t, 3> mid;
163 for (std::size_t i = 0; i < mSubdivisions; ++i)
169 midVertexIndices.clear();
173 for (std::size_t j = 0; j < (*currFaces).size(); ++j)
175 const auto& outter = (*currFaces)[j];
178 for (std::size_t k = 0; k < 3; ++k)
180 auto indexA = outter[k];
181 auto indexB = outter[(k + 1) % 3];
186 std::swap(indexA, indexB);
189 const auto result = midVertexIndices.insert(
190 {{indexA, indexB}, this->mVertices.size()});
191 const auto& inserted =
result.second;
196 const auto& v1 = this->mVertices[indexA];
197 const auto& v2 = this->mVertices[indexB];
198 this->mVertices.emplace_back(mRadius * (v1 + v2).normalized());
201 mid[k] =
result.first->second;
205 (*newFaces).emplace_back(
Triangle(outter[0], mid[0], mid[2]));
206 (*newFaces).emplace_back(
Triangle(mid[0], outter[1], mid[1]));
207 (*newFaces).emplace_back(
Triangle(mid[0], mid[1], mid[2]));
208 (*newFaces).emplace_back(
Triangle(mid[2], mid[1], outter[2]));
212 std::swap(currFaces, newFaces);
216 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:43
static std::size_t getNumEdges(std::size_t subdivisions)
Returns the number of edges of icosphere given subdivisions.
Definition Icosphere-impl.hpp:53
static std::pair< Vertices, Triangles > computeIcosahedron(S radius)
Returns vertices and faces of icosahedron given radius.
Definition Icosphere-impl.hpp:68
Icosphere(S radius, std::size_t subdivisions)
Construct an icosphere given radius and subdivisions.
Definition Icosphere-impl.hpp:101
static std::size_t getNumTriangles(std::size_t subdivisions)
Returns the number of triangles of icosphere given subdivisions.
Definition Icosphere-impl.hpp:60