OpenSCAD教程
Defining and using modules
::定义和使用模块
The script of the last example of the previous chapter got quite long. This was the result of replacing the simple cylindrical wheels (which require one statement to be created) with a more complex wheel design (which requires many statements to be created). To change the wheels from the simple to the complex design you have to identify all cylinder commands that define the simple wheels and replace them with commands that define the complex wheels. This process sounds similar to the steps you had to go through to change the diameter of the wheels. When no use of variables was made you had to identify the corresponding values in your script and replace them one by one with the new value. This repetitive and time-consuming process was improved with the use of a wheel_radius variable which enabled you to quickly and easily change the diameter of the wheel. Can you do anything though to improve the corresponding error-prone process when you want to change completely the design of the wheels? The answer is yes! You can use modules which is the analogue of variables applied to whole parts/models. You can define a part of your design or even your whole model as a module.
::上一章的最后一个例子的脚本变得相当长. 这是用更复杂的轮设计 (需要创建一个语句) 取代简单的圆柱形轮的结果. 要将轮从简单设计改为复杂设计,你必须识别定义简单轮的所有圆柱命令并用定义复杂轮的命令替换它们. 这个过程听起来与你必须改变轮的直径所需的步骤相似. 当没有使用变量时,你必须在脚本中识别相应的值并将它们逐个替换为新的值. 这个重复和耗时的过程通过使用一个轮_半径变量得到了改进,使您能够快速和轻松地更改轮的直径. 您可以做任何事情来改善当您想要更改轮的答案时相应的错误易发生的过程吗?
First remember for a moment the design of the complex wheel.
::首先,请记住一下复杂的轮子的设计.
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); } |
You can define the above wheel as a module in the following way.
::你可以用以下方式将上述轮定义为模块.
blank_model.scad
$fa = 1; $fs = 0.4; module wheel() { 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); } } |
There are a few things that you need to get right. The first thing you should notice is that in order to define a module you have to type the word module followed by a name which you want to give to this module. In this case the module is named wheel. After the name of the module follows a pair of parentheses. Currently there is nothing inside the parentheses because no parameters have been defined for this module. Finally, after the pair of parentheses follows a pair of curly brackets. All commands that defined the corresponding object are placed inside the curly brackets. A semicolon is not required at the end.
::您需要做好一些事情.首先要注意的是,为了定义一个模块,您必须输入模块字,然后输入您想要给这个模块的名称.在这种情况下,该模块被称为轮.模块名称后接着是一对括号.目前括号内没有任何东西,因为这个模块没有定义参数.最后,括号后接着是一对括号.所有定义对应对象的命令都放置在括号内.在末尾不需要半点.
The second thing you should notice is that OpenSCAD has not created any wheel. This is because you have just defined the wheel module but have not used it yet. In order to create a wheel you need to add a statement that creates a wheel, similar to how you would add a statement to create any primitive object (cube, sphere etc.).
::你应该注意到的第二件事是OpenSCAD没有创建任何轮子.这是因为你刚刚定义了轮子模块,但还没有使用它.为了创建轮子,你需要添加一个创建轮子的语句,类似于你添加一个语句来创建任何原始对象 (立方体,球体等).
wheel_created_by_module.scad
$fa = 1; $fs = 0.4; module wheel() { 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); } } wheel(); |
You can think of defining modules as extending the OpenSCAD scripting language. When you have defined a wheel module it’s like having an additional available primitive object. In this case the new object is the wheel that you have defined. You can then use this module similar to how you would use any other available primitive.
::你可以把定义模块看作是扩展OpenSCAD脚本语言.当你定义了一个轮模块时,就像有一个额外的可用的原始对象.在这种情况下,新的对象是你定义的轮.然后你可以使用这个模块,就像你使用任何其他可用的原始一样.
Try defining the above wheel module in the car’s script. Try creating the wheels of the car using the defined wheel module. |
car_with_wheels_created_by_module.scad
module wheel() { 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); } } $fa = 1; $fs = 0.4; base_height = 10; top_height = 14; track = 35; body_roll = 0; wheels_turn = 0; 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]) wheel(); // Front right wheel translate([-20,track/2,0]) rotate([0,0,wheels_turn]) wheel(); // Rear left wheel translate([20,-track/2,0]) rotate([0,0,0]) wheel(); // Rear right wheel translate([20,track/2,0]) rotate([0,0,0]) wheel(); // 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); |
Parameterizing modules
::参数化模块
The wheel design that was specified in the wheel module has a number of variables that can be used to customize it. These variables are defined inside the curly brackets of the wheel module’s definition. As a result, while the output of the wheel module can be customized, the wheel module itself can create only one version of the wheel which corresponds to the values of the defined variables. This means the wheel module can’t be used to create different wheels for the front and back axles. If you have been getting a feeling of the good practices of parametric design, you should realize that such a thing is not desired. It would be way better if the wheel module could be used to create different versions of the wheel. For this to happen the variables that are defined and used inside the wheel module, need to be defined as parameters of the wheel module instead. This can be done in the following way.
::轮模块中指定的轮子设计有多个可用于自定义的变量.这些变量定义在轮模块定义的卷曲括号内.因此,虽然轮模块的输出可以定制,但轮模块本身只能创建与定义变量的值相对应的单个版本的轮子.这意味着轮模块不能用于为前轴和后轴创建不同的轮子.如果您已经了解了参数设计的良好实践,您应该意识到这样的事情是不必要的.如果轮模块可以用于创建不同的轮子版本,那么会更好.为了实现这一点,在轮模块内定义和使用的变量需要定义为轮模块的参数.这可以用以下方法来完成.
wheel_created_by_parameterized_module.scad
$fa = 1; $fs = 0.4; module wheel(wheel_radius, side_spheres_radius, hub_thickness, cylinder_radius) { 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); } } wheel(wheel_radius=10, side_spheres_radius=50, hub_thickness=4, cylinder_radius=2); |
You should notice the definition of the module’s parameters inside the parentheses. You should also notice that the value of each parameter is no longer assigned inside the curly brackets of the module’s definitions. Instead, the value of the parameters is defined every time the modules is called. As a result, the module can now be used to create different versions of the wheel.
::您应该注意到 modules参数的定义在括号内.您还应该注意到每个参数的值不再被分配到 modules定义的卷曲括号内.相反,参数的值每次调用模块时都被定义.因此,模块现在可以用于创建不同的版本的轮子.
Try defining the above wheel module in the car’s script. Try creating the car’s wheels by using the wheel module. When calling the wheel module pass the values of 10, 50, 4 and 2 to the corresponding wheel_radius, side_spheres_radius, hub_thickness and cylinder_radius parameters. |
car_with_wheels_created_by_parameterized_module.scad
module wheel(wheel_radius, side_spheres_radius, hub_thickness, cylinder_radius) { 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); } } $fa = 1; $fs = 0.4; base_height = 10; top_height = 14; track = 35; body_roll = 0; wheels_turn = 0; 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]) wheel(wheel_radius=10, side_spheres_radius=50, hub_thickness=4, cylinder_radius=2); // Front right wheel translate([-20,track/2,0]) rotate([0,0,wheels_turn]) wheel(wheel_radius=10, side_spheres_radius=50, hub_thickness=4, cylinder_radius=2); // Rear left wheel translate([20,-track/2,0]) rotate([0,0,0]) wheel(wheel_radius=10, side_spheres_radius=50, hub_thickness=4, cylinder_radius=2); // Rear right wheel translate([20,track/2,0]) rotate([0,0,0]) wheel(wheel_radius=10, side_spheres_radius=50, hub_thickness=4, cylinder_radius=2); // 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); |
Try defining a wheel_radius, side_spheres_radius, hub_thickness and cylinder_radius variable in the car’s script and assign the values of 10, 50, 4 and 2 accordingly. Try using these variables to define the values of the wheel_radius, side_spheres_radius, hub_thickness and cylinder_radius parameters when calling the wheel module. |
wheel_radius=10; side_spheres_radius=50; hub_thickness=4; cylinder_radius=2; wheel(wheel_radius=wheel_radius, side_spheres_radius=side_spheres_radius, hub_thickness=hub_thickness, cylinder_radius=cylinder_radius); |
Try defining different wheel_radius, side_spheres_radius, hub_thickness and cylinder_radius variables for the front and rear axles. Try assigning a combination of values that you like to these variables. Remember to also edit the name of the variables in the respective calls of the wheel module. |
car_with_different_wheels.scad
module wheel(wheel_radius, side_spheres_radius, hub_thickness, cylinder_radius) { 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); } } $fa = 1; $fs = 0.4; base_height = 10; top_height = 14; track = 35; body_roll = 0; wheels_turn = 0; wheel_radius_front=10; side_spheres_radius_front=50; hub_thickness_front=4; cylinder_radius_front=2; wheel_radius_rear=12; side_spheres_radius_rear=30; hub_thickness_rear=8; cylinder_radius_rear=3; 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]) wheel(wheel_radius=wheel_radius_front, side_spheres_radius=side_spheres_radius_front, hub_thickness=hub_thickness_front, cylinder_radius=cylinder_radius_front); // Front right wheel translate([-20,track/2,0]) rotate([0,0,wheels_turn]) wheel(wheel_radius=wheel_radius_front, side_spheres_radius=side_spheres_radius_front, hub_thickness=hub_thickness_front, cylinder_radius=cylinder_radius_front); // Rear left wheel translate([20,-track/2,0]) rotate([0,0,0]) wheel(wheel_radius=wheel_radius_rear, side_spheres_radius=side_spheres_radius_rear, hub_thickness=hub_thickness_rear, cylinder_radius=cylinder_radius_rear); // Rear right wheel translate([20,track/2,0]) rotate([0,0,0]) wheel(wheel_radius=wheel_radius_rear, side_spheres_radius=side_spheres_radius_rear, hub_thickness=hub_thickness_rear, cylinder_radius=cylinder_radius_rear); // 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); |
Defining default values of module’s parameters
::定义模块参数的默认值
You can set a specific combination of values for the wheel module’s parameters as default. This can be achieved in the following way.
::您可以将轮模块参数的特定值组合设置为默认值.可以通过以下方式实现.
$fa = 1; $fs = 0.4; module wheel(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); } } |
You should notice that the default values are assigned inside the parentheses at the definition of the module. By defining default values for the module’s parameters, you have more flexibility in the way the wheel module is used. For example, the simplest way to use the module is without specifying any parameters when calling it.
::您应该注意到在模块定义时,默认值被赋值在括号内.通过定义模块参数的默认值,您在使用轮模块的方式上具有更大的灵活性.例如,最简单的使用模块的方式是在调用时不指定任何参数的情况下.
wheel_created_by_default_parameters.scad
… wheel(); … |
If a parameter’s value is not specified when calling the wheel module, the default value for this parameter is used. The default values can be set equal to the most used version of the wheel. The default values can be overridden by assigning a new value to the corresponding parameters when calling the wheel module. None or any number of default values may be overridden. Thus, by specifying default values the wheel module can be used in any of the following ways as well as in many more.
::如果在调用轮模块时未指定参数s值,则使用该参数的默认值.默认值可以设置为与轮模块最常用的版本相同.在调用轮模块时,可以通过赋予相应参数新的值来覆盖默认值.任何默认值或任何数量的默认值都可能被覆盖.因此,通过指定默认值,轮模块可以以以下任何方式以及更多方式使用.
wheel_created_by_default_parameters.scad
… wheel(); … |
wheel_with_thicker_hub.scad
… wheel(hub_thickness=8); … |
wheel_with_thicker_hub_and_larger_radius.scad
… wheel(hub_thickness=8, wheel_radius=12); … |
Include default values in the definition of the wheel module. Try creating a few wheels by overriding any number of default values. Can you make a wheel that looks like the following? |
wheel_with_larger_side_radius.scad
… wheel(side_spheres_radius=10); … |
The use of modules is a very powerful feature of OpenSCAD. You should start thinking of your models as a combination of modules. For example, the car model can be thought of as a combination of a body, wheel and axle module. This opens the possibilities of further reusing and recombining your modules to create different models.
::模块的使用是OpenSCAD的一个非常强大的功能.你应该开始把你的模型看作是模块的组合.例如,汽车模型可以被认为是车身,轮和轴模块的组合.这为进一步重复使用和重新组合你的模块创造不同的模型打开了可能性.
Try defining a body and an axle module. What parameters should the body and axle modules have? Try recreating the car using the body, wheel and axle modules. Give the parameters of the wheel module a default set of values that corresponds to the front wheels. Pass different values to the wheel module when creating the rear wheels by defining appropriate variables in your script. Set default values for the parameters of the body and axle modules too. |
car_with_different_wheels_and_default_body_and_axle.scad
module wheel(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); } } module body(base_height=10, top_height=14, base_length=60, top_length=30, width=20, top_offset=5) { // Car body base cube([base_length,width,base_height],center=true); // Car body top translate([top_offset,0,base_height/2+top_height/2 - 0.001]) cube([top_length,width,top_height],center=true); } module axle(track=35, radius=2) { rotate([90,0,0]) cylinder(h=track,r=radius,center=true); } $fa = 1; $fs = 0.4; wheelbase = 40; track = 35; body_roll = 0; wheels_turn = 0; wheel_radius_rear=12; // Body rotate([body_roll,0,0]) { body(); } // Front left wheel translate([-wheelbase/2,-track/2,0]) rotate([0,0,wheels_turn]) wheel(); // Front right wheel translate([-wheelbase/2,track/2,0]) rotate([0,0,wheels_turn]) wheel(); // Rear left wheel translate([wheelbase/2,-track/2,0]) rotate([0,0,0]) wheel(wheel_radius=wheel_radius_rear); // Rear right wheel translate([wheelbase/2,track/2,0]) rotate([0,0,0]) wheel(wheel_radius=wheel_radius_rear); // Front axle translate([-wheelbase/2,0,0]) axle(); // Rear axle translate([wheelbase/2,0,0]) axle(); |
Try reusing the body, wheel and axle modules to create vehicle that looks similar to the following. |
car_with_six_wheels.scad
module wheel(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); } } module body(base_height=10, top_height=14, base_length=60, top_length=30, width=20, top_offset=5) { // Car body base cube([base_length,width,base_height],center=true); // Car body top translate([top_offset,0,base_height/2+top_height/2 - 0.001]) cube([top_length,width,top_height],center=true); } module axle(track=35, radius=2) { rotate([90,0,0]) cylinder(h=track,r=radius,center=true); } $fa = 1; $fs = 0.4; track = 35; body_roll = 0; wheels_turn = 0; base_length = 100; top_length = 75; top_offset = 5; front_axle_offset = 30; rear_axle_1_offset = 10; rear_axle_2_offset = 35; wheel_radius = 12; // Body rotate([body_roll,0,0]) { body(base_length=base_length, top_length=top_length, top_offset=top_offset); } // Front left wheel translate([-front_axle_offset,-track/2,0]) rotate([0,0,wheels_turn]) wheel(wheel_radius=wheel_radius); // Front right wheel translate([-front_axle_offset,track/2,0]) rotate([0,0,wheels_turn]) wheel(wheel_radius=wheel_radius); // Rear left wheel 1 translate([rear_axle_1_offset,-track/2,0]) rotate([0,0,0]) wheel(wheel_radius=wheel_radius); // Rear right wheel 1 translate([rear_axle_1_offset,track/2,0]) rotate([0,0,0]) wheel(wheel_radius=wheel_radius); // Rear left wheel 2 translate([rear_axle_2_offset,-track/2,0]) rotate([0,0,0]) wheel(wheel_radius=wheel_radius); // Rear right wheel 2 translate([rear_axle_2_offset,track/2,0]) rotate([0,0,0]) wheel(wheel_radius=wheel_radius); // Front axle translate([-front_axle_offset,0,0]) axle(); // Rear axle 1 translate([rear_axle_1_offset,0,0]) axle(); // Rear axle 2 translate([rear_axle_2_offset,0,0]) axle(); |