我正在使用一个使用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次,并手动更改...?我有点想知道如何处理变化的入射角度,但不知道文件名的变化。
提前致谢。
答案 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)
您可以应用其他技巧来使程序更灵活,但目前,上述代码应该让您走上正轨。快乐的计划!