You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将计算结果添加到二维列表?Lisp球顶点坐标生成问题

解决Common Lisp中球体顶点坐标表达式未求值的问题

你的问题出在单引号'的引用行为上:Lisp里单引号会阻止列表内的表达式求值,所以'(0 (sin (/ pi 6)) (cos (/ pi 6)))会直接保留sin、cos这些符号,而不会计算它们的结果。

直接解决方案:用list函数替代单引号列表

list函数会对每个传入的参数求值,再将结果组合成列表,这正是你需要的:

(setf (elt sphereverticeslist 1)
      (list 0 (sin (/ pi 6)) (cos (/ pi 6))))

执行后,这个位置的元素会变成(0 0.5 0.8660254)(近似值),符合预期。

批量生成顶点的完整示例

如果要生成所有球体顶点,可以用循环批量计算,避免逐个手动设置:

(defvar spherelatamount 7)
(defvar spherelonamount 8)
(defparameter sphereverticeslist
  (make-list (+ 2 (* (- spherelatamount 2) spherelonamount))))

;; 设置北极点
(setf (elt sphereverticeslist 0) '(0 0 1))

;; 生成中间纬度层的所有顶点
(loop for lat-index from 1 to (- spherelatamount 2)
      ;; 计算当前纬度的极角(从北极点向下)
      for polar-angle = (* pi (/ lat-index spherelatamount))
      do (loop for lon-index from 0 to (- spherelonamount 1)
               ;; 计算当前顶点在列表中的索引
               for vertex-index = (+ 1 (* (- lat-index 1) spherelonamount) lon-index)
               ;; 计算球坐标转笛卡尔坐标的三个分量
               for x = (* (sin polar-angle) (cos (* 2 pi (/ lon-index spherelonamount))))
               for y = (* (sin polar-angle) (sin (* 2 pi (/ lon-index spherelonamount))))
               for z = (cos polar-angle)
               ;; 用list求值后存入列表
               do (setf (elt sphereverticeslist vertex-index) (list x y z))))

;; 设置南极点
(setf (elt sphereverticeslist (1- (length sphereverticeslist))) '(0 0 -1))

补充:准引用的替代方式

如果遇到需要部分元素保留字面量、部分求值的场景,可以用**反引号 **配合逗号, 强制求值单个元素(不过这个场景下没必要,仅作拓展):

(setf (elt sphereverticeslist 1)
      `(0 ,(sin (/ pi 6)) ,(cos (/ pi 6))))

逗号会让后面的表达式被求值,其余部分保留字面量。

内容的提问来源于stack exchange,提问作者nadirkazan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 17:05:22