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

OpenSCAD中带Z轴余弦平滑圆角的菱形孔建模求助

问题

需要在板材上按阵列钻菱形孔,已通过polyround实现XY轴的圆角处理,效果良好。现希望为该菱形孔添加Z轴方向的平滑C形圆角,计划采用余弦曲线实现过渡。尝试过以下方法但都存在问题:

  • 使用hull()函数无法适配凹面形态
  • 带缩放的linear_extrude只能实现线性过渡,达不到平滑效果
    目前通过多切片模拟目标形态,但渲染效率极低,无法适配大批量建模场景,求高效建模方案。

相关代码:

include <polyround.scad>

//precision of the rounding
n_diamond_spline = 25;

module diamond_zround( iw, ih, it, inr_rounding_factor )
{
    aan_points =
    ([
        [0, -ih/2, iw/inr_rounding_factor],
        [+iw/2, 0, ih/inr_rounding_factor],
        [0, +ih/2, iw/inr_rounding_factor],
        [-iw/2, 0, ih/inr_rounding_factor],
    ]);

    n_min_scale = 0.25;
    n_max_scale = 1.0;
    
    n_slices = 16;

    //hull()
        for (n_cnt_slice = [0 : n_slices-1])
        {
            //Smoothly decrease size
            n_scale = (n_max_scale-n_min_scale)*(0.5+cos(n_cnt_slice/n_slices*180)/2) +n_min_scale;
            
            translate([0,0,n_cnt_slice*it/2/n_slices])
            linear_extrude(0.01)
            scale([n_scale,n_scale])
            polygon(polyRound(aan_points,n_diamond_spline));
        }
    
        translate([0,0,it]) 
        rotate([180,0,00])
        for (n_cnt_slice = [0 : n_slices-1])
        {
            //Smoothly decrease size
            n_scale = (n_max_scale-n_min_scale)*(0.5+cos(n_cnt_slice/n_slices*180)/2) +n_min_scale;
            
            translate([0,0,n_cnt_slice*it/2/n_slices])
            linear_extrude(0.01)
            scale([n_scale,n_scale])
            polygon(polyRound(aan_points,n_diamond_spline));
        }


    /*
    linear_extrude(it/2,scale=0.9)
    polygon(polyRound(aan_points,n_diamond_spline));
    */
    
    
    /*
    translate([0,0,it]) 
    rotate([180,0,00])
    linear_extrude(it/2,scale=0.9)
    polygon(polyRound(aan_points,n_diamond_spline));
    */
}

diamond_zround(30, 20, 10, 10);
高效建模方案

核心思路是通过polyhedron直接构建平滑曲面模型,避免多切片的重复计算,同时用余弦曲线驱动Z轴方向的缩放过渡,完美适配凹面形态且保证渲染效率。

优化代码

include <polyround.scad>

n_diamond_spline = 25;

module diamond_zround(iw, ih, it, inr_rounding_factor, n_steps = 8) {
    // 生成XY平面的圆角菱形基础顶点
    base_points = polyRound([
        [0, -ih/2],
        [iw/2, 0],
        [0, ih/2],
        [-iw/2, 0]
    ], n_diamond_spline);
    
    n_min_scale = 0.25;
    n_max_scale = 1.0;
    half_thickness = it / 2;
    
    // 生成上下两部分的顶点数据
    bottom_verts = [];
    top_verts = [];
    for (z_step = [0:n_steps]) {
        z = z_step * half_thickness / n_steps;
        // 余弦曲线计算缩放比例:从1到min_scale平滑过渡
        t = z_step / n_steps;
        scale_factor = (n_max_scale - n_min_scale) * (0.5 + cos(t * 180) / 2) + n_min_scale;
        
        // 生成当前Z层的缩放后顶点
        scaled_points = [for (p = base_points) [p[0]*scale_factor, p[1]*scale_factor, z]];
        bottom_verts = concat(bottom_verts, scaled_points);
        
        // 生成对称的顶部Z层顶点
        mirrored_z = it - z;
        mirrored_scaled = [for (p = base_points) [p[0]*scale_factor, p[1]*scale_factor, mirrored_z]];
        top_verts = concat(top_verts, mirrored_scaled);
    }
    
    // 合并所有顶点
    all_verts = concat(bottom_verts, top_verts);
    num_base_points = len(base_points);
    offset = (n_steps + 1) * num_base_points;
    
    // 生成侧面的三角面索引
    faces = [];
    // 底部到中间的侧面
    for (i = 0:n_steps-1) {
        for (j = 0:num_base_points-1) {
            idx1 = i*num_base_points + j;
            idx2 = i*num_base_points + (j+1)%num_base_points;
            idx3 = (i+1)*num_base_points + (j+1)%num_base_points;
            idx4 = (i+1)*num_base_points + j;
            faces = concat(faces, [[idx1, idx2, idx3], [idx1, idx3, idx4]]);
        }
    }
    // 中间到顶部的侧面
    for (i = 0:n_steps-1) {
        for (j = 0:num_base_points-1) {
            idx1 = offset + i*num_base_points + j;
            idx2 = offset + i*num_base_points + (j+1)%num_base_points;
            idx3 = offset + (i+1)*num_base_points + (j+1)%num_base_points;
            idx4 = offset + (i+1)*num_base_points + j;
            faces = concat(faces, [[idx1, idx2, idx3], [idx1, idx3, idx4]]);
        }
    }
    
    // 生成顶部和底部的封闭面(可选)
    bottom_face = [for (j = 0:num_base_points-1) j];
    top_face = [for (j = 0:num_base_points-1) offset + n_steps*num_base_points + j];
    faces = concat(faces, [bottom_face, top_face]);
    
    // 构建多面体模型
    polyhedron(all_verts, faces);
}

// 调用示例
diamond_zround(30, 20, 10, 10, n_steps=8);

方案优势

  1. 效率提升:通过polyhedron一次性构建模型,避免大量小切片的重复计算,渲染速度提升数倍,适配大批量阵列场景。
  2. 平滑过渡:用余弦曲线精准控制每个Z层的缩放比例,保证过渡的自然平滑,n_steps参数可平衡精度与效率(8-16步即可满足视觉需求)。
  3. 凹面适配:直接基于顶点构建曲面,完美贴合菱形的凹面形态,不会出现hull()的变形问题。

额外优化建议

  • 阵列时先构建单个孔模型,再通过for循环复制,避免重复计算顶点数据。
  • 若不需要封闭顶部/底部,可删除对应面的生成代码,进一步提升效率。

内容的提问来源于stack exchange,提问作者05032 Mendicant Bias

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 15:05:15