You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++中为三角基元构成的曲面添加波浪效果?

生菜叶片曲面添加波浪效果问题

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

弯曲曲面视图1
弯曲曲面视图2

相关代码

#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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 10:30:45