跳转到内容

OpenSCAD 用户手册/数学函数

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

三角函数

[编辑 | 编辑源代码]

三角函数使用 C 语言数学函数,而这些函数又基于二进制浮点数数学,在计算过程中使用实数的近似值。 OpenSCAD 的数学函数使用 C++ 的 'double' 类型,在 Value.h/Value.cc 中,

有关 C 库数学函数细节的良好资源(例如有效输入/输出范围)可以在 Open Group 网站找到 math.hacos

度的数学 余弦 函数。 参见 余弦

参数

<degrees>
十进制。角度以度为单位。
使用示例
 for(i=[0:36])
    translate([i*10,0,0])
       cylinder(r=5,h=cos(i*10)*50+60);
OpenSCAD 余弦函数

数学 正弦 函数。 参见 正弦

参数

<degrees>
十进制。角度以度为单位。
使用示例 1
 for (i = [0:5]) {
  echo(360*i/6, sin(360*i/6)*80, cos(360*i/6)*80);
   translate([sin(360*i/6)*80, cos(360*i/6)*80, 0 ])
    cylinder(h = 200, r=10);
 }
使用示例 2
 for(i=[0:36])
    translate([i*10,0,0])
       cylinder(r=5,h=sin(i*10)*50+60);
OpenSCAD 正弦函数

数学 正切 函数。 参见 正切

参数

<degrees>
十进制。角度以度为单位。
使用示例
 for (i = [0:5]) {
  echo(360*i/6, tan(360*i/6)*80);
   translate([tan(360*i/6)*80, 0, 0 ])
    cylinder(h = 200, r=10);
 }

数学 反余弦反余弦,以度为单位表示。 参见:反三角函数

数学 反正弦反正弦,以度为单位表示。 参见:反三角函数

数学 反正切反正切 函数。 以度为单位返回 x 的反正切的主值。 atan 无法区分 y/x 和 -y/-x,并返回 -90 到 +90 的角度。 参见:atan2 以及 反三角函数

数学 二参数反正切 函数 atan2(y,x) 涵盖完整的 360 度。 此函数返回 x 轴与向量(x,y) 之间形成的完整角度(0-360),以度为单位表示。

使用示例

atan2(5.0,-5.0);     //result: 135 degrees. atan() would give -45
atan2(y,x);          //angle between (1,0) and (x,y) = angle around z-axis

其他数学函数

[编辑 | 编辑源代码]

数学 绝对值 函数。 返回带符号十进制数的正值。

使用示例

abs(-5.0);  returns 5.0
abs(0);     returns 0.0
abs(8.0);   returns 8.0

数学 向上取整 函数。

通过向上舍入值(如有必要)返回下一个最高的整数值。

参见:向上取整函数

echo(ceil(4.4),ceil(-4.4));     // produces ECHO: 5, -4

[注意: 需要版本 2015.03]

返回一个新的向量,它是附加了提供的向量的元素的结果。

如果一个参数是向量,则向量的元素将被单独附加到结果向量。 字符串在这种情况下与向量不同。

使用示例

echo(concat("a","b","c","d","e","f"));          // produces ECHO: ["a", "b", "c", "d", "e", "f"]
echo(concat(["a","b","c"],["d","e","f"]));      // produces ECHO: ["a", "b", "c", "d", "e", "f"]
echo(concat(1,2,3,4,5,6));                      // produces ECHO: [1, 2, 3, 4, 5, 6]

向量向量

echo(concat([ [1],[2] ], [ [3] ]));             // produces ECHO: [[1], [2], [3]]

注意: 传递给函数的所有向量都会失去一个嵌套级别。 当添加诸如单个元素 [x, y, z] 元组(也是向量)之类的元素时,在连接之前,元组需要用向量(即额外的括号)括起来。 在下面的示例中,一个第四点被添加到多边形路径中,该路径以前类似于三角形,现在将其变成一个正方形

polygon(concat([[0,0],[0,5],[5,5]], [[5,0]]));

与字符串对比

echo(concat([1,2,3],[4,5,6]));                   // produces ECHO: [1, 2, 3, 4, 5, 6]
echo(concat("abc","def"));                       // produces ECHO: ["abc", "def"]
echo(str("abc","def"));                          // produces ECHO: "abcdef"

计算 3D 或 2D 空间中两个向量的叉积。 如果两个向量都在 3D 中,结果是一个垂直于两个输入向量的向量。 如果两个向量都在 2D 空间中,它们的叉积具有 [0,0,z] 的形式,并且叉积函数仅返回叉积的 z 值

cross([x,y], [u,v]) = x*v - y*u

请注意,这是 2x2 矩阵 [[x,y],[u,v]] 的行列式。 使用任何其他类型,长度不同于 2 或 3 的向量,或者长度不同的向量会产生 'undef'。

使用示例

echo(cross([2, 3, 4], [5, 6, 7]));     // produces ECHO: [-3, 6, -3]
echo(cross([2, 1, -3], [0, 4, 5]));    // produces ECHO: [17, -10, 8]
echo(cross([2, 1], [0, 4]));           // produces ECHO: 8
echo(cross([1, -3], [4, 5]));          // produces ECHO: 17
echo(cross([2, 1, -3], [4, 5]));       // produces ECHO: undef
echo(cross([2, 3, 4], "5"));           // produces ECHO: undef

