方案:如何创建一个将数据保存到具有不同名称的文件的循环?

时间:2014-08-10 18:00:34

标签: loops scheme raytracing

我正在使用一个使用Scheme的程序(TracePro),我没有那么多使用过。我想创建一个代码来更改一些初始值,运行模拟,然后将结果数据表保存到文件,然后再次更改值,运行模拟,保存数据等90次。我到目前为止创建的代码:

(raytrace:set-beam-orientation-euler-degrees (gvector 0 90 -90))
(raytrace:grid)
(edit:select (car (cdr (entity:faces (entity 12)))))
(analysis:incident)
(analysis:incident-save "C:/Users/Admin/Desktop/testdata/incident0.csv" "csv")

有没有办法创建一个循环来运行这段代码,具有不同的入射角度,从0到90,以及不同的文件名,从incident0.csv一直到incident90.csv,而不必复制代码90次,并手动更改...?我有点想知道如何处理变化的入射角度,但不知道文件名的变化。

提前致谢。

1 个答案:

答案 0 :(得分:4)

我不知道TracePro的细节,但在任何Scheme程序中,您都可以使用递归循环。首先,我们必须重构代码中的部分,这些部分会更改并使其成为参数,并将代码封装在函数中。我不确定哪个值应该是入射角度,请根据需要进行调整:

(define (run-simulation angle)
  (raytrace:set-beam-orientation-euler-degrees
   (gvector angle 90 -90)) ; assuming that the first parameter is the angle
  (raytrace:grid)
  (edit:select
   (car (cdr (entity:faces (entity 12)))))
  (analysis:incident)
  (analysis:incident-save
   (string-append          ; this is how we can dynamically create file names
    "C:/Users/Admin/Desktop/testdata/incident"
    (number->string angle)
    ".csv")
   "csv"))

通过上述程序,可以轻松循环,根据需要多次调用。注意我们如何使用递归的基本情况来停止,以及在递归步骤中我们如何递增当前值:

(define (loop init end)
  (cond ((> init end) 'done)      ; base case of recursion
        (else                     ; otherwise
         (run-simulation init)    ; call the previous procedure
         (loop (+ init 1) end)))) ; advance recursion

现在我们只需要在调用循环时提供适当的启动和停止参数:

(loop 0 90)

如果我们对它很聪明,我们可以将相同的循环过程重用于其他目的,请注意,唯一可能改变的是被调用的过程 - 所以我们也可以将它作为参数传递!

(define (loop func init end)
  (cond ((> init end) 'done)
        (else
         (func init)
         (loop func (+ init 1) end))))

(loop run-simulation 0 90)

您可以应用其他技巧来使程序更灵活,但目前,上述代码应该让您走上正轨。快乐的计划!