The sphere primitive and resizing objects
::球原始和改变物体的大小

You showed the car to your friends and they were quite impressed with your new skills. One of them even challenged you to come up with different futuristic wheel designs. It’s time to put your creativity to work and learn more OpenSCAD features!
::你向朋友们展示了这辆车,他们对你的新技能印象深刻.其中一个甚至挑战你设计不同的未来轮胎.现在是时候发挥你的创造力,学习更多的OpenSCAD功能了!

So far you have been using the cube and cylinder primitives. Another 3D primitive that is available in OpenSCAD is the sphere. You can create a sphere using the following command.
::现在我们使用的是立方体和圆柱体的原始. 另一个在OpenSCAD中可用的3D原始是球体. 你可以使用以下命令创建一个球体.

Code

sphere.scad
::球体. 球体

sphere(r=10);

You should notice that the sphere is created centered on the origin. The input parameter r corresponds to the radius of the sphere.
::输入参数r与球的半径对应.

One idea that came to your head was to replace the cylindrical wheels with spherical ones.
::想到的其中一个想法是用球形轮子取代圆形轮子.

Exercise
Try making the wheels of your car spherical. To do so replace the appropriate cylinder commands with sphere commands. Is there still a need to rotate the wheels around the X axis? Is the wheel_width variable still required? Is there any visible change to your model when you modify the value of wheels_turn variable?
Code

car_with_spherical_wheels.scad
::车_带_球_轮.scad

$fa = 1;
$fs = 0.4;
wheel_radius = 8;
base_height = 8;
top_height = 10;
track = 40;
body_roll = 0;
wheels_turn = 20;
rotate([body_roll,0,0]) {
    // Car body base
    cube([60,20,base_height],center=true);
    // Car body top
    translate([5,0,base_height/2+top_height/2 - 0.001])
        cube([30,20,top_height],center=true);
}
// Front left wheel
translate([-20,-track/2,0])
    rotate([0,0,wheels_turn])
    sphere(r=wheel_radius);
// Front right wheel
translate([-20,track/2,0])
    rotate([0,0,wheels_turn])
    sphere(r=wheel_radius);
// Rear left wheel
translate([20,-track/2,0])
    rotate([0,0,0])
    sphere(r=wheel_radius);
// Rear right wheel
translate([20,track/2,0])
    rotate([0,0,0])
    sphere(r=wheel_radius);
// Front axle
translate([-20,0,0])
    rotate([90,0,0])
    cylinder(h=track,r=2,center=true);
// Rear axle
translate([20,0,0])
    rotate([90,0,0])
    cylinder(h=track,r=2,center=true);

The idea to use a sphere to create the wheels was nice. You can now squish the spheres to give them a more wheel like shape. One way to do so is using the scale command.
::现在可以压缩球体,让它们更像轮子. 一种方法是使用缩放命令.

Exercise
Try creating a sphere with a radius of 10 units on a blank model. Use the scale command to scale the sphere by a factor of 0.4 only along the Y axis.
Code

narrowed_spherical_wheel_using_scale.scad
::缩小_球形_轮_使用_尺度.scad

scale([1,0.4,1])
    sphere(r=10);

Another way to scale objects is by using the resize transformation. The difference between scale and resize is that when using the scale command, you have to specify the desired scaling factor along each axis but when using the resize command you have to specify the desired resulting dimensions of the object along each axis. In the previous example you started with a sphere that has a radius of 10 units (total dimension of 20 units along each axis) and scaled it by a factor of 0.4 along the Y axis. Thus, the resulting dimension of the scaled sphere along the Y axis is 8 units. The dimensions along the X and Z axis remain the same (20 units) since the scaling factors along these axes are equal to 1. You could achieve the same result using the following resize command.
::另一种方法是使用大小转换来缩放对象.大小和大小之间的区别在于,在使用大小命令时,您必须指定每个轴上的所需缩放因子,但在使用大小命令时,您必须指定每个轴上的对象的所需结果维度.在前面的例子中,您从一个半径为10个单位 (每个轴上的总维度为20个单位) 的球开始,并将其缩放为Y轴上的0.4个因子.因此,Y轴上的缩放球的结果维度为8个单位. X和Z轴上的维度保持不变 (20个单位),因为这些轴上的缩放因子等于1.您可以使用以下的大小命令实现相同的结果.