对于 2D 或 3D 中的任何两个向量 ab,以下成立

cross(a,b) == -cross(b,a)

数学 **exp** 函数。返回 x 的以 e 为底的指数函数,即 e 的 x 次方。参见:指数

echo(exp(1),exp(ln(3)*4));    // produces ECHO: 2.71828, 81

数学 **floor** 函数。floor(x) = 不大于 x 的最大整数

参见:向下取整函数

echo(floor(4.4),floor(-4.4));    // produces ECHO: 4, -5

数学 **自然对数**。参见:自然对数

数学 **长度** 函数。返回数组、向量或字符串参数的长度。

使用示例

str1="abcdef"; len_str1=len(str1);
echo(str1,len_str1);

a=6; len_a=len(a);
echo(a,len_a);

array1=[1,2,3,4,5,6,7,8]; len_array1=len(array1);
echo(array1,len_array1);

array2=[[0,0],[0,1],[1,0],[1,1]]; len_array2=len(array2);
echo(array2,len_array2);

len_array2_2=len(array2[2]);
echo(array2[2],len_array2_2);

结果

WARNING: len() parameter could not be converted in file , line 4
ECHO: "abcdef", 6
ECHO: 6, undef
ECHO: [1, 2, 3, 4, 5, 6, 7, 8], 8
ECHO: [[0, 0], [0, 1], [1, 0], [1, 1]], 4
ECHO: [1, 0], 2

此函数允许(例如)解析数组、向量或字符串。

使用示例

str2="4711";
for (i=[0:len(str2)-1])
	echo(str("digit ",i+1,"  :  ",str2[i]));

结果

ECHO: "digit 1  :  4"
ECHO: "digit 2  :  7"
ECHO: "digit 3  :  1"
ECHO: "digit 4  :  1"

请注意,当将简单变量作为参数传递时,len() 函数未定义并会引发警告。

这在处理模块参数时很有用,类似于形状可以定义为单个数字,也可以定义为 [x,y,z] 向量;即 cube(5) 或 cube([5,5,5])

例如

module doIt(size) {
	if (len(size) == undef) {
		// size is a number, use it for x,y & z. (or could be undef)
		do([size,size,size]);
	} else { 
		// size is a vector, (could be a string but that would be stupid)
		do(size);
	}
 }
 
doIt(5);	// equivalent to [5,5,5]
doIt([5,5,5]);	// similar to cube(5) v's cube([5,5,5])

[注意: 需要版本 2015.03]

在表达式中对变量进行顺序赋值。以下表达式将在 let 赋值的上下文中进行求值,可以使用这些变量。这主要用于通过将中间结果分配给变量来使复杂的表达式更具可读性。

参数

let (var1 = value1, var2 = f(var1), var3 = g(var1, var2)) expression

使用示例

echo(let(a = 135, s = sin(a), c = cos(a)) [ s, c ]); // ECHO: [0.707107, -0.707107]

Let 也可以用于在 函数 中创建变量。 (另请参见:“Let 语句”)

数学 **对数** 以 10 为底。例如:log(1000) = 3。参见:对数

在表中查找值,如果不存在精确匹配,则进行线性插值。第一个参数是要查找的值。第二个是查找表——一个键值对向量。

参数

key
查找键
<key,value> 数组
键和值

存在一个错误,即超出范围的键会返回列表中的第一个值。较新版本的 Openscad 应使用表的顶部或底部作为替代。

**使用示例:** 创建一个由不同高度的圆柱体组成的 3D 图表。

 function get_cylinder_h(p) = lookup(p, [
 		[ -200, 5 ],
 		[ -50, 20 ],
 		[ -20, 18 ],
 		[ +80, 25 ],
 		[ +150, 2 ]
 	]);
 
 for (i = [-100:5:+100]) {
 	// echo(i, get_cylinder_h(i));
 	translate([ i, 0, -30 ]) cylinder(r1 = 6, r2 = 2, h = get_cylinder_h(i)*3);
 }
OpenSCAD Lookup 函数

返回参数的最大值。如果给定一个向量作为参数,则返回该向量的最大元素。

参数

max(n,n{,n}...)
max(vector)
<n>
两个或多个小数
<vector>
单个小数向量 [注意: 需要 2014.06 版本].

使用示例

max(3.0,5.0)
max(8.0,3.0,4.0,5.0)
max([8,3,4,5])

结果

5
8
8

返回参数的最小值。如果给定一个向量作为参数,则返回该向量的最小元素。

参数

min(n,n{,n}...)
min(vector)
<n>
两个或多个小数
<vector>
单个小数向量 [注意: 需要 2014.06 版本].

使用示例

min(3.0,5.0)
min(8.0,3.0,4.0,5.0)
min([8,3,4,5])

结果

3
3
3

