test_pysketcher.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. from pysketcher import *
  2. def test_Axis():
  3. drawing_tool.set_coordinate_system(
  4. xmin=0, xmax=15, ymin=-7, ymax=8, axis=True,
  5. instruction_file='tmp_Axis.py')
  6. # Draw normal x and y axis with origin at (7.5, 2)
  7. # in the coordinate system of the sketch: [0,15]x[-7,8]
  8. x_axis = Axis((7.5,2), 5, 'x', rotation_angle=0)
  9. y_axis = Axis((7.5,2), 5, 'y', rotation_angle=90)
  10. system = Composition({'x axis': x_axis, 'y axis': y_axis})
  11. system.draw()
  12. drawing_tool.display()
  13. # Rotate this system 40 degrees counter clockwise
  14. # and draw it with dashed lines
  15. system.set_linestyle('dashed')
  16. system.rotate(40, (7.5,2))
  17. system.draw()
  18. drawing_tool.display()
  19. # Rotate this system another 220 degrees and show
  20. # with dotted lines
  21. system.set_linestyle('dotted')
  22. system.rotate(220, (7.5,2))
  23. system.draw()
  24. drawing_tool.display()
  25. drawing_tool.display('Axis')
  26. drawing_tool.savefig('tmp_Axis')
  27. expected = {
  28. 'x axis': {
  29. 'arrow': {
  30. 'head left': {'line': "2 (x,y) coords linestyle='dotted'",},
  31. 'line': {'line': "2 (x,y) coords linestyle='dotted'",},
  32. 'head right': {'line': "2 (x,y) coords linestyle='dotted'",},},
  33. 'label': "Text at (6.57388,-3.25231)",},
  34. 'y axis': {
  35. 'arrow': {
  36. 'head left': {'line': "2 (x,y) coords linestyle='dotted'",},
  37. 'line': {'line': "2 (x,y) coords linestyle='dotted'",},
  38. 'head right': {'line': "2 (x,y) coords linestyle='dotted'",},},
  39. 'label': "Text at (12.7523,1.07388)",},}
  40. msg = 'expected=%s, a=%s' % (expected, eval(repr(system)))
  41. assert eval(repr(system)) == expected, msg
  42. def test_Distance_wText():
  43. drawing_tool.set_coordinate_system(
  44. xmin=0, xmax=10, ymin=0, ymax=6,
  45. axis=True, instruction_file='tmp_Distance_wText.py')
  46. fontsize=14
  47. t = r'$ 2\pi R^2 $' # sample text
  48. examples = Composition({
  49. 'a0': Distance_wText((4,5), (8, 5), t, fontsize),
  50. 'a6': Distance_wText((4,5), (4, 4), t, fontsize),
  51. 'a1': Distance_wText((0,2), (2, 4.5), t, fontsize),
  52. 'a2': Distance_wText((0,2), (2, 0), t, fontsize),
  53. 'a3': Distance_wText((2,4.5), (0, 5.5), t, fontsize),
  54. 'a4': Distance_wText((8,4), (10, 3), t, fontsize,
  55. text_spacing=-1./60),
  56. 'a5': Distance_wText((8,2), (10, 1), t, fontsize,
  57. text_spacing=-1./40, alignment='right'),
  58. 'c1': Text_wArrow('text_spacing=-1./60',
  59. (4, 3.5), (9, 3.2),
  60. fontsize=10, alignment='left'),
  61. 'c2': Text_wArrow('text_spacing=-1./40, alignment="right"',
  62. (4, 0.5), (9, 1.2),
  63. fontsize=10, alignment='left'),
  64. })
  65. examples.draw()
  66. drawing_tool.display('Distance_wText and text positioning')
  67. drawing_tool.savefig('tmp_Distance_wText')
  68. expected = {
  69. 'a1': {
  70. 'text': "Text at (1.13014,3.14588)",
  71. 'arrow': {
  72. 'arrow': {
  73. 'line': "2 (x,y) coords linecolor='k' linewidth=1 arrow='<->'",},},},
  74. 'a0': {
  75. 'text': "Text at (6,5.16667)",
  76. 'arrow': {'arrow': {
  77. 'line': "2 (x,y) coords linecolor='k' linewidth=1 arrow='<->'",},},},
  78. 'a3': {
  79. 'text': "Text at (1.07454,5.14907)",
  80. 'arrow': {'arrow': {
  81. 'line': "2 (x,y) coords linecolor='k' linewidth=1 arrow='<->'",},},},
  82. 'a2': {
  83. 'text': "Text at (1.11785,1.11785)",
  84. 'arrow': {'arrow': {
  85. 'line': "2 (x,y) coords linecolor='k' linewidth=1 arrow='<->'",},},},
  86. 'a5': {
  87. 'text': "Text at (8.8882,1.27639)",
  88. 'arrow': {'arrow': {
  89. 'line': "2 (x,y) coords linecolor='k' linewidth=1 arrow='<->'",},},},
  90. 'a4': {
  91. 'text': "Text at (8.92546,3.35093)",
  92. 'arrow': {'arrow': {
  93. 'line': "2 (x,y) coords linecolor='k' linewidth=1 arrow='<->'",},},},
  94. 'a6': {
  95. 'text': "Text at (4.16667,4.5)",
  96. 'arrow': {'arrow': {
  97. 'line': "2 (x,y) coords linecolor='k' linewidth=1 arrow='<->'",},},},
  98. 'c2': "Text_wArrow at (4,0.5)",
  99. 'c1': "Text_wArrow at (4,3.5)",
  100. }
  101. msg = 'expected=%s, a=%s' % (expected, eval(repr(examples)))
  102. assert eval(repr(examples)) == expected, msg
  103. def test_Rectangle():
  104. L = 3.0
  105. W = 4.0
  106. drawing_tool.set_coordinate_system(
  107. xmin=0, xmax=2*W, ymin=-L/2, ymax=2*L,
  108. axis=True, instruction_file='tmp_Rectangle.py')
  109. drawing_tool.set_linecolor('blue')
  110. drawing_tool.set_grid(True)
  111. xpos = W/2
  112. r = Rectangle(lower_left_corner=(xpos,0), width=W, height=L)
  113. r.draw()
  114. r.draw_dimensions()
  115. drawing_tool.display('Rectangle')
  116. drawing_tool.savefig('tmp_Rectangle')
  117. expected = {'rectangle': "5 (x,y) coords",}
  118. msg = 'expected=%s, a=%s' % (expected, eval(repr(r)))
  119. assert eval(repr(r)) == expected, msg
  120. def test_Triangle():
  121. L = 3.0
  122. W = 4.0
  123. drawing_tool.set_coordinate_system(
  124. xmin=0, xmax=2*W, ymin=-L/2, ymax=1.2*L,
  125. axis=True, instruction_file='tmp_Triangle.py')
  126. drawing_tool.set_linecolor('blue')
  127. drawing_tool.set_grid(True)
  128. xpos = 1
  129. t = Triangle(p1=(W/2,0), p2=(3*W/2,W/2), p3=(4*W/5.,L))
  130. t.draw()
  131. t.draw_dimensions()
  132. drawing_tool.display('Triangle')
  133. drawing_tool.savefig('tmp_Triangle')
  134. expected = {'triangle': "4 (x,y) coords",}
  135. msg = 'expected=%s, a=%s' % (expected, eval(repr(t)))
  136. assert eval(repr(t)) == expected, msg
  137. def test_Arc():
  138. L = 4.0
  139. W = 4.0
  140. drawing_tool.set_coordinate_system(
  141. xmin=-W/2, xmax=W, ymin=-L/2, ymax=1.5*L,
  142. axis=True, instruction_file='tmp_Arc.py')
  143. drawing_tool.set_linecolor('blue')
  144. drawing_tool.set_grid(True)
  145. center = point(0,0)
  146. radius = L/2
  147. start_angle = 60
  148. arc_angle = 45
  149. a = Arc(center, radius, start_angle, arc_angle)
  150. a.draw()
  151. R1 = 1.25*radius
  152. R2 = 1.5*radius
  153. R = 2*radius
  154. a.dimensions = {
  155. 'start_angle':
  156. Arc_wText(
  157. 'start_angle', center, R1, start_angle=0,
  158. arc_angle=start_angle, text_spacing=1/10.),
  159. 'arc_angle':
  160. Arc_wText(
  161. 'arc_angle', center, R2, start_angle=start_angle,
  162. arc_angle=arc_angle, text_spacing=1/20.),
  163. 'r=0':
  164. Line(center, center +
  165. point(R*cos(radians(start_angle)),
  166. R*sin(radians(start_angle)))),
  167. 'r=start_angle':
  168. Line(center, center +
  169. point(R*cos(radians(start_angle+arc_angle)),
  170. R*sin(radians(start_angle+arc_angle)))),
  171. 'r=start+arc_angle':
  172. Line(center, center +
  173. point(R, 0)).set_linestyle('dashed'),
  174. 'radius': Distance_wText(center, a(0), 'radius', text_spacing=1/40.),
  175. 'center': Text('center', center-point(radius/10., radius/10.)),
  176. }
  177. for dimension in a.dimensions:
  178. if dimension.startswith('r='):
  179. dim = a.dimensions[dimension]
  180. dim.set_linestyle('dashed')
  181. dim.set_linewidth(1)
  182. dim.set_linecolor('black')
  183. a.draw_dimensions()
  184. drawing_tool.display('Arc')
  185. drawing_tool.savefig('tmp_Arc')
  186. expected = {'arc': "181 (x,y) coords"}
  187. msg = 'expected=%s, a=%s' % (expected, eval(repr(a)))
  188. assert eval(repr(a)) == expected, msg
  189. expected = {
  190. 'center': 'text "center" at (-0.2,-0.2)',
  191. 'start_angle': {'text': "Text at (2.68468,1.55)",
  192. 'arc': {'arc': "181 (x,y) coords",},},
  193. 'r=start+arc_angle': {
  194. 'line': "2 (x,y) coords linecolor='k' linewidth=1 linestyle='dashed'",},
  195. 'r=0': {'line': "2 (x,y) coords linecolor='k' linewidth=1 linestyle='dashed'",},
  196. 'radius': {'text': "Text at (0.629904,0.791025)",
  197. 'arrow': {'arrow': {
  198. 'line': "2 (x,y) coords linecolor='k' linewidth=1 arrow='<->'",},},},
  199. 'r=start_angle': {'line': "2 (x,y) coords linecolor='k' linewidth=1 linestyle='dashed'",},
  200. 'arc_angle': {'text': "Text at (0.430736,3.27177)",
  201. 'arc': {'arc': "181 (x,y) coords",},}
  202. }
  203. msg = 'expected=%s, a=%s' % (expected, eval(repr(a.dimensions)))
  204. assert eval(repr(a.dimensions)) == expected, msg
  205. def test_Spring():
  206. L = 5.0
  207. W = 2.0
  208. drawing_tool.set_coordinate_system(
  209. xmin=0, xmax=7*W, ymin=-L/2, ymax=1.5*L,
  210. axis=True, instruction_file='tmp_Spring.py')
  211. drawing_tool.set_linecolor('blue')
  212. drawing_tool.set_grid(True)
  213. xpos = W
  214. s1 = Spring((W,0), L, teeth=True)
  215. s1_title = Text('Default Spring',
  216. s1.geometric_features()['end'] + point(0,L/10))
  217. s1.draw()
  218. s1_title.draw()
  219. #s1.draw_dimensions()
  220. xpos += 3*W
  221. s2 = Spring(start=(xpos,0), length=L, width=W/2.,
  222. bar_length=L/6., teeth=False)
  223. s2.draw()
  224. s2.draw_dimensions()
  225. drawing_tool.display('Spring')
  226. drawing_tool.savefig('tmp_Spring')
  227. # Check s1 and s1.dimensions
  228. expected = {
  229. 'bar1': {'line': "2 (x,y) coords",},
  230. 'bar2': {'line': "2 (x,y) coords",},
  231. 'spiral': "45 (x,y) coords",}
  232. msg = 'expected=%s, a=%s' % (expected, eval(repr(s1)))
  233. assert eval(repr(s1)) == expected, msg
  234. expected = {
  235. 'bar_length1': {'text': "Text_wArrow at (-1.5,1.75)",
  236. 'arrow': {'arrow': {
  237. 'line': "2 (x,y) coords linecolor='k' linewidth=1 arrow='<->'",},},},
  238. 'bar_length2': {'text': "Text_wArrow at (-1.5,5.5)",
  239. 'arrow': {'arrow': {
  240. 'line': "2 (x,y) coords linecolor='k' linewidth=1 arrow='<->'",},},},
  241. 'width': {'text': "Text at (2,-1.51667)",
  242. 'arrow': {'arrow': {
  243. 'line': "2 (x,y) coords linecolor='k' linewidth=1 arrow='<->'",},},},
  244. 'start': 'annotation "start" at (1.25,-0.75) with arrow to (2,0)',
  245. 'length': {'text': "Text at (3.73333,2.5)",
  246. 'arrow': {'arrow': {
  247. 'line': "2 (x,y) coords linecolor='k' linewidth=1 arrow='<->'",},},},
  248. 'num_windings': 'annotation "num_windings" at (3,5.5) with arrow to (2.6,2.5)'
  249. }
  250. msg = 'expected=%s, a=%s' % (expected, eval(repr(s1.dimensions)))
  251. assert eval(repr(s1.dimensions)) == expected, msg
  252. def test_Dashpot():
  253. L = 5.0
  254. W = 2.0
  255. xpos = 0
  256. drawing_tool.set_coordinate_system(
  257. xmin=xpos, xmax=xpos+5.5*W, ymin=-L/2, ymax=1.5*L,
  258. axis=True, instruction_file='tmp_Dashpot.py')
  259. drawing_tool.set_linecolor('blue')
  260. drawing_tool.set_grid(True)
  261. # Default (simple) dashpot
  262. xpos = 1.5
  263. d1 = Dashpot(start=(xpos,0), total_length=L)
  264. d1_title = Text('Dashpot (default)',
  265. d1.geometric_features()['end'] + point(0,L/10))
  266. d1.draw()
  267. d1_title.draw()
  268. # Dashpot for animation with fixed bar_length, dashpot_length and
  269. # prescribed piston_pos
  270. xpos += 2.5*W
  271. d2 = Dashpot(start=(xpos,0), total_length=1.2*L, width=W/2,
  272. bar_length=W, dashpot_length=L/2, piston_pos=2*W)
  273. d2.draw()
  274. d2.draw_dimensions()
  275. drawing_tool.display('Dashpot')
  276. drawing_tool.savefig('tmp_Dashpot')
  277. expected = {
  278. 'line start': {'line': "2 (x,y) coords",},
  279. 'piston': {
  280. 'line': {'line': "2 (x,y) coords",},
  281. 'rectangle': {
  282. 'rectangle': "5 (x,y) coords fillcolor='' fillpattern='X'",},},
  283. 'pot': "4 (x,y) coords",
  284. }
  285. msg = 'expected=%s, a=%s' % (expected, eval(repr(d2)))
  286. assert eval(repr(d2)) == expected, msg
  287. expected = {
  288. 'width': {'text': "Text at (6.5,-1.56667)",
  289. 'arrow': {'arrow': {
  290. 'line': "2 (x,y) coords linecolor='k' linewidth=1 arrow='<->'",},},},
  291. 'start': 'annotation "start" at (5.75,-0.75) with arrow to (6.5,0)',
  292. 'bar_length': {'text': "Text_wArrow at (3.5,1.5)",
  293. 'arrow': {'arrow': {
  294. 'line': "2 (x,y) coords linecolor='k' linewidth=1 arrow='<->'",},},},
  295. 'total_length': {'text': "Text_wArrow at (8.75,5)",
  296. 'arrow': {'arrow': {
  297. 'line': "2 (x,y) coords linecolor='k' linewidth=1 arrow='<->'",},},},
  298. 'dashpot_length': {'text': "Text_wArrow at (7,-0.5)",
  299. 'arrow': {'arrow': {
  300. 'line': "2 (x,y) coords linecolor='k' linewidth=1 arrow='<->'",},},},
  301. 'piston_pos': {'text': "Text_wArrow at (3.5,3.6875)",
  302. 'arrow': {'arrow': {
  303. 'line': "2 (x,y) coords linecolor='k' linewidth=1 arrow='<->'",},},}
  304. }
  305. msg = 'expected=%s, a=%s' % (expected, eval(repr(d2.dimensions)))
  306. assert eval(repr(d2.dimensions)) == expected, msg
  307. def test_Wavy():
  308. drawing_tool.set_coordinate_system(xmin=0, xmax=1.5,
  309. ymin=-0.5, ymax=5,
  310. axis=True,
  311. instruction_file='tmp_Wavy.py')
  312. w = Wavy(main_curve=lambda x: 1 + sin(2*x),
  313. interval=[0,1.5],
  314. wavelength_of_perturbations=0.3,
  315. amplitude_of_perturbations=0.1,
  316. smoothness=0.05)
  317. w.draw()
  318. drawing_tool.display('Wavy')
  319. drawing_tool.savefig('tmp_Wavy')
  320. expected = {'wavy': "2001 (x,y) coords",}
  321. msg = 'expected=%s, a=%s' % (expected, eval(repr(w)))
  322. assert eval(repr(w)) == expected, msg
  323. def diff_files(files1, files2, mode='HTML'):
  324. import difflib, time
  325. n = 3
  326. for fromfile, tofile in zip(files1, files2):
  327. fromdate = time.ctime(os.stat(fromfile).st_mtime)
  328. todate = time.ctime(os.stat(tofile).st_mtime)
  329. fromlines = open(fromfile, 'U').readlines()
  330. tolines = open(tofile, 'U').readlines()
  331. diff_html = difflib.HtmlDiff().\
  332. make_file(fromlines,tolines,
  333. fromfile,tofile,context=True,numlines=n)
  334. diff_plain = difflib.unified_diff(fromlines, tolines, fromfile, tofile, fromdate, todate, n=n)
  335. filename_plain = fromfile + '.diff.txt'
  336. filename_html = fromfile + '.diff.html'
  337. if os.path.isfile(filename_plain):
  338. os.remove(filename_plain)
  339. if os.path.isfile(filename_html):
  340. os.remove(filename_html)
  341. f = open(filename_plain, 'w')
  342. f.writelines(diff_plain)
  343. f.close()
  344. size = os.path.getsize(filename_plain)
  345. if size > 4:
  346. print 'found differences:', fromfile, tofile
  347. f = open(filename_html, 'w')
  348. f.writelines(diff_html)
  349. f.close()
  350. def _test_test():
  351. """Compare files."""
  352. # Does not work yet.
  353. os.chdir('test')
  354. funcs = [name for name in globals() if name.startswith('test_') and callable(globals()[name])]
  355. funcs.remove('test_test')
  356. new_files = []
  357. res_files = []
  358. for func in funcs:
  359. mplfile = func.replace('test_', 'tmp_') + '.py'
  360. #exec(func + '()')
  361. new_files.append(mplfile)
  362. resfile = mplfile.replace('tmp_', 'res_')
  363. res_files.append(resfile)
  364. diff_files(new_files, res_files)