Code

narrowed_spherical_wheel_using_resize.scad
::缩小_球形_轮_使用_缩小.scad

resize([20,8,20])
    sphere(r=10);

When you are scaling/resizing an object and you are concerned about its resulting dimensions it is more convenient to use the resize command. In contrast when you are concerned more about the ratio of the resulting dimensions compared to the starting dimensions it is more convenient to use the scale command.
::当你正在缩放/调整一个对象,并且你关心它的结果尺寸时,使用调整尺寸命令更方便.相反,当你更关心结果尺寸与起始尺寸的比率时,使用缩放命令更方便.

Exercise
Try squishing the spherical wheels of your car along the Y axis. Use the resize command and the wheel_width variable to have control over the resulting width of the wheels. Resize the wheels only along the Y axis.
Code

car_with_narrowed_spherical_wheels.scad
::车_带_狭窄_球形_轮.scad

$fa = 1;
$fs = 0.4;
wheel_radius = 8;
base_height = 8;
top_height = 10;
track = 30;
wheel_width = 4;
body_roll = 0;
wheels_turn = -20;
rotate([body_roll,0,0]) {
    // Car body base
    cube([60,20,base_height],center=true);
    // Car body top
    translate([5,0,base_height/2+top_height/2 - 0.001])
        cube([30,20,top_height],center=true);
}
// Front left wheel
translate([-20,-track/2,0])
    rotate([0,0,wheels_turn])
    resize([2*wheel_radius,wheel_width,2*wheel_radius])
    sphere(r=wheel_radius);
// Front right wheel
translate([-20,track/2,0])
    rotate([0,0,wheels_turn])
    resize([2*wheel_radius,wheel_width,2*wheel_radius])
    sphere(r=wheel_radius);
// Rear left wheel
translate([20,-track/2,0])
    rotate([0,0,0])
    resize([2*wheel_radius,wheel_width,2*wheel_radius])
    sphere(r=wheel_radius);
// Rear right wheel
translate([20,track/2,0])
    rotate([0,0,0])
    resize([2*wheel_radius,wheel_width,2*wheel_radius])
    sphere(r=wheel_radius);
// Front axle
translate([-20,0,0])
    rotate([90,0,0])
    cylinder(h=track,r=2,center=true);
// Rear axle
translate([20,0,0])
    rotate([90,0,0])
    cylinder(h=track,r=2,center=true);

The new wheel design looks cool. You can now create a body that better suits this new style.
::现在可以设计出更适合这种新风格的车身.

Exercise
Try using the sphere and resize/scale commands in place of the cube commands to create a body that matches the style of the wheels.
Code

car_with_narrowed_spherical_wheels_and_body.scad
::车_带_狭窄_球形_轮_和_车身

$fa = 1;
$fs = 0.4;
wheel_radius = 8;
base_height = 8;
top_height = 10;
track = 28;
wheel_width = 4;
body_roll = 0;
wheels_turn = -20;
rotate([body_roll,0,0]) {
    // Car body base
    resize([90,20,12])
        sphere(r=10);
    // Car body top
    translate([10,0,5])
        resize([50,15,15])
        sphere(r=10);
}
// Front left wheel
translate([-20,-track/2,0])
    rotate([0,0,wheels_turn])
    resize([2*wheel_radius,wheel_width,2*wheel_radius])
    sphere(r=wheel_radius);
// Front right wheel
translate([-20,track/2,0])
    rotate([0,0,wheels_turn])
    resize([2*wheel_radius,wheel_width,2*wheel_radius])
    sphere(r=wheel_radius);
// Rear left wheel
translate([20,-track/2,0])
    rotate([0,0,0])
    resize([2*wheel_radius,wheel_width,2*wheel_radius])
    sphere(r=wheel_radius);
