跳转到内容

OpenSCAD 教程/第 8 章

来自维基教科书,开放世界中的开放书籍

从 2D 对象旋转挤出 3D 对象

[编辑 | 编辑源代码]

到目前为止,您一直在创建许多模型并定制您的汽车设计,同时发展了扎实的参数化建模技能,并探索了 OpenSCAD 的不同功能。考虑到您创建的每个模型都只使用了三个基本体:球体、立方体和圆柱体,这真是令人印象深刻。通过将这些基本体与变换命令组合起来,您可以创建大量模型,但仍然有一些模型无法仅通过使用这些基本体来创建。以下轮毂设计就是一个这样的例子。

上面的轮毂设计需要创建一个看起来像甜甜圈的物体。

这个甜甜圈形状的物体无法使用球体、立方体和圆柱体基本体创建。相反,它需要使用 2D 基本体和一个新的命令,该命令可以从 2D 轮廓创建 3D 形状。具体来说,甜甜圈可以通过首先使用圆形基本体定义一个圆形 2D 轮廓,然后使用 rotate_extrude 命令旋转挤出这个轮廓来创建。

代码

circular_profile.scad

$fa = 1;
$fs = 0.4;
wheel_radius = 12;
tyre_diameter = 6;
translate([wheel_radius - tyre_diameter/2, 0])
    circle(d=tyre_diameter);

代码

extruded_donut.scad

$fa = 1;
$fs = 0.4;
wheel_radius = 12;
tyre_diameter = 6;
rotate_extrude(angle=360) {
    translate([wheel_radius - tyre_diameter/2, 0])
        circle(d=tyre_diameter);
}

您应该注意您创建的 2D 轮廓的一些事项。在这种情况下,2D 轮廓是使用圆形命令创建的,直径设置为等于 tyre_diameter 变量。之所以这样做是因为甜甜圈形状的物体将对应于车轮的轮胎。稍后,您可能会发现其他 2D 基本体,如正方形命令。

您计划挤出的任何 2D 轮廓都应该在 X-Y 平面上创建,通常是在 X 为正的区域内。在数学上定义,2D 轮廓通常位于 X ≥ 0 和 Z = 0 的地方。此外,2D 轮廓始终没有厚度。这意味着 2D 轮廓永远不会直接用作模型的一部分,而是与 rotate_extrude 和 linear_extrude 命令结合使用来定义 3D 对象。

您也应该注意 rotate_extrude 命令的使用的一些事项。rotate extrude 命令用于创建 3D 对象,并且始终需要一个 2D 轮廓作为输入。创建所需 2D 轮廓的命令需要放在跟随 rotate_extrude 命令的一对花括号内。通过 rotate_extrude 命令创建的 3D 对象是围绕 Y 轴旋转 2D 轮廓的结果。然后将生成的 3D 对象放置在其旋转轴位于 Z 轴上的地方。这种怪癖最初可能需要一些时间才能适应,因此逐一查看该过程可能会有所帮助。

首先,rotate_extrude 命令接受 2D 轮廓作为输入。

然后它创建一个 3D 对象,它是围绕 Y 轴旋转提供的 2D 轮廓的结果。

最后,它像围绕 X 轴旋转 90 度一样放置 3D 模型。结果是,模型旋转的 Y 轴向上旋转以与 Z 轴对齐。

rotate_extrude 命令有一个名为 angle 的输入参数。angle 参数用于定义 2D 轮廓围绕 Y 轴旋转多少度。在这种情况下,angle 参数设置为 360 度,对应于一个完整的圆圈。

将 angle 参数设置为 60 度将创建以下模型。

而将其设置为 270 度将创建以下模型。等等。

练习
通过定义缺失的圆柱体对象来完成新的轮毂设计。圆柱体的高度应等于 wheel_width 变量的值,而圆柱体的半径应等于 wheel_radius - tyre_diameter/2。圆柱体应以原点为中心。
代码

rounded_wheel_horizontal.scad

$fa = 1;
$fs = 0.4;
wheel_radius = 12;
wheel_width = 4;
tyre_diameter = 6;
rotate_extrude(angle=360) {
    translate([wheel_radius-tyre_diameter/2,0])
        circle(d=tyre_diameter);
}
cylinder(h=wheel_width, r=wheel_radius - tyre_diameter/2, center=true);

