Index: modules/math/geometry.tcl ================================================================== --- modules/math/geometry.tcl +++ modules/math/geometry.tcl @@ -12,10 +12,11 @@ # # RCS: @(#) $Id: geometry.tcl,v 1.12 2010/05/24 21:44:16 andreas_kupries Exp $ namespace eval ::math::geometry {} +package require Tcl 8.5 package require math ### # # POINTS @@ -58,38 +59,35 @@ return [list $x $y] } # Vector addition proc ::math::geometry::+ {pa pb} { - foreach {ax ay} $pa break - foreach {bx by} $pb break + lassign $pa ax ay; lassign $pb bx by return [list [expr {$ax + $bx}] [expr {$ay + $by}]] } # Vector difference proc ::math::geometry::- {pa pb} { - foreach {ax ay} $pa break - foreach {bx by} $pb break + lassign $pa ax ay; lassign $pb bx by return [list [expr {$ax - $bx}] [expr {$ay - $by}]] } # Distance between 2 points proc ::math::geometry::distance {pa pb} { - foreach {ax ay} $pa break - foreach {bx by} $pb break + lassign $pa ax ay; lassign $pb bx by return [expr {hypot($bx-$ax,$by-$ay)}] } # Length of a vector proc ::math::geometry::length {v} { - foreach {x y} $v break + lassign $v x y return [expr {hypot($x,$y)}] } # Scaling a vector by a factor proc ::math::geometry::s* {factor p} { - foreach {x y} $p break + lassign $p x y return [list [expr {$x * $factor}] [expr {$y * $factor}]] } # Unit vector into specific direction given by angle (degrees) proc ::math::geometry::direction {angle} { @@ -116,11 +114,11 @@ } # Find direction octant the point (vector) lies in. proc ::math::geometry::octant {p} { variable todeg - foreach {x y} $p break + lassign $p x y set a [expr {(atan2(-$y,$x)*$todeg)}] while {$a > 360} {set a [expr {$a - 360}]} while {$a < -360} {set a [expr {$a + 360}]} if {$a < 0} {set a [expr {360 + $a}]} @@ -148,39 +146,36 @@ } } # Return the NW and SE corners of the rectangle. proc ::math::geometry::nwse {rect} { - foreach {xnw ynw xse yse} $rect break + lassign $rect xnw ynw xse yse return [list [p $xnw $ynw] [p $xse $yse]] } # Construct rectangle from NW and SE corners. proc ::math::geometry::rect {pa pb} { - foreach {ax ay} $pa break - foreach {bx by} $pb break + lassign $pa ax ay; lassign $pb bx by return [list $ax $ay $bx $by] } proc ::math::geometry::conjx {p} { - foreach {x y} $p break + lassign $p x y return [list [expr {- $x}] $y] } proc ::math::geometry::conjy {p} { - foreach {x y} $p break + lassign $p x y return [list $x [expr {- $y}]] } proc ::math::geometry::x {p} { - foreach {x y} $p break - return $x + return [lindex $p 0] } proc ::math::geometry::y {p} { - foreach {x y} $p break - return $y + return [lindex $p 1] } # ::math::geometry::calculateDistanceToLine # # Calculate the distance between a point and a line. @@ -198,11 +193,11 @@ # - calculateDistanceToLine {-10 0} {0 0 10 10} # Result: 7.07106781187 # proc ::math::geometry::calculateDistanceToLine {P line} { # solution based on FAQ 1.02 on comp.graphics.algorithms - # L = sqrt( (Bx-Ax)^2 + (By-Ay)^2 ) + # L = hypot( Bx-Ax, By-Ay ) # (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay) # s = ----------------------------- # L^2 # dist = |s|*L # @@ -218,11 +213,11 @@ set Cx [lindex $P 0] set Cy [lindex $P 1] if {$Ax==$Bx && $Ay==$By} { return [lengthOfPolyline [concat $P [lrange $line 0 1]]] } else { - set L [expr {sqrt(pow($Bx-$Ax,2) + pow($By-$Ay,2))}] + set L [expr {hypot($Bx-$Ax,$By-$Ay)}] return [expr {abs(($Ay-$Cy)*($Bx-$Ax)-($Ax-$Cx)*($By-$Ay)) / $L}] } } # ::math::geometry::findClosestPointOnLine @@ -265,12 +260,13 @@ # r<0 P is on the backward extension of AB # r>1 P is on the forward extension of AB # 01 P is on the forward extension of AB # 0