csdl_shapes.itcl 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. # -----------------------------------*-Tcl-*--------------------------
  2. #
  3. # shapes.itcl
  4. #
  5. # These Incr Tcl classes define the shapes of transmission
  6. # line cross section structures.
  7. #
  8. # Bob Techentin
  9. # January 23, 2000
  10. #
  11. # Copyright 2000-2004 Mayo Foundation. All Rights Reserved.
  12. # $Id: csdl_shapes.itcl,v 1.3 2004/02/09 18:56:01 techenti Exp $
  13. #
  14. # --------------------------------------------------------------------
  15. package require Itcl
  16. package require units
  17. package provide csdl 1.0.1
  18. # --------------------------------------------------------------------
  19. #
  20. # itcl::class Shape
  21. #
  22. # Defines a shape of a structure in a transmission line
  23. # cross section. While we can't exactly declare a
  24. # virtual class, we can document the expected
  25. # functionality of an object of type Shape.
  26. #
  27. # A shape doesn't know _where_ it is, but it does
  28. # know its height and width and color.
  29. #
  30. # Shapes don't do much interesting, but they can accept
  31. # a visitor class which can do interesting things like
  32. # draw them.
  33. #
  34. # options
  35. #
  36. # -color
  37. # Each shape has an intrinsic color, which is defined
  38. # by the object which creates it. Note that some simulators,
  39. # (i.e., BEM MMTL) depend upon color to properly identify
  40. # the type of structure. (blue==ground)
  41. #
  42. # -description
  43. # A text description, set by the creator. This text is
  44. # displayed when the Shape draws itself. The creator
  45. # would typically use this description to display the
  46. # name and/or attributes of the structure.
  47. #
  48. # methods
  49. #
  50. # width
  51. # height
  52. # area
  53. # circumference
  54. # These methods return the width, height, area, or
  55. # circumference of the shape, as a floating point number,
  56. # scaled to the default length units, as defined in the variable
  57. # ::units::default(Length)
  58. #
  59. # These are useful for drawing routines which operate
  60. # on lists of Shapes. Since the caller doesn't know the
  61. # specific gemoetry of any given shape, it can just ask
  62. # the shape for the amount of space that it needs.
  63. #
  64. # --------------------------------------------------------------------
  65. itcl::class Shape {
  66. public variable name ""
  67. public variable color ""
  68. public variable description ""
  69. method accept { visitor x y } {
  70. # Cleverly call a visitor based on our class name
  71. scan [info class] "::%s" myClass
  72. $visitor visit$myClass $this $x $y
  73. }
  74. method width {}
  75. method height {}
  76. method area {}
  77. method circumference {}
  78. }
  79. itcl::class Rectangle {
  80. inherit Shape
  81. public variable width 0.0
  82. public variable height 0.0
  83. constructor {args} {
  84. eval configure $args
  85. }
  86. method width {}
  87. method height {}
  88. method area {}
  89. method circumference {}
  90. }
  91. itcl::class Trapezoid {
  92. inherit Shape
  93. public variable topWidth 0.0
  94. public variable bottomWidth 0.0
  95. public variable height 0.0
  96. constructor {args} {
  97. eval configure $args
  98. }
  99. method width {}
  100. method height {}
  101. method area {}
  102. method circumference {}
  103. }
  104. itcl::class Circle {
  105. inherit Shape
  106. public variable diameter 0.0
  107. constructor {args} {
  108. eval configure $args
  109. }
  110. method width {}
  111. method height {}
  112. method area {}
  113. method circumference {}
  114. }
  115. itcl::class Layer {
  116. inherit Shape
  117. public variable thickness 0.0
  118. constructor {args} {
  119. eval configure $args
  120. }
  121. method width {}
  122. method height {}
  123. method area {}
  124. method circumference {}
  125. }
  126. # --------------------------------------------------------------------
  127. # Rectangle methods
  128. # --------------------------------------------------------------------
  129. itcl::configbody Rectangle::width {check_length $width "width"}
  130. itcl::configbody Rectangle::height {check_length $height "height"}
  131. itcl::body Rectangle::width {} {return [length $width]}
  132. itcl::body Rectangle::height {} {return [length $height]}
  133. itcl::body Rectangle::area {} {
  134. return [expr {[length $width]*[length $height]}]
  135. }
  136. itcl::body Rectangle::circumference {} {
  137. return [expr {2.0*([length $width]+[length $height])}]
  138. }
  139. # --------------------------------------------------------------------
  140. # Trapezoid methods
  141. # --------------------------------------------------------------------
  142. itcl::configbody Trapezoid::topWidth {check_length $topWidth "top width"}
  143. itcl::configbody Trapezoid::bottomWidth {check_length $bottomWidth "bottom width"}
  144. itcl::configbody Trapezoid::height {check_length $height "height"}
  145. itcl::body Trapezoid::width {} {
  146. if {[length $topWidth]>[length $bottomWidth]} {
  147. return [length $topWidth]
  148. } else {
  149. return [length $bottomWidth]
  150. }
  151. }
  152. itcl::body Trapezoid::height {} {return [length $height]}
  153. itcl::body Trapezoid::area {} {
  154. set h [length $height]
  155. set tw [length $topWidth]
  156. set bw [length $bottomWidth]
  157. return [expr {$h * ($tw + $bw)/2.0}]
  158. }
  159. itcl::body Trapezoid::circumference {} {
  160. #
  161. # +-------------+ +
  162. # / \ | h = height
  163. # / \ |
  164. # +-------------------+ +
  165. # +--+ base
  166. set h [length $height]
  167. set tw [length $topWidth]
  168. set bw [length $bottomWidth]
  169. set base [expr {0.5*abs($tw-$bw)}]
  170. set sidelength [expr {sqrt($h*$h + $base*$base)}]
  171. return [expr {$tw + $bw + 2.0*$sidelength}]
  172. }
  173. # --------------------------------------------------------------------
  174. # Circle methods
  175. # --------------------------------------------------------------------
  176. itcl::configbody Circle::diameter {check_length $diameter "diameter"}
  177. itcl::body Circle::width {} {return [length $diameter]}
  178. itcl::body Circle::height {} {return [length $diameter]}
  179. itcl::body Circle::area {} {
  180. set pi 3.14159265358979323846
  181. set d [length $diameter]
  182. return [expr {$pi * $d*$d / 4.0}]
  183. }
  184. itcl::body Circle::circumference {} {
  185. set pi 3.14159265358979323846
  186. set d [length $diameter]
  187. return [expr {$pi * $d}]
  188. }
  189. # --------------------------------------------------------------------
  190. # Layer methods
  191. # --------------------------------------------------------------------
  192. itcl::configbody Layer::thickness {check_length $thickness "thickness"}
  193. itcl::body Layer::width {} {
  194. # as far as anybody checking on the width of all the
  195. # cross section structures is concerned, the layer
  196. # width is 2x the thickness. But we draw it "wide"
  197. # when compared to the width of all the other layers
  198. # and structures.
  199. return [expr {[length $thickness]*2}]
  200. }
  201. itcl::body Layer::height {} {return [length $thickness]}
  202. set ::units::default(Length) meter
  203. set ::units::default(Time) second
  204. proc check_length { value name } {
  205. global units::default
  206. if { $value == "" } {
  207. error "'$name' value is required"
  208. }
  209. if { [catch {units::convert $value $units::default(Length)} result] } {
  210. error "Invalid Dimension '$name': $result"
  211. }
  212. if { $result < 0.0 } {
  213. error "Invalid '$name': Negative dimensions are not allowed"
  214. }
  215. }
  216. proc length { value } {
  217. # add default units, if necessary
  218. if { [string is double $value] } {
  219. append value $units::default(Length)
  220. }
  221. units::convert $value $units::default(Length)
  222. }
  223. proc time { value } {
  224. # add default units, if necessary
  225. if { [string is double $value] } {
  226. append value $units::default(Time)
  227. }
  228. units::convert $value $units::default(Time)
  229. }