练习
为了使这个轮毂与前几章的模型兼容,请围绕 X 轴将其旋转 90 度。将此轮毂设计变成名为 rounded_simple_wheel 的模块,并在您的 vehicle_parts.scad 脚本中添加它,以备后用。
代码
…
module rounded_simple_wheel(wheel_radius=12, wheel_width=4, tyre_diameter=6) {
    rotate([90,0,0]) {
        rotate_extrude(angle=360) {
            translate([wheel_radius-tyre_diameter/2,0])
                circle(d=tyre_diameter);
        }
        cylinder(h=wheel_width, r=wheel_radius - tyre_diameter/2, center=true);
    }
}
…

练习
上面的轮毂是一个轴对称物体,这意味着它围绕一个轴表现出对称性。具体来说,对称轴是围绕它旋转 2D 轮廓以形成 3D 对象的轴。当一个物体是轴对称的时,只要提供适当的 2D 轮廓,它就可以使用一个 rotate_extrude 命令创建。对于上面的轮毂设计并非如此,因为中心部分是使用与旋转挤出分离的圆柱体命令添加的。从上面的模块中删除圆柱体命令,并在提供的 2D 轮廓中添加适当的修改,以便整个轮毂由 rotate_extrude 命令创建。

代码
…
translate([wheel_radius-tyre_diameter/2,0])
    circle(d=tyre_diameter);
translate([0,-wheel_width/2])
    square([wheel_radius-tyre_diameter/2,wheel_width]);
…

代码
…
module rounded_simple_wheel(wheel_radius=12, wheel_width=4, tyre_diameter=6) {
    rotate([90,0,0]) {
        rotate_extrude(angle=360) {
            translate([wheel_radius-tyre_diameter/2,0])
                circle(d=tyre_diameter);
            translate([0,-wheel_width/2])
                square([wheel_radius-tyre_diameter/2,wheel_width]);
        }
    }
}
…

您应该记住,轴对称物体可以通过 rotate_extrude 命令完全创建。之前的轮毂设计就是这方面的具体例子。无论您是通过提供整个物体的 2D 轮廓并使用单个 rotate_extrude 命令来创建轴对称物体,还是仅针对无法以任何其他方式创建的部分使用 rotate_extrude 命令,都取决于每种情况,由您决定。例如,如果您想要进一步模块化您的轮毂设计并将它们分成可组合的轮胎和轮辋模块,您将不可避免地需要使用 rotate_extrude 命令创建甜甜圈形状的轮胎。由于在这种情况下,轮毂的轮辋将是一个单独的模块,并且没有现有的 rotate_extrude 命令,因此使用圆柱体命令创建它是最简单也是最直接的方法。

现在是将您新学到的知识付诸实践,为小型机器人汽车项目创建轮辋的时候了。

练习
扩展 rounded_simple_wheel 模块,使轮毂设计在其轮毂上有一个孔,可以用来将其安装在轴上。为此,您需要使用 difference 命令从现有模型中减去一个圆柱体。孔的直径应等于一个名为 axle_diameter 的新模块输入参数。此参数的默认值应为 3 个单位。通过定义圆柱体高度的方式,您应该确保圆柱体始终比轮毂的宽度略长,以避免使用 difference 命令时出现任何错误。保存修改后的模块后,您应该使用它来创建一个轮毂版本,其 wheel_radius、wheel_width、tire_diameter 和 axle_diameter 分别为 20、6、4 和 5 个单位。

代码

robot_wheel.scad

…
module rounded_simple_wheel(wheel_radius=12, wheel_width=4, tyre_diameter=6, axle_diameter=3) {
    difference() {
        
        // wheel
        rotate([90,0,0]) {
            rotate_extrude(angle=360) {
                translate([wheel_radius-tyre_diameter/2,0])
                    circle(d=tyre_diameter);
                translate([0,-wheel_width/2])
                    square([wheel_radius-tyre_diameter/2,wheel_width]);
            }
        }
        
        // axle hole
        rotate([90,0,0])
            cylinder(h=wheel_width+1,r=axle_diameter/2,center=true);
    }
}
…
代码
…
rounded_simple_wheel(wheel_radius=20, wheel_width=6, tyre_diameter=4, axle_diameter=5);
…