// Rear right wheel
translate([20,track/2,0])
    rotate([0,0,0])
    resize([2*wheel_radius,wheel_width,2*wheel_radius])
    sphere(r=wheel_radius);
// Front axle
translate([-20,0,0])rotate([90,0,0])
    cylinder(h=track,r=2,center=true);
// Rear axle
translate([20,0,0])
    rotate([90,0,0])
    cylinder(h=track,r=2,center=true);

Combining objects in other ways
::通过其他方式组合物体

So far when you wanted to create an additional object in your model, you just added another statement in your script. The final car model is the union of all objects that have been defined in your script. You have been implicitly using the union command which is one of the available boolean operations. When using the union boolean operation, OpenSCAD takes the union of all objects as the resulting model. In the following script the union is used implicitly.
::到目前为止,当你想要在模型中创建一个额外的对象时,你只是在脚本中添加了另一个语句.最终的车模型是脚本中定义的所有对象的结合.你已经隐式地使用了联盟命令,这是可用的布尔操作之一.当使用联盟布尔操作时,OpenSCAD将所有对象的结合作为结果模型.在下面的脚本中,联盟被隐式地使用.

Code

union_of_two_spheres_implicit.scad
::两个球体的联合

sphere(r=10);
translate([10,0,0])
    sphere(r=10);

You can make the use of union explicit by including the union command in your script.
::你可以在脚本中包含 union 命令,

Code

union_of_two_spheres_explicit.scad
::两个球体的联合

union() {
    sphere(r=10);
    translate([12,0,0])
        sphere(r=10);
}

You should notice that the union command doesn’t have any input parameters. This is true for all boolean operations. The union is applied to all objects inside the curly brackets. You should also notice that the statements inside the curly brackets have a semicolon at the end. In contrast there is no semicolon after the closing curly bracket. This syntax is similar to the use of transformations when applied to multiple objects.
::您应该注意到,union命令没有任何输入参数.这对于所有布尔运算都是如此.Union适用于卷曲括号内的所有对象.您还应该注意到,卷曲括号内的语句在末尾有一个半点点.相比之下,闭括号后没有半点点.这种语法与应用到多个对象时的转换类似.

In total there are three boolean operations. The second one is the difference. The difference command subtracts the second and all further objects that have been defined inside the curly brackets from the first one. The previous example results in the following model when using the difference operation instead of the union.
::总共有三种布尔运算.第二个是差异.差异命令从第一个中减去第二个和所有已经定义在卷曲括号中的进一步对象.使用差异运算而不是联盟时,上一个示例会产生以下模型.

Code

difference_of_two_spheres.scad
::两个球体的差异.

difference() {
    sphere(r=10);
    translate([12,0,0])
        sphere(r=10);
}

Further defined objects (third, fourth etc.) are also subtracted. The following example has three objects.
::另外定义的对象 (第三,第四等) 也被减去.下面的例子有三个对象.

Code

difference_of_three_spheres.scad
::三个球的差异.

difference() {
    sphere(r=10);
    translate([12,0,0])
        sphere(r=10);
    translate([0,-12,0])
        sphere(r=10);
}

The third boolean operation is the intersection. The intersection operation keeps only the overlapping portion of all objects. The previous example results in the following model when the intersection operation is used.
::第三个布尔式操作是交叉.交叉操作只保留所有对象的重叠部分.当使用交叉操作时,上述示例会产生以下模型.

Code

intersection_of_three_spheres.scad
::三个球的交集

intersection() {
    sphere(r=10);
    translate([12,0,0])
        sphere(r=10);
    translate([0,-12,0])
        sphere(r=10);
}

The resulting model is the common area of all three objects.
::结果的模型是所有三个物体的共同面积.

When only the first two spheres are defined inside the curly brackets, the intersection is the following.
::当仅前两个球体被定义在卷曲括号内时,交点是如下.

Code

intersection_of_two_spheres.scad
::两个球体的交集

intersection() {
    sphere(r=10);
    translate([12,0,0])
        sphere(r=10);
}

