OpenSCAD用戶手冊/變換

維基教科書,自由的教學讀本

基本概念[編輯]

顧名思義,變換會以各種方式影響子節點,例如對它們進行移動、旋轉或縮放。級聯變換(cascading transformations)則常用於將多種變換作用於一個最終子對象 。通過嵌套語句即可實現級聯變換,即:

rotate([45,45,45])
  translate([10,20,30])
    cube(10);

利用'{' 與 '}'圍起子節點樹,即可將變換應用於這一組子節點,如:

translate([0,0,-5])
{
    cube(10);
    cylinder(r=5,h=10);
}

變換要寫於其影響的對象之前。

可以將類似於translate(平移)、mirror(鏡像)與scale(縮放)這樣的命令想象為動詞。而將color(上色)這樣的命令想象為描述對象的形容詞。

請注意,變換命令後不加分號。

高級概念[編輯]

由於OpenSCAD採用不同的庫來實現其中功能,因此在用F5預覽變換的行為時可能會產生一些不一致的現象。傳統的變換(平移,旋轉,縮放,鏡像與multmatrix)都採用OpenGL實現預覽。而其他更為高級的變換,如resize,則用CGAL進行處理,其行為就像CSG操作,影響的是對象本身,而不僅僅是對其進行變換。特別是這會影響修飾符的顯示,尤其是"#"與"%",where the highlight may not display intuitively。such as highlighting the pre-resized object, but highlighting the post-scaled object.



scale[編輯]

scale命令利用指定的向量來縮放其子元素。參數名可以不寫。

用例:
scale(v = [x, y, z]) { ... }
cube(10);
translate([15,0,0]) scale([0.5,1,2]) cube(10);

在OpenSCAD中進行scale()變換後的圖像顯示結果

注意: 不要用負數作為縮放值。負縮放值的效果可以在預覽中看到,但是通過CGAL渲染時會導致不可預測的錯誤。如需輸入負值,可用mirror()函數代替。

resize[編輯]

根據指定的x、y、z修改子對象的尺寸。

resize()函數由CGAL來實現,就像render()這樣的函數一樣要處理整個幾何體,因此就算是在預覽模式下也要花上些時間來進行處理。


用例:

// 将球体在x轴上的直径拓展至30,在y轴上的直径拓展至60,在z轴上的直径拓展至10。
resize(newsize=[30,60,10]) sphere(r=10);

在OpenSCAD中利用resize()繪製橢圓體的示例

如果x、y或z為0,那麼原對象在對應維度上保持不變。

// 将大小为1x1x1的立方体调整为2x2x1
resize([2,2,0]) cube();

如果把'auto'參數設置為true,則resize函數將對參數值為0的維度進行自動縮放。例如:

// 将大小为1x2x0.5的长方体调整为7x14x3.5
resize([7,0,0], auto=true) cube([1,2,0.5]);

'auto'參數也可用於僅對一個維度進行自動縮放而其他維度保持不變的情況。

// 将原长方体调整为10x8x1。请注意,其z维度保持不变。
resize([10,0,0], auto=[true,true,false]) cube([5,4,1]);

rotate[編輯]

令子元素繞坐標軸或任意軸旋轉'a'度。如果將參數按下列相同順序指定,則可省略參數名。

//用例:
rotate(a = deg_a, v = [x, y, z]) { ... }  
// 或
rotate(deg_a, [x, y, z]) { ... }
rotate(a = [deg_x, deg_y, deg_z]) { ... }
rotate([deg_x, deg_y, deg_z]) { ... }

參數'a'(deg_a)可以是一個數組,其語法如上所示;當deg_a是一個數組時,將忽略參數'v'。而此時的'a'則指定的是令物體繞多個坐標軸進行旋轉,而旋轉的執行順序為:x, y, z。這就意味着下列代碼:

rotate(a=[ax,ay,az]) {...}

等價於(旋轉順序會影響最終旋轉結果):

rotate(a=[0,0,az]) rotate(a=[0,ay,0]) rotate(a=[ax,0,0]) {...}

可選參數'v'是一個向量,您可藉此令對象繞任意軸進行旋轉。


例如,為了讓一個對象上下顛倒翻轉過來,您可以令此對象繞'y'軸旋轉180度。

rotate(a=[0,180,0]) { ... }

常用化簡寫法為:

rotate([0,180,0]) { ... }


在指定單個坐標軸時,通過設置參數'v'也能令對象繞坐標軸進行旋轉。例如,以下代碼是上述代碼的等效實現,它令對象僅繞軸y進行旋轉

