patternMinor
Calculating positions along the edges of a rectangle
Viewed 0 times
positionstheedgesrectanglecalculatingalong
Problem
I had the following three Tcl procedures, which calculate positions along three edges of a rectangle:
Since the code for each of the procedures is almost identical, I decided to write a single generalized procedure and three specializations of it.
I had some difficulties with generalizing the fact that the
Here is the solution I came up with:
```
#---- Numbered pins at the top ---------------------------------------
proc setNumberedTopPins {xRight y pins} {
setNumberedPins Top 2 $xRight $y $pins
}
#---- Numbered pins at the right -------------------------------------
proc setNumberedRi
#---- Numbered pins at the top ---------------------------------------
# Given a list of triplets (number, name, index), place the pins for the
# signals "name" along the top edge, positioned vertically at 'y'
# and horizontally at 'number' times a constant space left of 'xRight'
# (plus an arbitrary offset of 2).
proc setNumberedTopPins {xRight y pins} {
set padWidth 95
foreach {number name index} $pins {
set xOffset [expr $number * $padWidth + 2]
setPin $name [expr $xRight-$xOffset] $y Top $index
}
}
#---- Numbered pins at the right -------------------------------------
# The same for the right edge.
proc setNumberedRightPins {x yTop pins} {
set padWidth 95
foreach {number name index} $pins {
set yOffset [expr max(0, $number * $padWidth - 2.5)]
setPin $name $x [expr $yTop-$yOffset] Right $index
}
}
#---- Numbered pins at the bottom ------------------------------------
# The same for the bottom edge.
proc setNumberedBottomPins {xRight y pins} {
set padWidth 95
foreach {number name index} $pins {
set xOffset [expr $number * $padWidth + 2]
setPin $name [expr $xRight-$xOffset] $y Bottom $index
}
}Since the code for each of the procedures is almost identical, I decided to write a single generalized procedure and three specializations of it.
I had some difficulties with generalizing the fact that the
offset is sometimes applied to the second (x) and sometimes to the third (y) argument of setPin. I wanted to make sure that this decision is only taken once, outside the foreach loop.Here is the solution I came up with:
```
#---- Numbered pins at the top ---------------------------------------
proc setNumberedTopPins {xRight y pins} {
setNumberedPins Top 2 $xRight $y $pins
}
#---- Numbered pins at the right -------------------------------------
proc setNumberedRi
Solution
I would suggest that since only 2 of the procs are close enough to identical, just "combine" those:
Notes:
set padWidth 95
proc setNumberedRightPins {x yTop pins} {
foreach {number name index} $pins {
set yOffset [expr {max(0, $number * $::padWidth - 2.5)}]
setPin $name $x [expr {$yTop-$yOffset}] Right $index
}
}
proc setNumberedTopPins {args} {
setNumberedTopOrBottomPins {*}$args Top
}
proc setNumberedBottomPins {args} {
setNumberedTopOrBottomPins {*}$args Bottom
}
proc setNumberedTopOrBottomPins {xRight y pins side} {
foreach {number name index} $pins {
set xOffset [expr {$number * $::padWidth + 2}]
setPin $name [expr {$xRight-$xOffset}] $y $side $index
}
}Notes:
- always brace your expressions, gain a big performance boost
- constants can live in the global namespace, and you access them with a fully qualified variable name
Code Snippets
set padWidth 95
proc setNumberedRightPins {x yTop pins} {
foreach {number name index} $pins {
set yOffset [expr {max(0, $number * $::padWidth - 2.5)}]
setPin $name $x [expr {$yTop-$yOffset}] Right $index
}
}
proc setNumberedTopPins {args} {
setNumberedTopOrBottomPins {*}$args Top
}
proc setNumberedBottomPins {args} {
setNumberedTopOrBottomPins {*}$args Bottom
}
proc setNumberedTopOrBottomPins {xRight y pins side} {
foreach {number name index} $pins {
set xOffset [expr {$number * $::padWidth + 2}]
setPin $name [expr {$xRight-$xOffset}] $y $side $index
}
}Context
StackExchange Code Review Q#87774, answer score: 3
Revisions (0)
No revisions yet.