Exercise
Try using the difference operation to create a new wheel design. To do so first create a sphere and then subtract a portion of a sphere from both sides. The radius of the first sphere should be equal to the desired wheel radius (wheel_radius variable). The radius of the other two spheres should be equal to a side_spheres_radius variable. Given a hub_thickness variable what is the amount of units that the side spheres should be translated along the positive and negative direction of Y axis so that the thickness of the remaining material at the center of the first sphere is equal to the value of hub_thickness?
Code

wheel_with_spherical_sides.scad
::具有球面的轮子

$fa = 1;
$fs = 0.4;
wheel_radius=10;
side_spheres_radius=50;
hub_thickness=4;
difference() {
    sphere(r=wheel_radius);
    translate([0,side_spheres_radius + hub_thickness/2,0])
        sphere(r=side_spheres_radius);
    translate([0,- (side_spheres_radius + hub_thickness/2),0])
        sphere(r=side_spheres_radius);
}

Exercise
Try removing some material from the wheels by subtracting four cylinders that are perpendicular to the wheel. The cylinders should be placed at half the wheel radius and be equally spaced. Introduce a cylinder_radius and a cylinder_height variable. The value of cylinder_height should be appropriate so that the cylinders are always longer than the thickness of the material they are removed from.
Code

wheel_with_spherical_sides_and_holes.scad
::具有球面和洞的轮子.

$fa = 1;
$fs = 0.4;
wheel_radius=10;
side_spheres_radius=50;
hub_thickness=4;
cylinder_radius=2;
cylinder_height=2*wheel_radius;
difference() {
    // Wheel sphere
    sphere(r=wheel_radius);
    // Side sphere 1
    translate([0,side_spheres_radius + hub_thickness/2,0])
        sphere(r=side_spheres_radius);
    // Side sphere 2
    translate([0,- (side_spheres_radius + hub_thickness/2),0])
        sphere(r=side_spheres_radius);
    // Cylinder 1
    translate([wheel_radius/2,0,0])
        rotate([90,0,0])
        cylinder(h=cylinder_height,r=cylinder_radius,center=true);
    // Cylinder 2
    translate([0,0,wheel_radius/2])
        rotate([90,0,0])
        cylinder(h=cylinder_height,r=cylinder_radius,center=true);
    // Cylinder 3
    translate([-wheel_radius/2,0,0])
        rotate([90,0,0])
        cylinder(h=cylinder_height,r=cylinder_radius,center=true);
    // Cylinder 4
    translate([0,0,-wheel_radius/2])
        rotate([90,0,0])
        cylinder(h=cylinder_height,r=cylinder_radius,center=true);
}

Exercise
Try using the above wheels in one version of the car.
Code

car_with_wheels_with_spherical_sides_and_holes.scad
::车_带_轮_带_球面_和_洞.

