【问题标题】:3D cube with individually rounded corners带有单独圆角的 3D 立方体
【发布时间】:2022-07-12 19:19:32
【问题描述】:

在 OpenSCAD 中获得真正的圆角 3D 立方体似乎并不容易(或可能?)。我用hull() 和球体尝试了一些东西,但没有正常工作。然后我尝试在每个平面上用圆形外壳制作一些东西,然后与所有 3 个平面相交。边缘很好,但角落不光滑。我知道每个边缘的线性挤压是问题,因为它不会遵循在另一个平面上定义的曲线。我还没有完全理解minkowski() 函数,但它看起来也不能解决问题。

那么有没有希望让它正常工作?

到目前为止,这是我的代码:

// Lengths in X, Y, Z dimension
dx = 10;
dy = 20;
dz = 5;

// Corner radius on XY plane (from origin clockwise around positive Z axis)
rxy = [1, 1, 3, 1];
// Corner radius on YZ plane (from origin clockwise around positive X axis)
ryz = [1, 1, 1, 1];
// Corner radius on XZ plane (from origin clockwise around positive Y axis)
rxz = [1, 1, 2, 1];

intersection()
{
    // XY plane
    linear_extrude(dz)
    hull()
    {
        for (ix = [0:1], iy = [0:1])
        {
            i = [0, 1, 3, 2][ix * 2 + iy];
            r = rxy[i] == 0 ? 0.0001 : rxy[i];
            x = ix == 0 ? r : dx - r;
            y = iy == 0 ? r : dy - r;
            translate([x, y, 0])
            circle(r, $fn=40);
        }
    }

    // YZ plane
    translate([0, 0, dz])
    rotate([0, 90, 0])
    linear_extrude(dx)
    hull()
    {
        for (iy = [0:1], iz = [0:1])
        {
            i = [1, 0, 2, 3][iy * 2 + iz];
            r = ryz[i] == 0 ? 0.0001 : ryz[i];
            y = iy == 0 ? r : dy - r;
            z = iz == 0 ? r : dz - r;
            intersection()
            {
                translate([z, y, 0])
                circle(r, $fn=40);

                square([dz, dy]);
            }
        }
    }

    // XZ plane
    translate([0, dy, 0])
    rotate([90, 0, 0])
    linear_extrude(dy)
    hull()
    {
        for (ix = [0:1], iz = [0:1])
        {
            i = [0, 3, 1, 2][ix * 2 + iz];
            r = rxz[i] == 0 ? 0.0001 : rxz[i];
            x = ix == 0 ? r : dx - r;
            z = iz == 0 ? r : dz - r;
            intersection()
            {
                translate([x, z, 0])
                circle(r, $fn=40);

                square([dx, dz]);
            }
        }
    }
}

角落看起来像这样:

一个应用程序是这样的形状:https://www.printables.com/model/62314-cable-clamp#preview 它到处都有轻微的圆角,并且恰好在一个边缘有一个大圆角。

【问题讨论】:

    标签: openscad


    【解决方案1】:

    有一个 OpenSCAD module 可以做到这一点。该页面还列出了指向使用 Minkowski 的simple version 的链接。这是简单版本的代码。

    // More information: https://danielupshaw.com/openscad-rounded-corners/
    
    module roundedcube_simple(size = [1, 1, 1], center = false, radius = 0.5) {
        // If single value, convert to [x, y, z] vector
        size = (size[0] == undef) ? [size, size, size] : size;
    
        translate = (center == false) ?
            [radius, radius, radius] :
            [
                radius - (size[0] / 2),
                radius - (size[1] / 2),
                radius - (size[2] / 2)
        ];
    
        translate(v = translate)
        minkowski() {
            cube(size = [
                size[0] - (radius * 2),
                size[1] - (radius * 2),
                size[2] - (radius * 2)
            ]);
            sphere(r = radius);
        }
    }
    

    radius * 2 从立方体尺寸中减去,因为 Minkowski 将半径添加到所有边。

    【讨论】:

    • 在哪里可以为每条边设置单独的半径?
    【解决方案2】:

    如果你觉得不需要重新发明轮子,你可以使用 BOSL2 之类的库:

    include <BOSL2/std.scad>
    cuboid([20, 20, 20], rounding=4, $fn=60);
    

    【讨论】:

    • 在哪里可以为每条边设置单独的半径?看起来他们在角落也使用了球体,无法达到效果。
    【解决方案3】:

    我找到了您问题的部分解决方案:您只能确定 6 个半径(顶面边缘的所有半径都相同,底面也一样)但我认为这对于示例来说已经足够了你显示了。

    代码:

    module rounded_cube(size = [4, 2, 1], face_radii = [1/8, 1/16], edges_radii = [1, 1/2, 1/4, 1/8, ], $fn = 16){
        
        module block(size = [1, 2], radii = [1/2, 1/4], $fn = 16){
            intersection(){
                union(){
                    square([size.x - radii[0], radii[0]]);
                    translate([0, size.y - radii[1]])
                    square([size.x - radii[1], radii[1]]);
                    
                    translate([0, radii[0]])
                    square([size.x, size.y - radii[0] - radii[1]]);
                
                    translate([size.x - radii[0], radii[0]])
                    circle(radii[0]);
                    translate([size.x - radii[1], size.y - radii[1]])
                    circle(radii[1]);
                }
                square([size.x, size.y]);
            }
        }
    
        //block();
        
        assert(max(face_radii) <= min(edges_radii), "all face radii must be smaller than all edges radii");
        
        assert(face_radii[0] + face_radii[1] <= size.z, "the sum of the face radii must be smaller than the height of the rounded cube");
        
        assert(
            edges_radii[0] + edges_radii[1] <= size.x &&
            edges_radii[1] + edges_radii[2] <= size.y &&
            edges_radii[2] + edges_radii[3] <= size.x &&
            edges_radii[3] + edges_radii[0] <= size.y, 
            "the sum of two consecutive edges radii must be smaller than the side they lie on");
    
        for(e = [0 : 3]){
            translate([size.x * [0, 1, 1, 0][e], size.y * [0, 0, 1, 1][e]])
            rotate([0, 0, 180 + e*90]){
                translate([-edges_radii[e], -edges_radii[e]])
                rotate_extrude(angle = 90, $fn = $fn * 4)
                block([edges_radii[e], size.z], [face_radii[0], face_radii[1]], $fn = $fn * 4);
                
                rotate([-90, 0, 90])
                translate([-size[(e + 1) % 2] / 2, -size.z, edges_radii[e]])
                linear_extrude(size[e % 2] - edges_radii[e] - edges_radii[(e + 1) % 4])
                block([size[(e + 1) % 2] / 2, size.z], [face_radii[1], face_radii[0]], $fn = $fn * 4);
            }
        }
    }
    
    rounded_cube(size = [4, 2, 1], face_radii = [1/8, 1/16], edges_radii = [1, 1/2, 1/4, 1/8], $fn = 16);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-15
      • 2012-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多