仅出于清晰度包含在本文档中。OpenSCAD 中存在“模”运算,作为一个运算符 %,而不是一个函数。参见 模运算符 (%)

返回向量的 欧几里得范数。请注意,这会返回实际的数值长度,而 **len** 会返回向量或数组中的元素数量。

使用示例

a=[1,2,3,4];
b="abcd";
c=[];
d="";
e=[[1,2,3,4],[1,2,3],[1,2],[1]];
echo(norm(a)); //5.47723
echo(norm(b)); //undef
echo(norm(c)); //0
echo(norm(d)); //undef
echo(norm(e[0])); //5.47723
echo(norm(e[1])); //3.74166
echo(norm(e[2])); //2.23607
echo(norm(e[3])); //1

结果

ECHO: 5.47723
ECHO: undef
ECHO: 0
ECHO: undef
ECHO: 5.47723
ECHO: 3.74166
ECHO: 2.23607
ECHO: 1

数学 **幂** 函数。

从 2021.01 版本开始,可以使用 幂运算符 ^ 代替。

参数

<base>
小数。底数。
<exponent>
小数。指数。

使用示例

for (i = [0:5]) {
 translate([i*25,0,0]) {
   cylinder(h = pow(2,i)*5, r=10);
   echo (i, pow(2,i));
 }
}
echo(pow(10,2)); // means 10^2 or 10*10
// result: ECHO: 100

echo(pow(10,3)); // means 10^3 or 10*10*10
// result: ECHO: 1000

echo(pow(125,1/3)); // means 125^(0.333...), which calculates the cube root of 125
// result: ECHO: 5

随机数生成器。生成一个伪随机数的常量向量,非常类似于数组。这些数字是双精度浮点数,而不是整数。当只生成一个数字时,您仍然需要使用 variable[0] 来调用它。

参数

min_value
随机数范围的最小值
max_value
随机数范围的最大值
value_count
要作为向量返回的随机数数量
seed_value(可选)
用于随机数生成器的种子值,以获得可重复的结果。在 2015 年底之前的版本中,seed_value 会四舍五入到最接近的整数

使用示例

// get a single number
single_rand = rands(0,10,1)[0];
echo(single_rand);
// get a vector of 4 numbers
seed=42;
random_vect=rands(5,15,4,seed);
echo( "Random Vector: ",random_vect);
sphere(r=5);
for(i=[0:3]) {
 rotate(360*i/4) {
   translate([10+random_vect[i],0,0])
     sphere(r=random_vect[i]/2);
 }
}
// ECHO: "Random Vector: ", [8.7454, 12.9654, 14.5071, 6.83435]

“round”运算符分别返回最大或最小整数部分,如果数值输入为正或负。

使用示例

round(5.4);
round(5.5);
round(5.6);
round(-5.4);
round(-5.5);
round(-5.6);

结果

5
6
6
-5
-6
-6

数学 **符号** 函数。返回一个单位值,提取值的符号,参见:符号函数

参数

<x>
小数。要查找符号的值。

使用示例

sign(-5.0);
sign(0);
sign(8.0);

结果

-1.0
0.0
1.0

数学 **平方根** 函数。

使用示例
translate([sqrt(100),0,0])sphere(100);

无穷大和小数

[编辑 | 编辑源代码]

OpenSCAD 如何处理 (1/0) 之类的输入?基本上,行为是从 OpenSCAD 所用语言 C++ 语言及其浮点数类型以及相关的 C 数学库继承而来的。此系统允许通过特殊值“Inf”或“-Inf”来表示正无穷大和负无穷大。它还允许将像 sqrt(-1) 或 0/0 这样的内容表示为“NaN”,它是“非数字”的缩写。可以在网上找到解释,例如 Open Group 关于 math.h 的网站维基百科关于 IEEE 754 数字格式的页面。但是,OpenSCAD 是一种独立的语言,因此它可能不完全匹配 C 中发生的所有情况。例如,OpenSCAD 在三角函数中使用度而不是弧度。另一个例子是 sin() 在输入为 1/0 时不会抛出“域错误”,尽管它确实返回 NaN。

以下是一些示例,说明 2015 年底 OpenSCAD 回归测试系统中对 OpenSCAD 数学函数的无穷输入及其结果输出。

0/0: nan sin(1/0): nan asin(1/0): nan ln(1/0): inf round(1/0): inf
-0/0: nan cos(1/0): nan acos(1/0): nan ln(-1/0): nan round(-1/0): -inf
0/-0: nan tan(1/0): nan atan(1/0): 90 log(1/0): inf sign(1/0): 1
1/0: inf ceil(-1/0): -inf atan(-1/0): -90 log(-1/0): nan sign(-1/0): -1
1/-0: -inf ceil(1/0): inf atan2(1/0, -1/0): 135 max(-1/0, 1/0): inf sqrt(1/0): inf
-1/0: -inf floor(-1/0): -inf exp(1/0): inf min(-1/0, 1/0): -inf sqrt(-1/0): nan
-1/-0: inf floor(1/0): inf exp(-1/0): 0 pow(2, 1/0): inf pow(2, -1/0): 0
华夏公益教科书