这个轮毂设计对于小型机器人汽车应用来说看起来很合适,但您可以做一些事情来增加机器人的牵引力。与其 3D 打印整个轮毂,不如只 3D 打印轮辋,然后添加一个 O 型圈或橡皮筋作为轮胎以获得更大的牵引力。最终的轮毂将看起来像下面的图像,其中 O 型圈或橡皮筋由蓝色表示。

在这种情况下,您必须 3D 打印的相应轮辋如下所示。

练习
以 rounded_simple_wheel 模块为指导,创建一个名为 robot_rim 的新模块。robot_rim 模块应具有与 rounded_simple_wheel 模块相同的输入参数。在 robot_rim 模块中添加所有必要的命令,以便它创建上面的轮辋设计。您可以通过两种方式做到这一点。
  • 第一种方法是从对应于轮辋的正方形中减去对应于轮胎的圆形,在 rotate_extrude 命令内定义设计的 2D 轮廓,然后从生成的 3D 对象中减去轴的圆柱体,以获得最终的轮辋设计。
  • 第二种方法是从对应于轮辋的较大圆柱体中减去一个对应于轮胎的甜甜圈形状的物体和一个对应于轴孔的圆柱体。
请记住,虽然围绕良好的设计实践有一些传统智慧,但没有客观上正确或错误的选择。在实践中,您很可能会选择第一个想到的选择或对您最有意义的选择。为了完成本练习,请尝试两种方法,看看您最喜欢哪种方法。
  • 第一种方法
代码

robot_rim_from_profile_difference.scad

…
module rounded_simple_wheel(wheel_radius=12, wheel_width=4, tyre_diameter=6, axle_diameter=3) {
    rotate([90,0,0])difference() {
        
        // resulting rim
        rotate_extrude(angle=360) {
            difference() {
                
                // cylindrical rim profile
                translate([0,-wheel_width/2])
                    square([wheel_radius-tyre_diameter/2,wheel_width]);
                
                // tire profile
                translate([wheel_radius-tyre_diameter/2,0])
                    circle(d=tyre_diameter);
            }
        }
        
        // axle hole
        cylinder(h=wheel_width+1,r=axle_diameter/2,center=true);
    }
}
…

  • 第二种方法
代码

robot_rim_from_3d_object_difference.scad

…
module rounded_simple_wheel(wheel_radius=12, wheel_width=4, tyre_diameter=6, axle_diameter=3) {
    rotate([90,0,0])
        difference() {
        
            // cylindrical rim
            cylinder(h=wheel_width,r=wheel_radius-tyre_diameter/2,center=true);
        
            // tire
            rotate_extrude(angle=360) {
                translate([wheel_radius-tyre_diameter/2,0])
                    circle(d=tyre_diameter);
            }

            // axle hole
            cylinder(h=wheel_width+1,r=axle_diameter/2,center=true);
        }
}
…

通常,在设计新零件时考虑用于创建对象的制造过程会有所帮助。通常,这种考虑会促进适合当前制造方法的设计,但它也可以指导您的建模过程。

例如,考虑这样一种情况:您没有使用 3D 打印等增材制造来制造这个机器人轮毂,而是使用了车床或铣床等减材制造。在这种情况下,您可能会选择第二种方法,因为它更接近地复制了当前的制造过程,并且可以更好地估计最终的制造过程可能需要多少步骤。

从 2D 对象线性挤出 3D 对象

[编辑 | 编辑源代码]

如前所述,OpenSCAD 还有另一个命令可以用来从提供的 2D 轮廓创建 3D 对象。这个命令是 linear_extrude。与 rotate_extrude 命令相比,linear_extrude 通过沿着 Z 轴扩展位于 XY 平面上的 2D 轮廓来创建 3D 对象。与 rotate_extrude 命令类似,当您想要创建的 3D 对象无法通过组合可用的 3D 基本体直接创建时,可以使用 linear_extrude。以下是一个例子。

代码

extruded_ellipse.scad

$fa = 1;
$fs = 0.4;
linear_extrude(height=50)
    scale([2,1,1])
    circle(d=10);

上面的对象是一个管子,它具有以下轮廓。

代码

ellipse_profile.scad

$fa = 1;
$fs = 0.4;
scale([2,1,1])
    circle(d=10);