rotate(a=180, v=[0,1,0]) { ... }


在指定單個坐標軸時,參數'v'是一個定義任意旋轉軸的向量;這與此前提及的繞多個坐標軸進行旋轉並不相同。例如,令對象繞向量[1,1,0]定義的軸旋轉45度的代碼為

rotate(a=45, v=[1,1,0]) { ... }

在OpenSCAD中進行rotate()變換後的圖像顯示結果


利用單個標量參數令對象繞Z軸進行旋轉。這種方法在2D環境中十分有用,此時通常僅繞一種軸進行旋轉。例如:

rotate(45) square(10);

在OpenSCAD中利用rotate(45)進行2D渲染後的效果


旋轉規則提示[編輯]
右手定則


針對以下情況:

rotate([a, b, c]) { ... };

"a"是一個令對象從+Y軸方向至+Z軸方向繞X軸旋轉的旋轉角。
"b"是一個令對象從+Z軸方向至+X軸方向繞Y軸旋轉的旋轉角。
"c"是一個令對象從+X軸方向至+Y軸方向繞Z軸旋轉的旋轉角。

這些情況均遵從右手法則。右手拇指指向旋轉軸的正方向,則其他手指的自然彎曲方向即為旋轉方向。


因此,如果"a"恆為0,且對"b"與"c"進行適當的計算,便可將rotate()當作球坐標系來使用。
所以,為了構建從原點至(x,y,z)的圓柱體,可以這樣編寫代碼:

x= 10; y = 10; z = 10; // 圆柱体的端点坐标
 
length = norm([x,y,z]);  // 半径距离
b = acos(z/length); // 倾角(inclination angle)
c = atan2(y,x);     // 方位角(azimuthal angle)

rotate([0, b, c]) 
    cylinder(h=length, r=0.5);
%cube([x,y,z]); // 圆柱体的端点应与立方体的交点重合

將OpenSCAD的Rotate()函數用作求坐標系的示例。

translate[編輯]

沿指定向量平移(移動)子元素。可省略參數名。

示例:
translate(v = [x, y, z]) { ... }
cube(2,center = true); 
translate([5,0,0]) 
   sphere(1,center = true);

在OpenSCAD中進行translate()變換後的圖像顯示結果

mirror[編輯]

基於原點對平面上的子元素進行鏡像操作。傳入mirror()函數的參數為交於原點且用於鏡像對象的平面上的法向量。

函數簽名:[編輯]

mirror(v= [x, y, z] ) { ... }

Examples[編輯]

左側為原始對象。請注意,鏡像並非複製品。而是像rotate與scale函數那樣,改變對象本身。

rotate([0,0,10]) cube([3,2,1]);
mirror([1,0,0]) translate([1,0,0]) rotate([0,0,10]) cube([3,2,1]);

在OpenSCAD中執行mirror()變換的效果圖

multmatrix[編輯]

為所有子元素的幾何體乘上指定的4x4變換矩陣。

用法: multmatrix(m = [...]) { ... }

以下為矩陣中前三行每一元素的內含解析:

[Scale X][Scale X sheared along Y][Scale X sheared along Z][Translate X]
[Scale Y sheared along X][Scale Y][Scale Y sheared along Z][Translate Y]
[Scale Z sheared along X][Scale Z sheared along Y][Scale Z][Translate Z]

第四行用於在3D環境中定義對象的視圖。在OpenSCAD中沒有用到這一點,應將其設置為[0,0,0,1]。

以下示例為將對象在XY平面內旋轉45度,並按[10,20,30]進行平移,其效果與translate([10,20,30]) rotate([0,0,45])相同。

angle=45;
multmatrix(m = [ [cos(angle), -sin(angle), 0, 10],
                 [sin(angle),  cos(angle), 0, 20],
                 [         0,           0, 1, 30],
                 [         0,           0, 0,  1]
              ]) union() {
   cylinder(r=10.0,h=10,center=false);
   cube(size=[10,10,10],center=false);
}

以下為令模型傾斜(skew)的示例,這是不能由其他變換來實現的。此例也展示了可將矩陣置於一個變量中。

M = [ [ 1  , 0  , 0  , 0   ],
      [ 0  , 1  , 0.7, 0   ],  // "0.7"为倾斜值;在这里,它令对象偏离y轴发生倾斜
      [ 0  , 0  , 1  , 0   ],
      [ 0  , 0  , 0  , 1   ] ] ;
