我是TCL的初学者。我试图使用事先计算的列表作为过程的参数。结果我得到了#34;无效的命令名称"。这是代码,我错在哪里?
proc matrix_to_quaternion { matrix_VMD } {
set q1 [expr { 0.5*sqrt(1+[lindex $matrix_VMD 0 0]+[lindex $matrix_VMD 1 1]+[lindex $matrix_VMD 2 2]) }]
set q2 [expr (1/(4*$q1))*([lindex $matrix_VMD 2 1]-[lindex $matrix_VMD 1 2])]
set q3 [expr (1/(4*$q1))*([lindex $matrix_VMD 0 2]-[lindex $matrix_VMD 2 0])]
set q4 [expr (1/(4*$q1))*([lindex $matrix_VMD 1 0]-[lindex $matrix_VMD 0 1])]
puts q1 q2 q3 q4
}
答案 0 :(得分:0)
要返回复合值(而不是将其打印出来),您应该使用以下内容:
return [list $q1 $q2 $q3 $q4]
我们使用$
因为我们想要那些局部变量中的值,而不是它们的名称。你还应该在所有表达式周围放置{
大括号}
,因为这样可以防止双插值,并允许Tcl编译代码以加快速度。这是正确的版本:
proc matrix_to_quaternion { matrix_VMD } {
set q1 [expr { 0.5*sqrt(1+[lindex $matrix_VMD 0 0]+[lindex $matrix_VMD 1 1]+[lindex $matrix_VMD 2 2]) }]
set q2 [expr { (1/(4*$q1))*([lindex $matrix_VMD 2 1]-[lindex $matrix_VMD 1 2]) }]
set q3 [expr { (1/(4*$q1))*([lindex $matrix_VMD 0 2]-[lindex $matrix_VMD 2 0]) }]
set q4 [expr { (1/(4*$q1))*([lindex $matrix_VMD 1 0]-[lindex $matrix_VMD 0 1]) }]
return [list $q1 $q2 $q3 $q4]
}
除此之外,您的代码片段不太可能产生具有合理输入数据的错误消息。除非您使用如下代码序列调用代码:
[matrix_to_quaternion $someInput]
在这种情况下,您可以将通话结果用作单词;命令的第一个单词是命令的名称,以及您返回的内容(以及应该在正确的代码中返回的内容)不是命令的名称。这让Tcl抱怨你。 Tcl通常会小心翼翼地试图向您提供有关它认为错误的信息(不仅仅是“未知命令”,而是“未知命令" BLAH" ”)帮助很多。
你给我们的代码让我有些困惑。它不像我们希望的那么清晰。这是我使用的(相同的算法),因为我也知道lassign
命令......
proc matrix_to_quaternion { matrix_VMD } {
lassign $matrix_VMD m0 m1 m2
set q1 [expr { 0.5*sqrt(1 + [lindex $m0 0] + [lindex $m1 1] + [lindex $m2 2]) }]
set q2 [expr { 0.25/$q1 * ([lindex $m2 1] - [lindex $m1 2]) }]
set q3 [expr { 0.25/$q1 * ([lindex $m0 2] - [lindex $m2 0]) }]
set q4 [expr { 0.25/$q1 * ([lindex $m1 0] - [lindex $m0 1]) }]
return [list $q1 $q2 $q3 $q4]
}
我测试时速度也更快(在我的答案中,它占用了早期版本的60%左右,并且在修正后返回列表时比你的快8倍;支撑表达式使得重大差异),但我的担忧完全与使代码更清晰。