#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
struct Vertex {
float x, y, z; // Position
float nx, ny, nz; // Normal
};
void generateCone(float radius, float height, int slices) {
std::ofstream file("cone.ply");
// 文件头,PLY格式
file << "ply\n";
file << "format ascii 1.0\n";
file << "element vertex " << slices + 2 << "\n"; // 顶点数(底面 + 顶点)
file << "property float x\n";
file << "property float y\n";
file << "property float z\n";
file << "property float nx\n";
file << "property float ny\n";
file << "property float nz\n";
file << "element face " << slices << "\n"; // 每个切片一个面
file << "property list uchar int vertex_indices\n";
file << "end_header\n";
// 顶点数据:圆锥的顶点和底面
Vertex topVertex = { 0.0f, 0.0f, height, 0.0f, 0.0f, 1.0f }; // 圆锥顶点
file << topVertex.x << " " << topVertex.y << " " << topVertex.z << " "
<< topVertex.nx << " " << topVertex.ny << " " << topVertex.nz << "\n";
// 使用 vector 替代底面圆的顶点
std::vector<Vertex> bottomVertices(slices);
for (int i = 0; i < slices; ++i) {
float angle = 2 * M_PI * i / slices; // 每个切片的角度
float x = radius * cos(angle);
float y = radius * sin(angle);
float z = 0.0f; // 底面在z=0处
// 法向量(对于底面法向量是垂直的,指向负z轴)
float nx = 0.0f, ny = 0.0f, nz = -1.0f;
bottomVertices[i] = { x, y, z, nx, ny, nz };
file << bottomVertices[i].x << " " << bottomVertices[i].y << " " << bottomVertices[i].z << " "
<< bottomVertices[i].nx << " " << bottomVertices[i].ny << " " << bottomVertices[i].nz << "\n";
}
// 面数据:每个面由一个顶点和两个底面顶点构成
for (int i = 0; i < slices; ++i) {
int next = (i + 1) % slices; // 防止越界,最后一个顶点与第一个顶点相连
file << "3 " // 一个面有3个顶点
<< 0 << " " // 顶点索引(圆锥顶点的索引是0)
<< i + 1 << " " // 底面顶点的索引
<< next + 1 << "\n"; // 下一个底面顶点的索引
}
file.close();
std::cout << "Cone model saved to cone.ply\n";
}
int main() {
generateCone(1.0f, 4.0f, 36); // 半径1,高4,切片数36
return 0;
}