multmatrix(M) {  union() {
    cylinder(r=10.0,h=10,center=false);
    cube(size=[10,10,10],center=false); 
} }

不夠刺激?[編輯]

來這裡學習更多的相關知識吧:

color[編輯]

利用指定的RGB顏色 + alpha值來顯示子元素。此函數僅用於F5預覽,因為CGAL 與 STL (F6)當前還不支持上色。如果未指定alpha值,其默認值為1.0(不透明)。

函數簽名:[編輯]

color( c = [r, g, b, a] ) { ... }
color( c = [r, g, b], alpha = 1.0 ) { ... }
color( "#hexvalue" ) { ... }
color( "colorname", 1.0 ) { ... }

請注意,r, g, b, a值僅限於[0,1]範圍中的浮點值,而非相對傳統的{ 0 ... 255 }整數值。然鵝,沒有神馬能阻止您通過適當的比例轉換方式color([ R/255, G/255, B/255 ]) { ... }來運用{0 ... 255}範圍的R, G, B值:

[請注意: 需要使用版本 2011.12] 可以通過顏色名稱(大小寫敏感)來定義顏色。例如,要創建一個紅色的球體,您可以寫color("red") sphere(5);。對於採用顏色名稱指定顏色的方式而言,還要為alpha值額外指定一個參數:color("Blue",0.5) cube(5);

[請注意: 需要使用版本 2019.05] 表示顏色的16進制值有4種格式:#rgb, #rgba, #rrggbb#rrggbbaa。如果alpha值以單獨的16進制參數給出,the alpha parameter will take precedence.

可用的顏色名稱都取自萬維網聯盟的[1]。下面給出一幅顏色名稱圖表,
(請注意,包括slategrey/slategray等在內的grey/gray拼寫都是合法的):


Purples
Lavender
Thistle
Plum
Violet
Orchid
Fuchsia
Magenta
MediumOrchid
MediumPurple
BlueViolet
DarkViolet
DarkOrchid
DarkMagenta
Purple
Indigo
DarkSlateBlue
SlateBlue
MediumSlateBlue
Pinks
Pink
LightPink
HotPink
DeepPink
MediumVioletRed
PaleVioletRed
Blues
Aqua
Cyan
LightCyan
PaleTurquoise
Aquamarine
Turquoise
MediumTurquoise
DarkTurquoise
CadetBlue
SteelBlue
LightSteelBlue
PowderBlue
LightBlue
SkyBlue
LightSkyBlue
DeepSkyBlue
DodgerBlue
CornflowerBlue
RoyalBlue
Blue
MediumBlue
DarkBlue
Navy
MidnightBlue
Reds
IndianRed
LightCoral
Salmon
DarkSalmon
LightSalmon
Red
Crimson
FireBrick
DarkRed
Greens
GreenYellow
Chartreuse
LawnGreen
Lime
LimeGreen
PaleGreen
LightGreen
MediumSpringGreen
SpringGreen
MediumSeaGreen
SeaGreen
ForestGreen
Green
DarkGreen
YellowGreen
OliveDrab
Olive
DarkOliveGreen
MediumAquamarine
DarkSeaGreen
LightSeaGreen
DarkCyan
Teal
Oranges
LightSalmon
Coral
Tomato
OrangeRed
DarkOrange
Orange
Yellows
Gold
Yellow
LightYellow
LemonChiffon
LightGoldenrodYellow
PapayaWhip
Moccasin
PeachPuff
PaleGoldenrod
Khaki
DarkKhaki
Browns
Cornsilk
BlanchedAlmond
Bisque
NavajoWhite
Wheat
BurlyWood
Tan
RosyBrown
SandyBrown
Goldenrod
DarkGoldenrod
Peru
Chocolate
SaddleBrown
Sienna
Brown
Maroon
Whites
White
Snow
Honeydew
MintCream
Azure
AliceBlue
GhostWhite
WhiteSmoke
Seashell
Beige
OldLace
FloralWhite
Ivory
AntiqueWhite
Linen
LavenderBlush
MistyRose
Grays
Gainsboro
LightGrey
Silver
DarkGray
Gray
DimGray
LightSlateGray
SlateGray
DarkSlateGray
Black

示例[編輯]

一個3-D酷炫多色正弦波模型