关于 linear_extrude 的使用,您需要注意一些要点。linear_extrude 的语法类似于 rotate_extrude 命令的语法。创建将沿 Z 轴挤出的 2D 轮廓的命令需要放在紧随 linear_extrude 命令之后的一对花括号内。height 参数用于定义 2D 轮廓将沿 Z 轴挤出多少个单位。默认情况下,2D 轮廓沿着 Z 轴的正方向挤出,挤出的单位数量等于分配给 height 参数的值。

通过传递一个名为 center 的额外参数,并将其设置为 true,2D 轮廓将沿着 Z 轴的两个方向挤出。生成的物体的总长度仍然等于 height 参数。

代码

centered_extrusion.scad

…
linear_extrude(height=50,center=true)
    scale([2,1,1])
    circle(d=10);
…

还可以使用一个名为 twist 的额外参数,以指定角度围绕 Z 轴扭曲生成的 3D 对象。

代码

extrusion_with_twist.scad

…
linear_extrude(height=50,center=true,twist=120)
    scale([2,1,1])
    circle(d=10);
…

最后,还可以使用另一个名为 scale 的参数,以指定的缩放因子缩放生成的 3D 对象的一端。

代码

extrusion_with_twist_and_scale.scad

…
linear_extrude(height=50,center=true,twist=120,scale=1.5)
    scale([2,1,1])
    circle(d=10);
…

现在应该很清楚,rotate_extrude 和 linear_extrude 命令如何让您能够创建无法通过直接组合可用 3D 基本体创建的对象。您可以使用这些命令来创建更抽象和艺术的设计,但让我们看看如何使用 linear_extrude 命令来创建一个新的车身。

练习
使用与上面示例类似的 linear_extrude 命令来创建以下车身。您应该创建一个名为 extruded_car_body 的新模块。该模块应该具有 length、rear_height、rear_width 和 scaling_factor 输入参数。这些参数的默认值分别为 80、20、25 和 0.5 个单位。模块的 length 和 scaling_factor 参数将用于调用 linear_extrude 命令,以设置其 height 和 scale 参数的值。提供的 2D 轮廓应该是一个圆形,根据 rear_height 和 rear_width 参数调整大小。

代码

extruded_car_body.scad

module rounded_car_body(length=80, rear_height=20, rear_width=25, scaling_factor=0.5) {
rotate([0,-90,0])
    linear_extrude(height=length,center=true,scale=scaling_factor)
    resize([rear_height,rear_width])
    circle(d=rear_height);    
}
练习
通过添加一个名为 rounded 的布尔输入参数来扩展前面的模块。该参数的默认值为 false。如果将 rounded 参数设置为 true,则应在车身的前后创建两个额外的物体,以使车身变得圆滑,如下面的图像所示。这两个物体是球体,已经调整大小和缩放。尝试找出一种合适的方式来调整球体的尺寸和缩放比例,以达到与下面的图像类似的效果。

代码

rounded_extruded_car_body.scad

…
module rounded_car_body(length=80, rear_height=20, rear_width=25, scaling_factor=0.5, rounded=false) {
    
    // center part
    rotate([0,-90,0])
        linear_extrude(height=length,center=true,scale=scaling_factor)
        resize([rear_height,rear_width])
        circle(d=rear_height);
    
    if (rounded) {
        // rear part
        translate([length/2,0,0])
            resize([rear_height,rear_width,rear_height])
            sphere(d=rear_height);
        
        // front part
        translate([-length/2,0,0])
            scale(scaling_factor)
            resize([rear_height,rear_width,rear_height])
            sphere(d=rear_height);
    }    
}
…
练习
将新的圆形车身用于您喜欢的任何汽车设计。

如前所述,rotate_extrude 和 linear_extrude 命令也可以用来创建更抽象的物体。当提供的 2D 轮廓使用可用的圆形和方形 2D 基本体创建,并且当 linear_extrude 命令的 twist 和 scale 参数没有使用时,生成的 3D 对象也可以直接使用可用的 3D 基本体创建。这些命令真正强大的地方在于能够创建任何不是圆形和方形组合的 2D 轮廓,而是任意形状。这种能力可以通过使用 polygon 2D 基本体来实现,您将在下一章学习这种基本体。

华夏公益教科书