$fa = 1;
$fs = 0.4;
wheel_radius = 10;
base_height = 10;
top_height = 14;
track = 35;
wheel_width = 10;
body_roll = 0;
wheels_turn = 0;
side_spheres_radius=50;
hub_thickness=4;
cylinder_radius=2;
cylinder_height=2*wheel_radius;
rotate([body_roll,0,0]) {
    // Car body base
    cube([60,20,base_height],center=true);
    // Car body top
    translate([5,0,base_height/2+top_height/2 - 0.001])
        cube([30,20,top_height],center=true);
}
// Front left wheel
translate([-20,-track/2,0])
    rotate([0,0,wheels_turn])
    difference() {
        // Wheel sphere
        sphere(r=wheel_radius);
        // Side sphere 1
        translate([0,side_spheres_radius + hub_thickness/2,0])
            sphere(r=side_spheres_radius);
        // Side sphere 2
        translate([0,- (side_spheres_radius + hub_thickness/2),0])
            sphere(r=side_spheres_radius);
        // Cylinder 1
        translate([wheel_radius/2,0,0])
            rotate([90,0,0])
            cylinder(h=cylinder_height,r=cylinder_radius,center=true);
        // Cylinder 2
        translate([0,0,wheel_radius/2])
            rotate([90,0,0])
            cylinder(h=cylinder_height,r=cylinder_radius,center=true);
        // Cylinder 3
        translate([-wheel_radius/2,0,0])
            rotate([90,0,0])
            cylinder(h=cylinder_height,r=cylinder_radius,center=true);
        // Cylinder 4
        translate([0,0,-wheel_radius/2])
            rotate([90,0,0])
            cylinder(h=cylinder_height,r=cylinder_radius,center=true);
}
// Front right wheel
translate([-20,track/2,0])
    rotate([0,0,wheels_turn])
    difference() {
        // Wheel sphere
        sphere(r=wheel_radius);
        // Side sphere 1
        translate([0,side_spheres_radius + hub_thickness/2,0])
            sphere(r=side_spheres_radius);
        // Side sphere 2
        translate([0,- (side_spheres_radius + hub_thickness/2),0])
            sphere(r=side_spheres_radius);
        // Cylinder 1
        translate([wheel_radius/2,0,0])
            rotate([90,0,0])
            cylinder(h=cylinder_height,r=cylinder_radius,center=true);
        // Cylinder 2
        translate([0,0,wheel_radius/2])
            rotate([90,0,0])
            cylinder(h=cylinder_height,r=cylinder_radius,center=true);
        // Cylinder 3
        translate([-wheel_radius/2,0,0])
            rotate([90,0,0])
            cylinder(h=cylinder_height,r=cylinder_radius,center=true);
        // Cylinder 4
        translate([0,0,-wheel_radius/2])
            rotate([90,0,0])
            cylinder(h=cylinder_height,r=cylinder_radius,center=true);
}
// Rear left wheel
translate([20,-track/2,0])
    rotate([0,0,0])
    difference() {
        // Wheel sphere
        sphere(r=wheel_radius);
        // Side sphere 1
        translate([0,side_spheres_radius + hub_thickness/2,0])
            sphere(r=side_spheres_radius);
        // Side sphere 2
        translate([0,- (side_spheres_radius + hub_thickness/2),0])
            sphere(r=side_spheres_radius);
        // Cylinder 1
        translate([wheel_radius/2,0,0])
            rotate([90,0,0])
            cylinder(h=cylinder_height,r=cylinder_radius,center=true);
        // Cylinder 2
        translate([0,0,wheel_radius/2])
            rotate([90,0,0])
            cylinder(h=cylinder_height,r=cylinder_radius,center=true);
        // Cylinder 3
        translate([-wheel_radius/2,0,0])
            rotate([90,0,0])
            cylinder(h=cylinder_height,r=cylinder_radius,center=true);
        // Cylinder 4
        translate([0,0,-wheel_radius/2])
            rotate([90,0,0])
            cylinder(h=cylinder_height,r=cylinder_radius,center=true);
}
// Rear right wheel
translate([20,track/2,0])
    rotate([0,0,0])
    difference() {
        // Wheel sphere
        sphere(r=wheel_radius);
        // Side sphere 1
        translate([0,side_spheres_radius + hub_thickness/2,0])
            sphere(r=side_spheres_radius);
        // Side sphere 2
        translate([0,- (side_spheres_radius + hub_thickness/2),0])
            sphere(r=side_spheres_radius);
        // Cylinder 1
        translate([wheel_radius/2,0,0])
            rotate([90,0,0])
            cylinder(h=cylinder_height,r=cylinder_radius,center=true);
        // Cylinder 2
        translate([0,0,wheel_radius/2])
            rotate([90,0,0])
            cylinder(h=cylinder_height,r=cylinder_radius,center=true);
        // Cylinder 3
        translate([-wheel_radius/2,0,0])
            rotate([90,0,0])
            cylinder(h=cylinder_height,r=cylinder_radius,center=true);
        // Cylinder 4
        translate([0,0,-wheel_radius/2])
            rotate([90,0,0])
            cylinder(h=cylinder_height,r=cylinder_radius,center=true);
}
// Front axle
translate([-20,0,0])
    rotate([90,0,0])
    cylinder(h=track,r=2,center=true);
// Rear axle
translate([20,0,0])
    rotate([90,0,0])
    cylinder(h=track,r=2,center=true);

Last modified: Thursday, 20 March 2025, 12:21 PM