這裡給出一個繪製多色波浪對象的代碼片段:

  for(i=[0:36]) {
    for(j=[0:36]) {
      color( [0.5+sin(10*i)/2, 0.5+sin(10*j)/2, 0.5+sin(10*(i+j))/2] )
      translate( [i, j, 0] )
      cube( size = [1, 1, 11+10*cos(10*i)*sin(10*j)] );
    }
  }

↗ 由於 -1<=sin(x)<=1,因此 0<=(1/2 + sin(x)/2)<=1 ,這樣即可為RGB分量賦予[0,1]區間中的顏色值。

基於Wikipedia中"網頁顏色"詞條的顏色圖表

示例2[編輯]

在本例中,我們將基於參數來選擇性地設置顏色,這裡使用了如下技巧:

 module myModule(withColors=false) {
    c=withColors?"red":undef;
    color(c) circle(r=10);
 }

將colorname設置為undef將保持其默認顏色。

offset[編輯]

[請注意: 需要使用版本 2015.03]

offset函數根據指定的值令2D輪廓外向或內向移動。

  • 通過正偏移外表面與負偏移內表面之差可方便地繪製薄壁。
  • Fillet: offset(r=-3) offset(delta=+3) rounds all inside (concave) corners, and leaves flat walls unchanged. However, holes less than 2*r in diameter will vanish.
  • Round: offset(r=+3) offset(delta=-3) rounds all outside (convex) corners, and leaves flat walls unchanged. However, walls less than 2*r thick will vanish.

參數

r | delta
雙精度浮點數(double)。偏移多邊形的值。此值為負時,令多邊形進行內向偏移。參數r指定的是用於生成圓角的半徑,使用delta則採用直邊。
chamfer
布爾值(boolean)。 (默認值為false) 在使用delta參數時,此標誌定義了是(以直線進行切割)否(擴展至邊的交點)應當對邊進行倒角。
正的r/delta值
負的r/delta值
不同參數所得到的結果。黑色多邊形是用於offset()處理的輸入幾何圖形。

示例

示例1的效果圖。
// 示例1
 
linear_extrude(height = 60, twist = 90, slices = 60) {
   difference() {
     offset(r = 10) {
      square(20, center = true);
     }
     offset(r = 8) {
       square(20, center = true);
     }
   }
 }
// 示例2
 
module fillet(r) {
   offset(r = -r) {
     offset(delta = r) {
       children();
     }
   }
}


minkowski[編輯]

一個長方體與一個圓柱體
上述長方體與圓柱體的閔可夫斯基和

顯示子節點的閔可夫斯基和(minkowski sum)

用例:

假設您有一個平整的立方體,並希望對其進行倒圓角操作。有很多方法可以達到此目的,minkowski就是一種簡單易用的方法。先來製作待處理的立方體與圓柱體:

 $fn=50;
 cube([10,10,1]);
 cylinder(r=2,h=1);

接着,令它們執行閔可夫斯基和(請注意,立方體的外形尺寸現在為14x2,10+2+2 = 14個單位,而高的2個單位則為兩者的高之和):

$fn=50;
minkowski()
{
  cube([10,10,1]);
  cylinder(r=2,h=1);
}

請注意:第二個對象的原點(origin)將用於求和運算。如果第二個對象並未對齊於原點,則閔可夫斯基和的結果將是不對稱的。下列兩種閔可夫斯基和是不同的:第一種會把原始的立方體在正負每個方向各展開0.5個單位。而第二種會將原始立方體在每個正方向上擴展+1,卻不會在負方向上對其進行展開。

minkowski() {
	cube([10, 10, 1]);
	cylinder(1, center=true);
}
minkowski() {
	cube([10, 10, 1]);
	cylinder(1);
}

hull[編輯]

兩個圓柱體
上述兩個圓柱體的凸包

顯示子節點的凸包(convex hull)

用例:

hull() {
    translate([15,10,0]) circle(10);
    circle(10);
}

採用2D參數的hull函數只能計算出2D結果;在Z軸方向上平移2D組件不會產生任何效果。

組合變換[編輯]

在把多種變換組合在一起時,要按從右至左的次序進行處理。例如,

 rotate( ... ) translate ( ... ) cube(5) ;

將首先平移立方體,再以平移距離為半徑的弧(弧度為rotate中所指定)進行移動。

 translate ( ... ) rotate( ... ) cube(5) ;

將首先旋轉立方體,再將其按平移定義的偏移量進行平移。

將兩種變換組合起來
color("red")   translate([0,10,0])  rotate([45,0,0])     cube(5);
color("green") rotate([45,0,0])     translate([0,10,0])  cube(5);