Maxima draw3d 中子程序内的 transform 为什么不生效?
数据小陈
让 sphere 返回一个包含 transform = [...] 和 spherical(...) 的列表。原代码中的 block 只返回最后一个表达式 spherical(...),因此 draw3d 没有收到平移选项。
为什么放在子程序里没有效果?
原函数的主体是两个依次求值的表达式:
transform = [x+coords[1], y+coords[2], z+coords[3], x, y, z],
spherical(radius,a,0,2*%pi,z1,0,%pi)
如果没有提前返回,block 会以最后一个表达式的值作为返回值。因此,调用 sphere(r1,c1) 时,返回的只有 spherical(3,a,0,2*%pi,z1,0,%pi),不包含前面的 transform 等式。这符合 Maxima 的 block 返回规则。
transform = [...] 是由绘图函数解释的选项表达式。在普通 block 中对它求值,不会自动修改外层绘图场景。把平移量写成固定数值也一样。
修改函数,让选项和球面一起返回
可以去掉 block,直接返回列表:
load(draw)$
r1: 3$
c1: [10,10,10]$
r2: 4$
c2: [5,5,5]$
sphere(radius,coords) := [
transform = [
x+coords[1],
y+coords[2],
z+coords[3],
x, y, z
],
spherical(radius,a,0,2*%pi,z1,0,%pi)
]$
draw3d(
color = blue,
opacity = 0.1,
sphere(r1,c1),
color = orange,
opacity = 0.1,
sphere(r2,c2)
)$
draw3d 对应的三维场景构造器支持用列表传入绘图选项和图形对象,并按顺序处理它们。因此,列表中的平移选项可以作用于紧随其后的球面。参见 Maxima draw 文档。
按代码定义,第一个球面的半径为 3、球心为 [10,10,10];第二个球面的半径为 4、球心为 [5,5,5]。这是代码表达的预期结果,未在此运行绘图验证。
如果还需要使用 block
如果后续要增加局部计算,可以保留 block,但最后必须返回整个列表:
sphere(radius,coords) := block([],
[
transform = [
x+coords[1],
y+coords[2],
z+coords[3],
x, y, z
],
spherical(radius,a,0,2*%pi,z1,0,%pi)
]
)$
原定义中的局部变量 t 没有使用,可以删除。
使用时注意什么?
- 保留
transform = [...]中的等号。改成赋值符号:不能解决选项没有传入绘图场景的问题。 transform应放在需要变换的图形对象之前。- 返回列表只用于组织场景参数,不会建立独立的选项作用域。如果后面还有其他图形,需按需要重新指定
transform;可以用transform = [x,y,z,x,y,z]恢复恒等变换。 - 示例假定
coords是包含三个坐标的列表,且x、y、z、a、z1没有被预先赋值为其他表达式。
备注:内容仅供参考。
