PAYATHON 2026

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 没有被预先赋值为其他表达式。

备注:内容仅供参考。