如何在C++中为三角基元构成的曲面添加波浪效果?
生菜叶片曲面添加波浪效果问题
我得先说明:这更偏向数学问题而非编程问题。我正在开发一个生菜植物模型,涉及复杂几何结构。目前已经构建出二维曲面,现在想给它加波浪效果,但不知道怎么实现。这个曲面由三角基元构成,基元通过xyz向量定义顶点位置。我用HELIOS API开发这个程序化生菜模型,原本是用for循环和正弦函数构建曲面的。另外说下,我在几何、计算机图形学和C++方面基础都比较薄弱。


相关代码
#include "Context.h" #include "Visualizer.h" using namespace helios; using namespace std; vector<uint> addLeaf(float leaf_length, float leaf_width, float leaf_bend_x, float leaf_bend_y, float rotation_z, float rotation_x, float displacement, float radius, Context* context ) { std::vector<uint> UUIDs; // float leaf_length = 10; float Nz = 10; // params.s1_leaf_subdivisions ; number of times to split the dimension float dz = leaf_length / Nz; // length of each subdivision // float leaf_width = 10; float Ny = 10; // params.s1_leaf_subdivisions ; number of times to split the dimension float dy = leaf_width / Ny; // length of each subdivision // leaf wave // float A_3 = leaf_length * float(0.5); // Half waves on the leaf 10 // float A_2 = leaf_length * float(0.1); // amplitude 0.25 float A_3 = 1; // Half waves on the leaf 10 float A_2 = 1; // amplitude 0.25 float leaf_amplitude = leaf_length / float(10); // the 2 * dx extends the sine wave a bit beyond 1/2 wavelength so base of leaves come together for (int i = 0; i < Nz + (2 * dz); i++) { for (float j = 0; j < Ny; j++) { float z = i * dz; //for each subdivision in z define Z coord float y = j * dy; //for each subdivision in y define y coord float x = 0; // we will also need an x coord float sz = dz; // the next step in z will be equal to a subdivision in z float sy = dy; // the next step in y will be equal to a subdivision in y float z_i = z * M_PI / (Nz * dz); // the second coord for z is z_i needed to define a triangle primitive float sz_i = (z + sz) * M_PI / (Nz * dz); // // this would be y_1 in sorghum model float y_i = (y * M_PI / (Ny * dy)) / (A_3); // the second coord for y is y_i needed to define a triangle primitive float sy_i = ((y + sy) * M_PI / (Ny * dy)) / (A_3); //waviness of leaf float leaf_wave_1; float leaf_wave_2; float leaf_wave_3; float leaf_wave_4; if (j == 0) { leaf_wave_1 = A_2 * sin(z_i); leaf_wave_2 = A_2 * sin(sz_i); } else { leaf_wave_1 = A_2 * sin(z_i); leaf_wave_2 = A_2 * sin(sz_i); } // Now define x based on z,y and add leaf bend in x and y x = leaf_bend_x * sin(z_i); x = ((x*radius + displacement + (leaf_bend_y * sin(y_i))) / 2) + leaf_wave_1; vec3 v0(x*radius + displacement, y, z); x = leaf_bend_x * sin(sz_i); x = ((x*radius + displacement + (leaf_bend_y * sin(y_i))) / 2) + leaf_wave_2; vec3 v1(x*radius + displacement, y, z + sz); if (j == Nz - 1) { leaf_wave_3 = sin(sz_i) * A_2; leaf_wave_4 = sin(z_i) * A_2; } else { leaf_wave_3 = sin(sz_i) * A_2; leaf_wave_4 = sin(z_i) * A_2; } x = leaf_bend_x * sin(sz_i); x = ((x*radius + displacement + (leaf_bend_y * sin(sy_i))) / 2) + leaf_wave_3 ; vec3 v2(x*radius + displacement, y + sy, z + sz); x = leaf_bend_x * sin(z_i); x = ((x*radius + displacement + (leaf_bend_y * sin(sy_i))) / 2) + leaf_wave_4 ; vec3 v3(x*radius + displacement, y + sy, z); // set of two triangles which form a rectangle or square as subunits of leaf UUIDs.push_back(context->addTriangle(v0, v1, v2, RGB::cyan)); UUIDs.push_back(context->addTriangle(v0, v2, v3, RGB::magenta)); } } return UUIDs; } // call to functions and build lettuce geometries int main( void ){ Context context; float leaf_length = 10; float leaf_width = 10; float radius = 1; // additional control leaf curvature // add leaves one by one; 'i' here is # of leaves external to whorl for (int i = 0; i < 6; i++) { if (i == 0)addLeaf(leaf_length, leaf_width, 0.5*leaf_length, 0.5*leaf_width, 4 * M_PI / 9*i, 0, i/5, radius, &context); // if (i == 1)addLeaf(leaf_length, leaf_width, 0.5*leaf_length, 0.5*leaf_width, 4 * M_PI / 9*i, -M_PI/ 20, i/5, radius, &context); // if (i == 2)addLeaf(leaf_length, leaf_width, 0.5*leaf_length, 0.5*leaf_width, 4 * M_PI / 9*i, -M_PI/ 10, i/5, radius, &context); // if (i == 3)addLeaf(leaf_length, leaf_width, 0.5*leaf_length, 0.5*leaf_width, 4 * M_PI / 9*i, -M_PI/ 9, i/5, radius, &context); // if (i == 4)addLeaf(leaf_length, leaf_width, 0.5*leaf_length, 0.5*leaf_width, 4 * M_PI / 9*i, -M_PI/ 7, i/5, radius, &context); // if (i == 5)addLeaf(leaf_length, leaf_width, 0.5*leaf_length, 0.5*leaf_width, 4 * M_PI / 9*i, -M_PI/ 5, i/5, radius, &context); } Visualizer visualizer(800); visualizer.buildContextGeometry(&context); visualizer.setLightingModel(Visualizer::LIGHTING_PHONG); visualizer.plotInteractive(); }
我试过用正弦函数加额外的for循环生成一系列值,加到三角形的X坐标上,但没得到预期效果。
内容的提问来源于stack exchange,提问作者Jonny Bliss
相关产品推荐
相关产品推荐

