2017-07-08 2 views
0

Je veux passer la sortie d'une procédure qui est une liste en tant qu'argument à une autre procédure. Voici un code que j'ai essayé.Comment passer la sortie d'une procédure en tant qu'argument à une autre procédure en tcl

proc distance {n1 n2 nd1 nd2} { 
    set x1 [expr int([$n1 set X_])] 
    set y1 [expr int([$n1 set Y_])] 
    set x2 [expr int([$n2 set X_])] 
    set y2 [expr int([$n2 set Y_])] 

    set d [expr hypot($x2-$x1,$y2-$y1)] 

    return [list $nd1 $nd2 $x1 $y1 $x2 $y2 $d] 
} 


proc processDistances {count threshold {filter ""}} { 

global node_ 


    set distances {} 
    for {set i 1} {$i < $count} {incr i} { 
     for {set j 1} {$j < $count} {incr j} { 
      # Skip self comparisons 
      if {$i == $j} continue 

      # Apply target filter 
      if {$filter ne "" && $j != $filter} continue 

      # Get the distance information 
      set thisDistance [distance $node_($i) $node_($j) $i $j] 

      # Check that the nodes are close enough 
      if {[lindex $thisDistance 6] < $threshold} { 
       lappend distances $thisDistance 
      } 
     } 
    } 

    # Sort the pairs, by distances 

    set distances [lsort -real -increasing -index 6 $distances] 

Inverse2 {*}$distances 
} 
$ns at 8.5 [list processDistances $val(nn) 200 41] 

proc Inverse2 {m} { 

set result [open R.tr w] 

lassign [lindex $m 0 2] x1 
lassign [lindex $m 0 3] y1 
lassign [lindex $m 0 4] d1 
lassign [lindex $m 1 2] x2 
lassign [lindex $m 1 3] y2 
lassign [lindex $m 1 4] d2 
lassign [lindex $m 2 2] x3 
lassign [lindex $m 2 3] y3 
lassign [lindex $m 2 4] d3 

set mt {{? ?} {? ?}} 
lset mt 0 0 [expr 2*($x1-$x2)] 
lset mt 0 1 [expr 2*($y1-$y2)] 
lset mt 1 0 [expr 2*($x1-$x3)] 
lset mt 1 1 [expr 2*($y1-$y3)] 
set const {{?} {?}} 
lset const 0 [expr {(pow($x1,2)+pow($y1,2)-pow($d1,2))-(pow($x2,2)+pow($y2,2)-pow($d2,2))}] 
lset const 1 [expr {(pow($x1,2)+pow($y1,2)-pow($d1,2))-(pow($x3,2)+pow($y3,2)-pow($d3,2))}] 

set x [expr {double([lindex [Inverse3 $mt] 0 0] * [lindex $const 0] 
        + [lindex [Inverse3 $mt] 0 1] * [lindex $const 1])}] 
set y [expr {double([lindex [Inverse3 $mt] 1 0] * [lindex $const 0] 
        + [lindex [Inverse3 $mt] 1 1] * [lindex $const 1])}] 

puts $result "x location of object is: $x \ny location of object is: $y" 

} 

Erreur:

ns: processDistances 42 200 41: wrong # args: should be "Inverse2 m" 
    while executing 
"Inverse2 {*} $distances" 
    (procedure "processDistances" line 32) 
    invoked from within 
"processDistances 42 200 41" 

Je reçois la sortie de proc processDistances avec succès ce qui est une liste triée mais quand je passe cette sortie à procedure Inverse2 en utilisant la commande Inverse2 {*}$distances écrite en processDistances (je tcl8.5) Je suis au-dessus de l'erreur. Où je me trompe. S'il vous plaît, aidez-moi.

+0

Vous avez réussi à générer l'erreur que vous avez affichée. Puis appliqué cette correction pour l'aller plus loin. Mais il génère des erreurs après cela parce que les lassigns définissent les variables x1, y1 pour les chaînes vides. Changement de clé: 'Inverse2 $ distances' –

+0

@Ron Norris Je veux que' $ distances' prenne place de "m" qui est l'argument de 'proc Inverse2' et ensuite il devrait extraire la valeur d'index de' $ distances' et 'lassign' dans 'proc Inverse2' –

+0

En appelant' Inverse2 $ distances', il passe la variable de la liste des distances à la procédure Inverse2 (à la place de "m"). N'est-ce pas ce que tu voulais? Si vous voulez qu'il soit passé par référence, vous pouvez le faire aussi. –

Répondre

0

Je vous suggère de l'exécuter comme je l'ai remplacé. Si cela ne fonctionne pas, je ne suis pas sûr de ce que vous demandez.

proc distance {n1 n2 nd1 nd2} { 
    set x1 [expr int([$n1 set X_])] 
    set y1 [expr int([$n1 set Y_])] 
    set x2 [expr int([$n2 set X_])] 
    set y2 [expr int([$n2 set Y_])] 

    set d [expr hypot($x2-$x1,$y2-$y1)] 

    return [list $nd1 $nd2 $x1 $y1 $x2 $y2 $d] 
} 


proc processDistances {count threshold {filter ""}} { 

global node_ 


    set distances {} 
    for {set i 1} {$i < $count} {incr i} { 
     for {set j 1} {$j < $count} {incr j} { 
      # Skip self comparisons 
      if {$i == $j} continue 

      # Apply target filter 
      if {$filter ne "" && $j != $filter} continue 

      # Get the distance information 
      set thisDistance [distance $node_($i) $node_($j) $i $j] 

      # Check that the nodes are close enough 
      if {[lindex $thisDistance 6] < $threshold} { 
       lappend distances $thisDistance 
      } 
     } 
    } 

    # Sort the pairs, by distances 

    set distances [lsort -real -increasing -index 6 $distances] 

#Inverse2 {*}$distances 
Inverse2 $distances 
} 
$ns at 8.5 [list processDistances $val(nn) 200 41] 

proc Inverse2 {m} { 

set result [open R.tr w] 

lassign [lindex $m 0 2] x1 
lassign [lindex $m 0 3] y1 
lassign [lindex $m 0 4] d1 
lassign [lindex $m 1 2] x2 
lassign [lindex $m 1 3] y2 
lassign [lindex $m 1 4] d2 
lassign [lindex $m 2 2] x3 
lassign [lindex $m 2 3] y3 
lassign [lindex $m 2 4] d3 

set mt {{? ?} {? ?}} 
lset mt 0 0 [expr 2*($x1-$x2)] 
lset mt 0 1 [expr 2*($y1-$y2)] 
lset mt 1 0 [expr 2*($x1-$x3)] 
lset mt 1 1 [expr 2*($y1-$y3)] 
set const {{?} {?}} 
lset const 0 [expr {(pow($x1,2)+pow($y1,2)-pow($d1,2))-(pow($x2,2)+pow($y2,2)-pow($d2,2))}] 
lset const 1 [expr {(pow($x1,2)+pow($y1,2)-pow($d1,2))-(pow($x3,2)+pow($y3,2)-pow($d3,2))}] 

set x [expr {double([lindex [Inverse3 $mt] 0 0] * [lindex $const 0] 
        + [lindex [Inverse3 $mt] 0 1] * [lindex $const 1])}] 
set y [expr {double([lindex [Inverse3 $mt] 1 0] * [lindex $const 0] 
        + [lindex [Inverse3 $mt] 1 1] * [lindex $const 1])}] 

puts $result "x location of object is: $x \ny location of object is: $y" 

} 
+0

Il est généralement utile de localiser vos modifications sans réduire les parties non pertinentes du code. –