浏览代码

almost done

Hans Petter Langtangen 13 年之前
父节点
当前提交
2457d1f7ee

+ 17 - 0
doc/src/sketcher/figs-sketcher/combine_figures.txt

@@ -0,0 +1,17 @@
+Here is a recipe on how to combine two or more figures into one
+(same effect as subfigure in latex):
+
+convert -background white Vehicle0_hier1.png  Vehicle0_hier2.png +append tmp.png
+
+Use +append for stacking left to right, -append for top to bottom.
+The positioning of the figures can be controlled by -gravity.
+
+More general tool: montage
+
+montage file1.png file2.png ... file4.png -geometry +2+2  result.png
+montage file1.png file2.png -tile x1 result.png
+montage file1.png file2.png -tile 1x result.png
+
+See
+http://www.imagemagick.org/Usage/montage/#montage
+for borders, frames and shadows.

+ 2 - 2
doc/src/sketcher/src-sketcher/flow_over_gaussian.py

@@ -31,7 +31,7 @@ outlet = Line((W+L,0), (W+L,H))
 outlet.set_linestyle('dashed')
 outlet.set_linestyle('dashed')
 
 
 #print repr(inlet_profile)
 #print repr(inlet_profile)
-fig = Compose({
+fig = Composition({
     'bottom': wall,
     'bottom': wall,
     'inlet': inlet_profile,
     'inlet': inlet_profile,
     'symmetry line': symmetry_line,
     'symmetry line': symmetry_line,
@@ -51,7 +51,7 @@ symbols = {
     'dashed line': Line((W-2.5*sigma,0), (W+2.5*sigma,0)).\
     'dashed line': Line((W-2.5*sigma,0), (W+2.5*sigma,0)).\
                    set_linestyle('dotted').set_linecolor('black'),
                    set_linestyle('dotted').set_linecolor('black'),
     }
     }
-symbols = Compose(symbols)
+symbols = Composition(symbols)
 symbols.draw()
 symbols.draw()
 
 
 drawing_tool.display()
 drawing_tool.display()

+ 1 - 1
doc/src/sketcher/src-sketcher/osc1.py

@@ -14,7 +14,7 @@ x = 0
 def make_dashpot(x):
 def make_dashpot(x):
     d_start = (-L,2*H)
     d_start = (-L,2*H)
     d = Dashpot(start=d_start, total_length=L+x, width=W,
     d = Dashpot(start=d_start, total_length=L+x, width=W,
-                bar_length=3*H/2, dashpot_length=L/4, piston_pos=H)
+                bar_length=3*H/2, dashpot_length=L/2, piston_pos=H+x)
     d.rotate(-90, d_start)
     d.rotate(-90, d_start)
     return d
     return d
 
 

文件差异内容过多而无法显示
+ 1141 - 0
doc/src/sketcher/src-sketcher/test/res_Arc.py


+ 84 - 0
doc/src/sketcher/src-sketcher/test/res_Axis.py

@@ -0,0 +1,84 @@
+import matplotlib.pyplot as mpl
+
+mpl.ion()  # for interactive drawing
+fig = mpl.figure()
+
+ax = fig.gca()
+xmin, xmax, ymin, ymax = 0.0, 15.0, -7.0, 8.0
+ax.set_xlim(xmin, xmax)
+ax.set_ylim(ymin, ymax)
+ax.set_aspect('equal')
+
+
+x = [12.240192378864668, 12.5]
+y = [2.150000000000001, 2.0000000000000004]
+ax.plot(x, y, 'r', linewidth=2, linestyle='solid')
+x = [7.5, 12.5]
+y = [2.0, 2.0000000000000004]
+ax.plot(x, y, 'r', linewidth=2, linestyle='solid')
+x = [12.240192378864668, 12.5]
+y = [1.8499999999999999, 2.0000000000000004]
+ax.plot(x, y, 'r', linewidth=2, linestyle='solid')
+ax.text(12.8333, 2, 'x',
+        horizontalalignment='center', fontsize=14)
+x = [7.35, 7.5]
+y = [6.740192378864668, 7.0]
+ax.plot(x, y, 'r', linewidth=2, linestyle='solid')
+x = [7.5, 7.5]
+y = [2.0, 7.0]
+ax.plot(x, y, 'r', linewidth=2, linestyle='solid')
+x = [7.65, 7.5]
+y = [6.740192378864668, 7.0]
+ax.plot(x, y, 'r', linewidth=2, linestyle='solid')
+ax.text(7.5, 7.33333, 'y',
+        horizontalalignment='center', fontsize=14)
+mpl.draw()
+x = [11.034779889691228, 11.33022221559489]
+y = [5.161843595132618, 5.213938048432697]
+ax.plot(x, y, 'r', linewidth=2, linestyle='dashed')
+x = [7.5, 11.33022221559489]
+y = [2.0, 5.213938048432697]
+ax.plot(x, y, 'r', linewidth=2, linestyle='dashed')
+x = [11.22761617259719, 11.33022221559489]
+y = [4.932030262196924, 5.213938048432697]
+ax.plot(x, y, 'r', linewidth=2, linestyle='dashed')
+ax.text(11.5856, 5.4282, 'x',
+        horizontalalignment='center', fontsize=14)
+x = [4.338156404867384, 4.286061951567303]
+y = [5.534779889691228, 5.83022221559489]
+ax.plot(x, y, 'r', linewidth=2, linestyle='dashed')
+x = [7.5, 4.286061951567303]
+y = [2.0, 5.83022221559489]
+ax.plot(x, y, 'r', linewidth=2, linestyle='dashed')
+x = [4.567969737803077, 4.286061951567303]
+y = [5.727616172597189, 5.83022221559489]
+ax.plot(x, y, 'r', linewidth=2, linestyle='dashed')
+ax.text(4.0718, 6.08557, 'y',
+        horizontalalignment='center', fontsize=14)
+mpl.draw()
+x = [6.824595394571309, 6.631759111665348]
+y = [-2.694225432125347, -2.92403876506104]
+ax.plot(x, y, 'r', linewidth=2, linestyle='dotted')
+x = [7.5, 6.631759111665348]
+y = [2.0, -2.92403876506104]
+ax.plot(x, y, 'r', linewidth=2, linestyle='dotted')
+x = [6.5291530686676476, 6.631759111665348]
+y = [-2.642130978825267, -2.92403876506104]
+ax.plot(x, y, 'r', linewidth=2, linestyle='dotted')
+ax.text(6.57388, -3.25231, 'x',
+        horizontalalignment='center', fontsize=14)
+x = [12.194225432125346, 12.424038765061042]
+y = [1.3245953945713098, 1.1317591116653478]
+ax.plot(x, y, 'r', linewidth=2, linestyle='dotted')
+x = [7.5, 12.424038765061042]
+y = [2.0, 1.1317591116653478]
+ax.plot(x, y, 'r', linewidth=2, linestyle='dotted')
+x = [12.142130978825266, 12.424038765061042]
+y = [1.029153068667647, 1.1317591116653478]
+ax.plot(x, y, 'r', linewidth=2, linestyle='dotted')
+ax.text(12.7523, 1.07388, 'y',
+        horizontalalignment='center', fontsize=14)
+mpl.draw()
+mpl.title("Axis")
+mpl.draw()
+mpl.savefig("tmp_Axis.png")

+ 172 - 0
doc/src/sketcher/src-sketcher/test/res_Dashpot.py

@@ -0,0 +1,172 @@
+import matplotlib.pyplot as mpl
+
+mpl.ion()  # for interactive drawing
+fig = mpl.figure()
+
+ax = fig.gca()
+xmin, xmax, ymin, ymax = 0.0, 11.0, -2.5, 7.5
+ax.set_xlim(xmin, xmax)
+ax.set_ylim(ymin, ymax)
+ax.set_aspect('equal')
+
+
+
+mpl.grid(True)
+x = [1.5, 1.5]
+y = [0.0, 1.25]
+ax.plot(x, y, 'b', linewidth=2, linestyle='solid')
+x = [1.5, 1.5]
+y = [5.0, 2.395833333333333]
+ax.plot(x, y, 'b', linewidth=2, linestyle='solid')
+x = [1.0833333333333333,
+ 1.9166666666666665,
+ 1.9166666666666665,
+ 1.0833333333333333,
+ 1.0833333333333333]
+y = [2.083333333333333,
+ 2.083333333333333,
+ 2.395833333333333,
+ 2.395833333333333,
+ 2.083333333333333]
+ax.fill(x, y, 'white', edgecolor='b', linewidth=2, hatch='X')
+x = [1.0, 1.0, 2.0, 2.0]
+y = [3.75, 1.25, 1.25, 3.75]
+ax.plot(x, y, 'b', linewidth=2, linestyle='solid')
+ax.text(1.5, 5.5, 'Dashpot (default)',
+        horizontalalignment='center', fontsize=14)
+x = [6.5, 6.5]
+y = [0.0, 2.0]
+ax.plot(x, y, 'b', linewidth=2, linestyle='solid')
+x = [6.5, 6.5]
+y = [6.0, 4.5]
+ax.plot(x, y, 'b', linewidth=2, linestyle='solid')
+x = [6.083333333333333,
+ 6.916666666666666,
+ 6.916666666666666,
+ 6.083333333333333,
+ 6.083333333333333]
+y = [4.1875, 4.1875, 4.5, 4.5, 4.1875]
+ax.fill(x, y, 'white', edgecolor='b', linewidth=2, hatch='X')
+x = [6.0, 6.0, 7.0, 7.0]
+y = [4.5, 2.0, 2.0, 4.5]
+ax.plot(x, y, 'b', linewidth=2, linestyle='solid')
+ax.text(6.5, -1.56667, 'width',
+        horizontalalignment='center', fontsize=14)
+x = [7.0, 6.0]
+y = [-1.75, -1.75]
+ax.plot(x, y, 'k', linewidth=1, linestyle='solid')
+mpl.arrow(x=6, y=-1.75, dx=1, dy=0,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+mpl.arrow(x=7, y=-1.75, dx=-1, dy=0,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+ax.annotate('start', xy=(6.5, 0), xycoords='data',
+            textcoords='data', xytext=(5.75, -0.75),
+            horizontalalignment='center',
+            verticalalignment='top',
+            fontsize=14,
+            arrowprops=dict(arrowstyle='->',
+                            facecolor='black',
+                            linewidth=2,
+                            shrinkA=5,
+                            shrinkB=5))
+ax.annotate('bar_length', xy=[ 5.5  1. ], xycoords='data',
+            textcoords='data', xytext=(3.5, 1.5),
+            horizontalalignment='left',
+            verticalalignment='top',
+            fontsize=14,
+            arrowprops=dict(arrowstyle='->',
+                            facecolor='black',
+                            linewidth=2,
+                            shrinkA=5,
+                            shrinkB=5))
+x = [5.5, 5.5]
+y = [0.0, 2.0]
+ax.plot(x, y, 'k', linewidth=1, linestyle='solid')
+mpl.arrow(x=5.5, y=2, dx=0, dy=-2,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+mpl.arrow(x=5.5, y=0, dx=0, dy=2,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+ax.annotate('total_length', xy=[ 8.5  3. ], xycoords='data',
+            textcoords='data', xytext=(8.75, 5.0),
+            horizontalalignment='left',
+            verticalalignment='top',
+            fontsize=14,
+            arrowprops=dict(arrowstyle='->',
+                            facecolor='black',
+                            linewidth=2,
+                            shrinkA=5,
+                            shrinkB=5))
+x = [8.5, 8.5]
+y = [0.0, 6.0]
+ax.plot(x, y, 'k', linewidth=1, linestyle='solid')
+mpl.arrow(x=8.5, y=6, dx=0, dy=-6,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+mpl.arrow(x=8.5, y=0, dx=0, dy=6,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+ax.annotate('dashpot_length', xy=[ 7.5   3.25], xycoords='data',
+            textcoords='data', xytext=(7.0, -0.5),
+            horizontalalignment='left',
+            verticalalignment='top',
+            fontsize=14,
+            arrowprops=dict(arrowstyle='->',
+                            facecolor='black',
+                            linewidth=2,
+                            shrinkA=5,
+                            shrinkB=5))
+x = [7.5, 7.5]
+y = [2.0, 4.5]
+ax.plot(x, y, 'k', linewidth=1, linestyle='solid')
+mpl.arrow(x=7.5, y=4.5, dx=0, dy=-2.5,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+mpl.arrow(x=7.5, y=2, dx=0, dy=2.5,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+ax.annotate('piston_pos', xy=[ 5.5      3.09375], xycoords='data',
+            textcoords='data', xytext=(3.5, 3.6875),
+            horizontalalignment='left',
+            verticalalignment='top',
+            fontsize=14,
+            arrowprops=dict(arrowstyle='->',
+                            facecolor='black',
+                            linewidth=2,
+                            shrinkA=5,
+                            shrinkB=5))
+x = [5.5, 5.5]
+y = [2.0, 4.1875]
+ax.plot(x, y, 'k', linewidth=1, linestyle='solid')
+mpl.arrow(x=5.5, y=4.1875, dx=0, dy=-2.1875,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+mpl.arrow(x=5.5, y=2, dx=0, dy=2.1875,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+mpl.title("Dashpot")
+mpl.draw()
+mpl.savefig("tmp_Dashpot.png")

+ 140 - 0
doc/src/sketcher/src-sketcher/test/res_Distance_wText.py

@@ -0,0 +1,140 @@
+import matplotlib.pyplot as mpl
+
+mpl.ion()  # for interactive drawing
+fig = mpl.figure()
+
+ax = fig.gca()
+xmin, xmax, ymin, ymax = 0.0, 10.0, 0.0, 6.0
+ax.set_xlim(xmin, xmax)
+ax.set_ylim(ymin, ymax)
+ax.set_aspect('equal')
+
+
+ax.text(1.13014, 3.14588, '$ 2\\pi R^2 $',
+        horizontalalignment='left', fontsize=14)
+x = [0.0, 2.0]
+y = [2.0, 4.5]
+ax.plot(x, y, 'k', linewidth=1, linestyle='solid')
+mpl.arrow(x=2, y=4.5, dx=-2, dy=-2.5,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+mpl.arrow(x=0, y=2, dx=2, dy=2.5,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+ax.text(6, 5.16667, '$ 2\\pi R^2 $',
+        horizontalalignment='center', fontsize=14)
+x = [8.0, 4.0]
+y = [5.0, 5.0]
+ax.plot(x, y, 'k', linewidth=1, linestyle='solid')
+mpl.arrow(x=4, y=5, dx=4, dy=0,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+mpl.arrow(x=8, y=5, dx=-4, dy=0,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+ax.text(1.07454, 5.14907, '$ 2\\pi R^2 $',
+        horizontalalignment='center', fontsize=14)
+x = [2.0, 0.0]
+y = [4.5, 5.5]
+ax.plot(x, y, 'k', linewidth=1, linestyle='solid')
+mpl.arrow(x=0, y=5.5, dx=2, dy=-1,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+mpl.arrow(x=2, y=4.5, dx=-2, dy=1,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+ax.text(1.11785, 1.11785, '$ 2\\pi R^2 $',
+        horizontalalignment='left', fontsize=14)
+x = [2.0, 0.0]
+y = [0.0, 2.0]
+ax.plot(x, y, 'k', linewidth=1, linestyle='solid')
+mpl.arrow(x=0, y=2, dx=2, dy=-2,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+mpl.arrow(x=2, y=0, dx=-2, dy=2,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+ax.text(8.8882, 1.27639, '$ 2\\pi R^2 $',
+        horizontalalignment='right', fontsize=14)
+x = [10.0, 8.0]
+y = [1.0, 2.0]
+ax.plot(x, y, 'k', linewidth=1, linestyle='solid')
+mpl.arrow(x=8, y=2, dx=2, dy=-1,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+mpl.arrow(x=10, y=1, dx=-2, dy=1,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+ax.text(8.92546, 3.35093, '$ 2\\pi R^2 $',
+        horizontalalignment='center', fontsize=14)
+x = [10.0, 8.0]
+y = [3.0, 4.0]
+ax.plot(x, y, 'k', linewidth=1, linestyle='solid')
+mpl.arrow(x=8, y=4, dx=2, dy=-1,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+mpl.arrow(x=10, y=3, dx=-2, dy=1,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+ax.text(4.16667, 4.5, '$ 2\\pi R^2 $',
+        horizontalalignment='left', fontsize=14)
+x = [4.0, 4.0]
+y = [4.0, 5.0]
+ax.plot(x, y, 'k', linewidth=1, linestyle='solid')
+mpl.arrow(x=4, y=5, dx=0, dy=-1,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+mpl.arrow(x=4, y=4, dx=0, dy=1,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+ax.annotate('text_spacing=-1./40, alignment="right"', xy=(9, 1.2), xycoords='data',
+            textcoords='data', xytext=(4, 0.5),
+            horizontalalignment='left',
+            verticalalignment='top',
+            fontsize=10,
+            arrowprops=dict(arrowstyle='->',
+                            facecolor='black',
+                            linewidth=2,
+                            shrinkA=5,
+                            shrinkB=5))
+ax.annotate('text_spacing=-1./60', xy=(9, 3.2), xycoords='data',
+            textcoords='data', xytext=(4, 3.5),
+            horizontalalignment='left',
+            verticalalignment='top',
+            fontsize=10,
+            arrowprops=dict(arrowstyle='->',
+                            facecolor='black',
+                            linewidth=2,
+                            shrinkA=5,
+                            shrinkB=5))
+mpl.title("Distance_wText and text positioning")
+mpl.draw()
+mpl.savefig("tmp_Distance_wText.png")

+ 60 - 0
doc/src/sketcher/src-sketcher/test/res_Rectangle.py

@@ -0,0 +1,60 @@
+import matplotlib.pyplot as mpl
+
+mpl.ion()  # for interactive drawing
+fig = mpl.figure()
+
+ax = fig.gca()
+xmin, xmax, ymin, ymax = 0.0, 8.0, -1.5, 6.0
+ax.set_xlim(xmin, xmax)
+ax.set_ylim(ymin, ymax)
+ax.set_aspect('equal')
+
+
+
+mpl.grid(True)
+x = [2.0, 6.0, 6.0, 2.0, 2.0]
+y = [0.0, 0.0, 3.0, 3.0, 0.0]
+ax.plot(x, y, 'b', linewidth=2, linestyle='solid')
+ax.text(4, -0.466667, 'width',
+        horizontalalignment='center', fontsize=14)
+x = [6.0, 2.0]
+y = [-0.6, -0.6]
+ax.plot(x, y, 'k', linewidth=1, linestyle='solid')
+mpl.arrow(x=2, y=-0.6, dx=4, dy=0,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+mpl.arrow(x=6, y=-0.6, dx=-4, dy=0,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+ax.annotate('lower_left_corner', xy=[ 2.  0.], xycoords='data',
+            textcoords='data', xytext=[ 1.2 -0.6],
+            horizontalalignment='center',
+            verticalalignment='top',
+            fontsize=14,
+            arrowprops=dict(arrowstyle='->',
+                            facecolor='black',
+                            linewidth=2,
+                            shrinkA=5,
+                            shrinkB=5))
+ax.text(6.93333, 1.5, 'height',
+        horizontalalignment='left', fontsize=14)
+x = [6.8, 6.8]
+y = [0.0, 3.0]
+ax.plot(x, y, 'k', linewidth=1, linestyle='solid')
+mpl.arrow(x=6.8, y=3, dx=0, dy=-3,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+mpl.arrow(x=6.8, y=0, dx=0, dy=3,
+          facecolor='k', edgecolor='k',
+          linewidth=1, head_width=0.1,
+          length_includes_head=True,
+          shape='full')
+mpl.title("Rectangle")
+mpl.draw()
+mpl.savefig("tmp_Rectangle.png")

文件差异内容过多而无法显示
+ 2201 - 0
doc/src/sketcher/src-sketcher/test/res_Spring.py


+ 26 - 0
doc/src/sketcher/src-sketcher/test/res_Triangle.py

@@ -0,0 +1,26 @@
+import matplotlib.pyplot as mpl
+
+mpl.ion()  # for interactive drawing
+fig = mpl.figure()
+
+ax = fig.gca()
+xmin, xmax, ymin, ymax = 0.0, 8.0, -1.5, 3.6
+ax.set_xlim(xmin, xmax)
+ax.set_ylim(ymin, ymax)
+ax.set_aspect('equal')
+
+
+
+mpl.grid(True)
+x = [2.0, 6.0, 3.2, 2.0]
+y = [0.0, 2.0, 3.0, 0.0]
+ax.plot(x, y, 'b', linewidth=2, linestyle='solid')
+ax.text(6, 2, 'p2',
+        horizontalalignment='center', fontsize=14)
+ax.text(3.2, 3, 'p3',
+        horizontalalignment='center', fontsize=14)
+ax.text(2, 0, 'p1',
+        horizontalalignment='center', fontsize=14)
+mpl.title("Triangle")
+mpl.draw()
+mpl.savefig("tmp_Triangle.png")

+ 861 - 0
doc/src/sketcher/src-sketcher/test/res_mpl.py

@@ -0,0 +1,861 @@
+import matplotlib.pyplot as mpl
+
+mpl.ion()  # for interactive drawing
+fig = mpl.figure()
+
+ax = fig.gca()
+xmin, xmax, ymin, ymax = -12.0, 12.0, -1.0, 12.0
+ax.set_xlim(xmin, xmax)
+ax.set_ylim(ymin, ymax)
+ax.set_aspect('equal')
+
+
+x = [-12.0, -11.8, -11.8, -12.0, -12.0]
+y = [0.0, 0.0, 8.0, 8.0, 0.0]
+ax.fill(x, y, 'white', edgecolor='r', linewidth=2, hatch='/')
+x = [-12.0, -9.0]
+y = [8.0, 8.0]
+ax.plot(x, y, 'r', linewidth=2, linestyle='solid')
+x = [-3.0, 0.0]
+y = [8.0, 8.0]
+ax.plot(x, y, 'r', linewidth=2, linestyle='solid')
+x = [-9.0,
+ -8.863636363636363,
+ -8.727272727272727,
+ -8.590909090909092,
+ -8.454545454545455,
+ -8.318181818181818,
+ -8.181818181818182,
+ -8.045454545454545,
+ -7.90909090909091,
+ -7.772727272727273,
+ -7.636363636363637,
+ -7.5,
+ -7.363636363636363,
+ -7.227272727272727,
+ -7.090909090909092,
+ -6.954545454545455,
+ -6.818181818181818,
+ -6.681818181818182,
+ -6.545454545454547,
+ -6.40909090909091,
+ -6.272727272727273,
+ -6.136363636363637,
+ -6.0,
+ -5.863636363636363,
+ -5.727272727272727,
+ -5.590909090909092,
+ -5.454545454545455,
+ -5.318181818181818,
+ -5.181818181818182,
+ -5.045454545454547,
+ -4.90909090909091,
+ -4.772727272727273,
+ -4.636363636363637,
+ -4.5,
+ -4.363636363636363,
+ -4.227272727272727,
+ -4.090909090909092,
+ -3.9545454545454533,
+ -3.81818181818182,
+ -3.6818181818181834,
+ -3.5454545454545467,
+ -3.40909090909091,
+ -3.2727272727272734,
+ -3.1363636363636367,
+ -3.0]
+y = [8.0,
+ 6.800000000000001,
+ 8.0,
+ 9.2,
+ 8.0,
+ 6.800000000000001,
+ 8.0,
+ 9.2,
+ 8.0,
+ 6.800000000000001,
+ 8.0,
+ 9.2,
+ 8.0,
+ 6.800000000000001,
+ 7.999999999999998,
+ 9.2,
+ 8.000000000000002,
+ 6.800000000000001,
+ 7.999999999999998,
+ 9.2,
+ 8.000000000000002,
+ 6.800000000000001,
+ 7.999999999999995,
+ 9.2,
+ 8.000000000000002,
+ 6.800000000000001,
+ 8.000000000000002,
+ 9.2,
+ 8.000000000000002,
+ 6.800000000000001,
+ 7.999999999999993,
+ 9.2,
+ 8.000000000000002,
+ 6.800000000000002,
+ 8.000000000000002,
+ 9.2,
+ 8.000000000000002,
+ 6.800000000000002,
+ 7.999999999999994,
+ 9.2,
+ 8.000000000000004,
+ 6.800000000000002,
+ 8.000000000000002,
+ 9.2,
+ 8.000000000000012]
+ax.plot(x, y, 'r', linewidth=2, linestyle='solid')
+x = [-12.0, -9.0]
+y = [4.0, 4.0]
+ax.plot(x, y, 'r', linewidth=2, linestyle='solid')
+x = [0.0, -6.625]
+y = [4.000000000000001, 4.0]
+ax.plot(x, y, 'r', linewidth=2, linestyle='solid')
+x = [-7.0, -7.0, -6.625, -6.625, -7.0]
+y = [4.833333333333334,
+ 3.1666666666666683,
+ 3.1666666666666683,
+ 4.833333333333334,
+ 4.833333333333334]
+ax.fill(x, y, 'white', edgecolor='r', linewidth=2, hatch='X')
+x = [-6.0, -9.0, -9.0, -6.0]
+y = [5.0, 5.0, 3.0, 3.0000000000000004]
+ax.plot(x, y, 'r', linewidth=2, linestyle='solid')
+x = [0.0, 8.0, 8.0, 0.0, 0.0]
+y = [2.0, 2.0, 10.0, 10.0, 2.0]
+ax.plot(x, y, 'r', linewidth=2, linestyle='solid')
+x = [3.0,
+ 2.999390827019096,
+ 2.9975640502598244,
+ 2.9945218953682735,
+ 2.99026806874157,
+ 2.984807753012208,
+ 2.9781476007338057,
+ 2.9702957262759964,
+ 2.961261695938319,
+ 2.9510565162951536,
+ 2.9396926207859084,
+ 2.9271838545667874,
+ 2.9135454576426008,
+ 2.898794046299167,
+ 2.882947592858927,
+ 2.866025403784439,
+ 2.848048096156426,
+ 2.8290375725550416,
+ 2.8090169943749475,
+ 2.788010753606722,
+ 2.766044443118978,
+ 2.743144825477394,
+ 2.719339800338651,
+ 2.6946583704589973,
+ 2.6691306063588582,
+ 2.6427876096865393,
+ 2.615661475325658,
+ 2.5877852522924734,
+ 2.5591929034707466,
+ 2.5299192642332047,
+ 2.5,
+ 2.4694715627858908,
+ 2.4383711467890774,
+ 2.4067366430758,
+ 2.374606593415912,
+ 2.342020143325669,
+ 2.3090169943749475,
+ 2.275637355816999,
+ 2.241921895599668,
+ 2.2079116908177596,
+ 2.1736481776669305,
+ 2.1391731009600656,
+ 2.1045284632676533,
+ 2.069756473744125,
+ 2.034899496702501,
+ 2.0,
+ 1.965100503297499,
+ 1.9302435262558746,
+ 1.8954715367323465,
+ 1.8608268990399346,
+ 1.8263518223330697,
+ 1.7920883091822406,
+ 1.7580781044003322,
+ 1.724362644183001,
+ 1.6909830056250525,
+ 1.6579798566743313,
+ 1.625393406584088,
+ 1.5932633569241998,
+ 1.5616288532109226,
+ 1.530528437214109,
+ 1.5000000000000002,
+ 1.4700807357667953,
+ 1.4408070965292534,
+ 1.412214747707527,
+ 1.3843385246743418,
+ 1.3572123903134607,
+ 1.3308693936411418,
+ 1.3053416295410027,
+ 1.280660199661349,
+ 1.256855174522606,
+ 1.233955556881022,
+ 1.2119892463932782,
+ 1.1909830056250525,
+ 1.1709624274449584,
+ 1.1519519038435742,
+ 1.1339745962155612,
+ 1.117052407141073,
+ 1.101205953700833,
+ 1.0864545423573992,
+ 1.0728161454332126,
+ 1.0603073792140916,
+ 1.0489434837048464,
+ 1.038738304061681,
+ 1.0297042737240036,
+ 1.0218523992661943,
+ 1.0151922469877919,
+ 1.0097319312584296,
+ 1.0054781046317267,
+ 1.0024359497401758,
+ 1.0006091729809041,
+ 1.0,
+ 1.0006091729809041,
+ 1.0024359497401758,
+ 1.0054781046317267,
+ 1.0097319312584299,
+ 1.0151922469877919,
+ 1.0218523992661943,
+ 1.0297042737240036,
+ 1.038738304061681,
+ 1.0489434837048464,
+ 1.0603073792140916,
+ 1.0728161454332126,
+ 1.0864545423573992,
+ 1.1012059537008332,
+ 1.117052407141073,
+ 1.1339745962155614,
+ 1.151951903843574,
+ 1.1709624274449582,
+ 1.1909830056250525,
+ 1.211989246393278,
+ 1.233955556881022,
+ 1.2568551745226058,
+ 1.280660199661349,
+ 1.3053416295410027,
+ 1.3308693936411418,
+ 1.3572123903134605,
+ 1.3843385246743418,
+ 1.4122147477075266,
+ 1.4408070965292534,
+ 1.4700807357667949,
+ 1.4999999999999996,
+ 1.5305284372141092,
+ 1.5616288532109222,
+ 1.5932633569241998,
+ 1.6253934065840876,
+ 1.6579798566743316,
+ 1.6909830056250525,
+ 1.7243626441830011,
+ 1.7580781044003322,
+ 1.7920883091822402,
+ 1.8263518223330697,
+ 1.8608268990399341,
+ 1.8954715367323467,
+ 1.9302435262558744,
+ 1.9651005032974993,
+ 1.9999999999999998,
+ 2.034899496702501,
+ 2.069756473744125,
+ 2.104528463267653,
+ 2.1391731009600656,
+ 2.17364817766693,
+ 2.2079116908177596,
+ 2.2419218955996674,
+ 2.2756373558169996,
+ 2.3090169943749475,
+ 2.342020143325669,
+ 2.374606593415912,
+ 2.4067366430757997,
+ 2.4383711467890774,
+ 2.4694715627858903,
+ 2.5,
+ 2.5299192642332047,
+ 2.559192903470747,
+ 2.587785252292473,
+ 2.6156614753256586,
+ 2.6427876096865393,
+ 2.669130606358858,
+ 2.6946583704589973,
+ 2.719339800338651,
+ 2.743144825477394,
+ 2.766044443118978,
+ 2.788010753606722,
+ 2.8090169943749475,
+ 2.829037572555042,
+ 2.848048096156426,
+ 2.8660254037844384,
+ 2.882947592858927,
+ 2.898794046299167,
+ 2.913545457642601,
+ 2.9271838545667874,
+ 2.9396926207859084,
+ 2.9510565162951536,
+ 2.961261695938319,
+ 2.9702957262759964,
+ 2.9781476007338057,
+ 2.984807753012208,
+ 2.99026806874157,
+ 2.9945218953682735,
+ 2.9975640502598244,
+ 2.999390827019096,
+ 3.0]
+y = [1.0,
+ 1.034899496702501,
+ 1.0697564737441252,
+ 1.1045284632676535,
+ 1.1391731009600654,
+ 1.1736481776669303,
+ 1.2079116908177594,
+ 1.2419218955996678,
+ 1.275637355816999,
+ 1.3090169943749475,
+ 1.3420201433256687,
+ 1.374606593415912,
+ 1.4067366430758002,
+ 1.4383711467890774,
+ 1.4694715627858908,
+ 1.5,
+ 1.529919264233205,
+ 1.559192903470747,
+ 1.5877852522924731,
+ 1.6156614753256582,
+ 1.6427876096865393,
+ 1.6691306063588582,
+ 1.6946583704589973,
+ 1.719339800338651,
+ 1.7431448254773942,
+ 1.766044443118978,
+ 1.788010753606722,
+ 1.8090169943749475,
+ 1.8290375725550416,
+ 1.8480480961564258,
+ 1.8660254037844386,
+ 1.882947592858927,
+ 1.898794046299167,
+ 1.9135454576426008,
+ 1.9271838545667874,
+ 1.9396926207859084,
+ 1.9510565162951536,
+ 1.961261695938319,
+ 1.9702957262759964,
+ 1.9781476007338057,
+ 1.9848077530122081,
+ 1.9902680687415704,
+ 1.9945218953682733,
+ 1.9975640502598242,
+ 1.9993908270190959,
+ 2.0,
+ 1.9993908270190959,
+ 1.9975640502598242,
+ 1.9945218953682733,
+ 1.9902680687415704,
+ 1.9848077530122081,
+ 1.9781476007338057,
+ 1.9702957262759964,
+ 1.961261695938319,
+ 1.9510565162951536,
+ 1.9396926207859084,
+ 1.9271838545667874,
+ 1.9135454576426008,
+ 1.8987940462991668,
+ 1.882947592858927,
+ 1.8660254037844388,
+ 1.848048096156426,
+ 1.8290375725550416,
+ 1.8090169943749475,
+ 1.788010753606722,
+ 1.766044443118978,
+ 1.7431448254773942,
+ 1.719339800338651,
+ 1.6946583704589973,
+ 1.6691306063588582,
+ 1.6427876096865395,
+ 1.6156614753256584,
+ 1.5877852522924734,
+ 1.559192903470747,
+ 1.529919264233205,
+ 1.5,
+ 1.4694715627858908,
+ 1.4383711467890774,
+ 1.4067366430758004,
+ 1.3746065934159122,
+ 1.3420201433256689,
+ 1.3090169943749475,
+ 1.275637355816999,
+ 1.2419218955996678,
+ 1.2079116908177594,
+ 1.1736481776669303,
+ 1.1391731009600654,
+ 1.1045284632676537,
+ 1.0697564737441256,
+ 1.0348994967025011,
+ 1.0000000000000002,
+ 0.9651005032974991,
+ 0.9302435262558747,
+ 0.8954715367323465,
+ 0.8608268990399345,
+ 0.8263518223330695,
+ 0.7920883091822405,
+ 0.7580781044003325,
+ 0.724362644183001,
+ 0.6909830056250528,
+ 0.6579798566743313,
+ 0.625393406584088,
+ 0.5932633569241998,
+ 0.5616288532109226,
+ 0.5305284372141091,
+ 0.4999999999999999,
+ 0.4700807357667952,
+ 0.4408070965292533,
+ 0.412214747707527,
+ 0.3843385246743418,
+ 0.35721239031346075,
+ 0.33086939364114176,
+ 0.30534162954100263,
+ 0.2806601996613488,
+ 0.25685517452260564,
+ 0.2339555568810221,
+ 0.21198924639327787,
+ 0.19098300562505266,
+ 0.17096242744495815,
+ 0.15195190384357404,
+ 0.13397459621556163,
+ 0.11705240714107301,
+ 0.10120595370083318,
+ 0.08645454235739902,
+ 0.07281614543321269,
+ 0.06030737921409157,
+ 0.04894348370484647,
+ 0.038738304061680995,
+ 0.029704273724003527,
+ 0.021852399266194422,
+ 0.01519224698779198,
+ 0.009731931258429749,
+ 0.005478104631726599,
+ 0.0024359497401758023,
+ 0.0006091729809042379,
+ 0.0,
+ 0.0006091729809042379,
+ 0.0024359497401756913,
+ 0.005478104631726599,
+ 0.009731931258429638,
+ 0.015192246987791869,
+ 0.021852399266194422,
+ 0.029704273724003416,
+ 0.03873830406168122,
+ 0.04894348370484636,
+ 0.06030737921409168,
+ 0.07281614543321258,
+ 0.08645454235739891,
+ 0.10120595370083296,
+ 0.1170524071410729,
+ 0.1339745962155614,
+ 0.15195190384357382,
+ 0.17096242744495838,
+ 0.19098300562505244,
+ 0.2119892463932782,
+ 0.23395555688102188,
+ 0.2568551745226054,
+ 0.2806601996613488,
+ 0.3053416295410024,
+ 0.3308693936411419,
+ 0.3572123903134604,
+ 0.3843385246743418,
+ 0.41221474770752664,
+ 0.44080709652925343,
+ 0.470080735766795,
+ 0.49999999999999956,
+ 0.5305284372141092,
+ 0.5616288532109222,
+ 0.5932633569241998,
+ 0.6253934065840876,
+ 0.6579798566743313,
+ 0.6909830056250523,
+ 0.7243626441830011,
+ 0.7580781044003322,
+ 0.7920883091822402,
+ 0.8263518223330696,
+ 0.8608268990399341,
+ 0.8954715367323466,
+ 0.9302435262558744,
+ 0.9651005032974992,
+ 0.9999999999999998]
+ax.plot(x, y, 'r', linewidth=2, linestyle='solid')
+x = [7.0,
+ 6.999390827019096,
+ 6.997564050259824,
+ 6.9945218953682735,
+ 6.99026806874157,
+ 6.984807753012208,
+ 6.978147600733806,
+ 6.970295726275996,
+ 6.961261695938319,
+ 6.951056516295154,
+ 6.939692620785909,
+ 6.927183854566787,
+ 6.9135454576426,
+ 6.898794046299167,
+ 6.882947592858927,
+ 6.866025403784439,
+ 6.848048096156425,
+ 6.829037572555041,
+ 6.8090169943749475,
+ 6.788010753606722,
+ 6.766044443118978,
+ 6.743144825477394,
+ 6.719339800338651,
+ 6.694658370458997,
+ 6.669130606358858,
+ 6.64278760968654,
+ 6.615661475325658,
+ 6.587785252292473,
+ 6.559192903470747,
+ 6.529919264233205,
+ 6.5,
+ 6.469471562785891,
+ 6.438371146789077,
+ 6.4067366430758,
+ 6.374606593415912,
+ 6.342020143325669,
+ 6.3090169943749475,
+ 6.275637355816999,
+ 6.241921895599668,
+ 6.20791169081776,
+ 6.17364817766693,
+ 6.139173100960066,
+ 6.104528463267654,
+ 6.069756473744125,
+ 6.034899496702501,
+ 6.0,
+ 5.965100503297499,
+ 5.930243526255874,
+ 5.895471536732346,
+ 5.860826899039934,
+ 5.82635182233307,
+ 5.79208830918224,
+ 5.758078104400332,
+ 5.724362644183001,
+ 5.6909830056250525,
+ 5.657979856674332,
+ 5.625393406584088,
+ 5.5932633569242,
+ 5.561628853210923,
+ 5.530528437214109,
+ 5.5,
+ 5.470080735766795,
+ 5.440807096529253,
+ 5.412214747707527,
+ 5.384338524674342,
+ 5.35721239031346,
+ 5.330869393641142,
+ 5.305341629541003,
+ 5.280660199661349,
+ 5.256855174522606,
+ 5.233955556881022,
+ 5.211989246393278,
+ 5.1909830056250525,
+ 5.170962427444959,
+ 5.151951903843575,
+ 5.133974596215561,
+ 5.117052407141073,
+ 5.101205953700833,
+ 5.0864545423574,
+ 5.072816145433213,
+ 5.060307379214091,
+ 5.048943483704846,
+ 5.038738304061681,
+ 5.029704273724004,
+ 5.021852399266194,
+ 5.015192246987792,
+ 5.00973193125843,
+ 5.0054781046317265,
+ 5.002435949740176,
+ 5.000609172980904,
+ 5.0,
+ 5.000609172980904,
+ 5.002435949740176,
+ 5.0054781046317265,
+ 5.00973193125843,
+ 5.015192246987792,
+ 5.021852399266194,
+ 5.029704273724004,
+ 5.038738304061681,
+ 5.048943483704846,
+ 5.060307379214091,
+ 5.072816145433213,
+ 5.0864545423574,
+ 5.101205953700833,
+ 5.117052407141073,
+ 5.133974596215562,
+ 5.151951903843574,
+ 5.170962427444958,
+ 5.1909830056250525,
+ 5.211989246393278,
+ 5.233955556881022,
+ 5.256855174522606,
+ 5.280660199661349,
+ 5.305341629541003,
+ 5.330869393641142,
+ 5.35721239031346,
+ 5.384338524674342,
+ 5.412214747707527,
+ 5.440807096529253,
+ 5.470080735766794,
+ 5.5,
+ 5.530528437214109,
+ 5.561628853210922,
+ 5.5932633569242,
+ 5.625393406584088,
+ 5.657979856674332,
+ 5.6909830056250525,
+ 5.724362644183001,
+ 5.758078104400332,
+ 5.79208830918224,
+ 5.82635182233307,
+ 5.860826899039934,
+ 5.895471536732346,
+ 5.930243526255874,
+ 5.965100503297499,
+ 6.0,
+ 6.034899496702501,
+ 6.069756473744125,
+ 6.104528463267653,
+ 6.139173100960066,
+ 6.17364817766693,
+ 6.20791169081776,
+ 6.241921895599667,
+ 6.2756373558169996,
+ 6.3090169943749475,
+ 6.342020143325669,
+ 6.374606593415912,
+ 6.406736643075799,
+ 6.438371146789077,
+ 6.46947156278589,
+ 6.5,
+ 6.529919264233205,
+ 6.559192903470747,
+ 6.587785252292473,
+ 6.615661475325659,
+ 6.64278760968654,
+ 6.669130606358857,
+ 6.694658370458997,
+ 6.719339800338651,
+ 6.743144825477394,
+ 6.766044443118978,
+ 6.788010753606722,
+ 6.8090169943749475,
+ 6.829037572555042,
+ 6.848048096156425,
+ 6.866025403784438,
+ 6.882947592858927,
+ 6.898794046299167,
+ 6.913545457642601,
+ 6.927183854566787,
+ 6.939692620785909,
+ 6.951056516295154,
+ 6.961261695938319,
+ 6.970295726275996,
+ 6.978147600733806,
+ 6.984807753012208,
+ 6.99026806874157,
+ 6.9945218953682735,
+ 6.997564050259824,
+ 6.999390827019096,
+ 7.0]
+y = [1.0,
+ 1.034899496702501,
+ 1.0697564737441252,
+ 1.1045284632676535,
+ 1.1391731009600654,
+ 1.1736481776669303,
+ 1.2079116908177594,
+ 1.2419218955996678,
+ 1.275637355816999,
+ 1.3090169943749475,
+ 1.3420201433256687,
+ 1.374606593415912,
+ 1.4067366430758002,
+ 1.4383711467890774,
+ 1.4694715627858908,
+ 1.5,
+ 1.529919264233205,
+ 1.559192903470747,
+ 1.5877852522924731,
+ 1.6156614753256582,
+ 1.6427876096865393,
+ 1.6691306063588582,
+ 1.6946583704589973,
+ 1.719339800338651,
+ 1.7431448254773942,
+ 1.766044443118978,
+ 1.788010753606722,
+ 1.8090169943749475,
+ 1.8290375725550416,
+ 1.8480480961564258,
+ 1.8660254037844386,
+ 1.882947592858927,
+ 1.898794046299167,
+ 1.9135454576426008,
+ 1.9271838545667874,
+ 1.9396926207859084,
+ 1.9510565162951536,
+ 1.961261695938319,
+ 1.9702957262759964,
+ 1.9781476007338057,
+ 1.9848077530122081,
+ 1.9902680687415704,
+ 1.9945218953682733,
+ 1.9975640502598242,
+ 1.9993908270190959,
+ 2.0,
+ 1.9993908270190959,
+ 1.9975640502598242,
+ 1.9945218953682733,
+ 1.9902680687415704,
+ 1.9848077530122081,
+ 1.9781476007338057,
+ 1.9702957262759964,
+ 1.961261695938319,
+ 1.9510565162951536,
+ 1.9396926207859084,
+ 1.9271838545667874,
+ 1.9135454576426008,
+ 1.8987940462991668,
+ 1.882947592858927,
+ 1.8660254037844388,
+ 1.848048096156426,
+ 1.8290375725550416,
+ 1.8090169943749475,
+ 1.788010753606722,
+ 1.766044443118978,
+ 1.7431448254773942,
+ 1.719339800338651,
+ 1.6946583704589973,
+ 1.6691306063588582,
+ 1.6427876096865395,
+ 1.6156614753256584,
+ 1.5877852522924734,
+ 1.559192903470747,
+ 1.529919264233205,
+ 1.5,
+ 1.4694715627858908,
+ 1.4383711467890774,
+ 1.4067366430758004,
+ 1.3746065934159122,
+ 1.3420201433256689,
+ 1.3090169943749475,
+ 1.275637355816999,
+ 1.2419218955996678,
+ 1.2079116908177594,
+ 1.1736481776669303,
+ 1.1391731009600654,
+ 1.1045284632676537,
+ 1.0697564737441256,
+ 1.0348994967025011,
+ 1.0000000000000002,
+ 0.9651005032974991,
+ 0.9302435262558747,
+ 0.8954715367323465,
+ 0.8608268990399345,
+ 0.8263518223330695,
+ 0.7920883091822405,
+ 0.7580781044003325,
+ 0.724362644183001,
+ 0.6909830056250528,
+ 0.6579798566743313,
+ 0.625393406584088,
+ 0.5932633569241998,
+ 0.5616288532109226,
+ 0.5305284372141091,
+ 0.4999999999999999,
+ 0.4700807357667952,
+ 0.4408070965292533,
+ 0.412214747707527,
+ 0.3843385246743418,
+ 0.35721239031346075,
+ 0.33086939364114176,
+ 0.30534162954100263,
+ 0.2806601996613488,
+ 0.25685517452260564,
+ 0.2339555568810221,
+ 0.21198924639327787,
+ 0.19098300562505266,
+ 0.17096242744495815,
+ 0.15195190384357404,
+ 0.13397459621556163,
+ 0.11705240714107301,
+ 0.10120595370083318,
+ 0.08645454235739902,
+ 0.07281614543321269,
+ 0.06030737921409157,
+ 0.04894348370484647,
+ 0.038738304061680995,
+ 0.029704273724003527,
+ 0.021852399266194422,
+ 0.01519224698779198,
+ 0.009731931258429749,
+ 0.005478104631726599,
+ 0.0024359497401758023,
+ 0.0006091729809042379,
+ 0.0,
+ 0.0006091729809042379,
+ 0.0024359497401756913,
+ 0.005478104631726599,
+ 0.009731931258429638,
+ 0.015192246987791869,
+ 0.021852399266194422,
+ 0.029704273724003416,
+ 0.03873830406168122,
+ 0.04894348370484636,
+ 0.06030737921409168,
+ 0.07281614543321258,
+ 0.08645454235739891,
+ 0.10120595370083296,
+ 0.1170524071410729,
+ 0.1339745962155614,
+ 0.15195190384357382,
+ 0.17096242744495838,
+ 0.19098300562505244,
+ 0.2119892463932782,
+ 0.23395555688102188,
+ 0.2568551745226054,
+ 0.2806601996613488,
+ 0.3053416295410024,
+ 0.3308693936411419,
+ 0.3572123903134604,
+ 0.3843385246743418,
+ 0.41221474770752664,
+ 0.44080709652925343,
+ 0.470080735766795,
+ 0.49999999999999956,
+ 0.5305284372141092,
+ 0.5616288532109222,
+ 0.5932633569241998,
+ 0.6253934065840876,
+ 0.6579798566743313,
+ 0.6909830056250523,
+ 0.7243626441830011,
+ 0.7580781044003322,
+ 0.7920883091822402,
+ 0.8263518223330696,
+ 0.8608268990399341,
+ 0.8954715367323466,
+ 0.9302435262558744,
+ 0.9651005032974992,
+ 0.9999999999999998]
+ax.plot(x, y, 'r', linewidth=2, linestyle='solid')
+x = [-6.0, 12.0, 12.0, -6.0]
+y = [0.0, 0.0, -0.2, -0.2]
+ax.fill(x, y, 'white', edgecolor='r', linewidth=2, hatch='/')
+mpl.draw()

二进制
doc/src/sketcher/src-sketcher/test/tmp_Arc.png


二进制
doc/src/sketcher/src-sketcher/test/tmp_Axis.png


二进制
doc/src/sketcher/src-sketcher/test/tmp_Dashpot.png


二进制
doc/src/sketcher/src-sketcher/test/tmp_Distance_wText.png


二进制
doc/src/sketcher/src-sketcher/test/tmp_Rectangle.png


二进制
doc/src/sketcher/src-sketcher/test/tmp_Spring.png


二进制
doc/src/sketcher/src-sketcher/test/tmp_Triangle.png


+ 9 - 1
doc/src/sketcher/src-sketcher/vehicle0.py

@@ -70,7 +70,15 @@ files = animate(fig, tp, move_vehicle, moviefiles=True,
 os.system('convert -delay 20 %s anim.gif' % files)
 os.system('convert -delay 20 %s anim.gif' % files)
 os.system('ffmpeg -i "tmp_frame_%04d.png" -b 800k -r 25 -vcodec mpeg4 -y -qmin 2 -qmax 31 anim.mpeg')
 os.system('ffmpeg -i "tmp_frame_%04d.png" -b 800k -r 25 -vcodec mpeg4 -y -qmin 2 -qmax 31 anim.mpeg')
 
 
-from scitools.std import movie
+try:
+    from scitools.std import movie
+except ImportError:
+    raise ImportError(
+        'scitools must be installed for running the "movie" function.\n'
+        'scitools is installed by sudo apt-get install python-scitools\n'
+        'on Ubuntu or by sudo python setup.py install if the code is\n'
+        'downloaded from http://code.google.com/p/scitools.')
+
 # HTML page showing individual frames
 # HTML page showing individual frames
 movie(files, encoder='html', fps=4, output_file='anim.html')
 movie(files, encoder='html', fps=4, output_file='anim.html')
 
 

+ 200 - 96
pysketcher/shapes.py

@@ -18,6 +18,11 @@ def point(x, y, check_inside=False):
 
 
     return array((x, y), dtype=float)
     return array((x, y), dtype=float)
 
 
+def distance(p1, p2):
+    p1 = arr2D(p1);  p2 = arr2D(p2)
+    d = p2 - p1
+    return sqrt(d[0]**2 + d[1]**2)
+
 def unit_vec(x, y=None):
 def unit_vec(x, y=None):
     """Return unit vector of the vector (x,y), or just x if x is a 2D point."""
     """Return unit vector of the vector (x,y), or just x if x is a 2D point."""
     if isinstance(x, (float,int)) and isinstance(y, (float,int)):
     if isinstance(x, (float,int)) and isinstance(y, (float,int)):
@@ -647,19 +652,6 @@ class Rectangle(Shape):
     """
     """
     Rectangle specified by the point `lower_left_corner`, `width`,
     Rectangle specified by the point `lower_left_corner`, `width`,
     and `height`.
     and `height`.
-
-    Recorded geometric features:
-
-    ==================== =============================================
-    Attribute            Description
-    ==================== =============================================
-    lower_left           Lower left corner point.
-    upper_left           Upper left corner point.
-    lower_right          Lower right corner point.
-    upper_right          Upper right corner point.
-    lower_mid            Middle point on lower side.
-    upper_mid            Middle point on upper side.
-    ==================== =============================================
     """
     """
     def __init__(self, lower_left_corner, width, height):
     def __init__(self, lower_left_corner, width, height):
         is_sequence(lower_left_corner)
         is_sequence(lower_left_corner)
@@ -683,14 +675,31 @@ class Rectangle(Shape):
             }
             }
         self.dimensions = dims
         self.dimensions = dims
 
 
-        # Stored geometric features
-        self.lower_left  = lower_left_corner
-        self.lower_right = lower_left_corner + point(width,0)
-        self.upper_left  = lower_left_corner + point(0,height)
-        self.upper_right = lower_left_corner + point(width,height)
-        self.lower_mid = 0.5*(self.lower_left + self.lower_right)
-        self.upper_mid = 0.5*(self.upper_left + self.upper_right)
-
+    def geometric_features(self):
+        """
+        Return dictionary with
+
+        ==================== =============================================
+        Attribute            Description
+        ==================== =============================================
+        lower_left           Lower left corner point.
+        upper_left           Upper left corner point.
+        lower_right          Lower right corner point.
+        upper_right          Upper right corner point.
+        lower_mid            Middle point on lower side.
+        upper_mid            Middle point on upper side.
+        ==================== =============================================
+        """
+        r = self.shapes['rectangle']
+        d = {'lower_left': point(r.x[0], r.y[0]),
+             'lower_right': point(r.x[1], r.y[1]),
+             'upper_right': point(r.x[2], r.y[2]),
+             'upper_left': point(r.x[3], r.y[3])}
+        d['lower_mid'] = 0.5*(d['lower_left'] + d['lower_right'])
+        d['upper_mid'] = 0.5*(d['upper_left'] + d['upper_right'])
+        d['left_mid'] = 0.5*(d['lower_left'] + d['upper_left'])
+        d['right_mid'] = 0.5*(d['lower_right'] + d['upper_right'])
+        return d
 
 
 class Triangle(Shape):
 class Triangle(Shape):
     """
     """
@@ -716,11 +725,11 @@ class Triangle(Shape):
                            'p2': Text('p2', p2),
                            'p2': Text('p2', p2),
                            'p3': Text('p3', p3)}
                            'p3': Text('p3', p3)}
 
 
-        # Stored geometric features
-        self.p1 = arr2D(p1)
-        self.p2 = arr2D(p2)
-        self.p3 = arr2D(p3)
-
+    def geometric_features(self):
+        t = self.shapes['triangle']
+        return {'p1': point(t.x[0], t.y[0]),
+                'p2': point(t.x[1], t.y[1]),
+                'p3': point(t.x[2], t.y[2])}
 
 
 class Line(Shape):
 class Line(Shape):
     def __init__(self, start, end):
     def __init__(self, start, end):
@@ -729,9 +738,10 @@ class Line(Shape):
         y = [start[1], end[1]]
         y = [start[1], end[1]]
         self.shapes = {'line': Curve(x, y)}
         self.shapes = {'line': Curve(x, y)}
 
 
-        # Stored geometric features
-        self.start = start
-        self.end = end
+    def geometric_features(self):
+        line = self.shapes['line']
+        return {'start': point(line.x[0], line.y[0]),
+                'end': point(line.x[1], line.y[1]),}
 
 
     def compute_formulas(self):
     def compute_formulas(self):
         x, y = self.shapes['line'].x, self.shapes['line'].y
         x, y = self.shapes['line'].x, self.shapes['line'].y
@@ -839,9 +849,13 @@ class Arc(Shape):
         # constructor forever). Set in test_Arc instead.
         # constructor forever). Set in test_Arc instead.
 
 
         # Stored geometric features
         # Stored geometric features
-        self.mid_point = self(arc_angle/2)
-        self.start = point(x[0], y[0])
-        self.end = point(x[-1], y[-1])
+    def geometric_features(self):
+        a = self.shapes['arc']
+        m = len(a.x)/2  # mid point in array
+        d = {'start': point(a.x[0], a.y[0]),
+             'end': point(a.x[-1], a.y[-1]),
+             'mid': point(a.x[m], a.y[m])}
+        return d
 
 
     def __call__(self, theta):
     def __call__(self, theta):
         """
         """
@@ -931,6 +945,7 @@ class Wall(Shape):
             y1 = concatenate(y)
             y1 = concatenate(y)
         else:
         else:
             y1 = asarray(y, float)
             y1 = asarray(y, float)
+        self.x1 = x1;  self.y1 = y1
 
 
         # Displaced curve (according to thickness)
         # Displaced curve (according to thickness)
         x2 = x1
         x2 = x1
@@ -945,12 +960,17 @@ class Wall(Shape):
         y = [y1[-1]] + y2[-1::-1].tolist() + [y1[0]]
         y = [y1[-1]] + y2[-1::-1].tolist() + [y1[0]]
         self.shapes = {'wall': wall}
         self.shapes = {'wall': wall}
 
 
-        #white_eraser = Curve(x, y)
-        #white_eraser.set_linecolor('white')
-        #from collections import OrderedDict
-        #self.shapes = OrderedDict()
-        #self.shapes['wall'] = wall
-        #self.shapes['eraser'] = white_eraser
+        white_eraser = Curve(x, y)
+        white_eraser.set_linecolor('white')
+        from collections import OrderedDict
+        self.shapes = OrderedDict()
+        self.shapes['wall'] = wall
+        self.shapes['eraser'] = white_eraser
+
+    def geometric_features(self):
+        d = {'start': point(self.x1[0], self.y1[0]),
+             'end': point(self.x1[-1], self.y1[-1])}
+        return d
 
 
 class Wall2(Shape):
 class Wall2(Shape):
     def __init__(self, x, y, thickness, pattern='/'):
     def __init__(self, x, y, thickness, pattern='/'):
@@ -966,6 +986,8 @@ class Wall2(Shape):
         else:
         else:
             y1 = asarray(y, float)
             y1 = asarray(y, float)
 
 
+        self.x1 = x1;  self.y1 = y1
+
         # Displaced curve (according to thickness)
         # Displaced curve (according to thickness)
         x2 = x1.copy()
         x2 = x1.copy()
         y2 = y1.copy()
         y2 = y1.copy()
@@ -997,6 +1019,11 @@ class Wall2(Shape):
         y = [y1[-1]] + y2[-1::-1].tolist() + [y1[0]]
         y = [y1[-1]] + y2[-1::-1].tolist() + [y1[0]]
         self.shapes['wall'] = wall
         self.shapes['wall'] = wall
 
 
+    def geometric_features(self):
+        d = {'start': point(self.x1[0], self.y1[0]),
+             'end': point(self.x1[-1], self.y1[-1])}
+        return d
+
 
 
 class VelocityProfile(Shape):
 class VelocityProfile(Shape):
     def __init__(self, start, height, profile, num_arrows, scaling=1):
     def __init__(self, start, height, profile, num_arrows, scaling=1):
@@ -1046,6 +1073,9 @@ class Arrow1(Shape):
         arrow.set_arrow(style)
         arrow.set_arrow(style)
         self.shapes = {'arrow': arrow}
         self.shapes = {'arrow': arrow}
 
 
+    def geometric_features(self):
+        return self.shapes['arrow'].geometric_features()
+
 class Arrow3(Shape):
 class Arrow3(Shape):
     """
     """
     Build a vertical line and arrow head from Line objects.
     Build a vertical line and arrow head from Line objects.
@@ -1076,6 +1106,9 @@ class Arrow3(Shape):
         # must be initialized first
         # must be initialized first
         self.rotate(rotation_angle, start)
         self.rotate(rotation_angle, start)
 
 
+    def geometric_features(self):
+        return self.shapes['line'].geometric_features()
+
 
 
 class Text(Point):
 class Text(Point):
     """
     """
@@ -1157,6 +1190,8 @@ class Axis(Shape):
         label.rotate(rotation_angle, start)
         label.rotate(rotation_angle, start)
         self.shapes = {'arrow': arrow, 'label': label}
         self.shapes = {'arrow': arrow, 'label': label}
 
 
+    def geometric_features(self):
+        return self.shapes['arrow'].geometric_features()
 
 
 # Maybe Axis3 with label below/above?
 # Maybe Axis3 with label below/above?
 
 
@@ -1194,10 +1229,10 @@ class Force(Arrow1):
         self.shapes['text'] = Text(text, text_pos, fontsize=fontsize,
         self.shapes['text'] = Text(text, text_pos, fontsize=fontsize,
                                    alignment=text_alignment)
                                    alignment=text_alignment)
 
 
-        # Stored geometric features
-        self.start = start
-        self.end = end
-        self.symbol_location = text_pos
+    def geometric_features(self):
+        d = Arrow1.geometric_features(self)
+        d['symbol_location'] = self.shapes['text'].position
+        return d
 
 
 class Axis2(Force):
 class Axis2(Force):
     def __init__(self, start, length, label,
     def __init__(self, start, length, label,
@@ -1213,6 +1248,7 @@ class Axis2(Force):
         self.shapes['label'] = self.shapes['text']
         self.shapes['label'] = self.shapes['text']
         del self.shapes['text']
         del self.shapes['text']
 
 
+    # geometric features from Force is ok
 
 
 class Gravity(Axis):
 class Gravity(Axis):
     """Downward-pointing gravity arrow with the symbol g."""
     """Downward-pointing gravity arrow with the symbol g."""
@@ -1281,6 +1317,10 @@ class Distance_wText(Shape):
         arrow.set_linewidth(1)
         arrow.set_linewidth(1)
         self.shapes = {'arrow': arrow, 'text': text}
         self.shapes = {'arrow': arrow, 'text': text}
 
 
+    def geometric_features(self):
+        d = self.shapes['arrow'].geometric_features()
+        d['text_position'] = self.shapes['text'].position
+        return d
 
 
 class Arc_wText(Shape):
 class Arc_wText(Shape):
     def __init__(self, text, center, radius,
     def __init__(self, text, center, radius,
@@ -1326,9 +1366,12 @@ class SimplySupportedBeam(Shape):
                            'size': Distance_wText((P2[0], P2[1]-size),
                            'size': Distance_wText((P2[0], P2[1]-size),
                                                   (P2[0]+size, P2[1]-size),
                                                   (P2[0]+size, P2[1]-size),
                                                   'size')}
                                                   'size')}
-        # Stored geometric features
-        self.mid_support = point(P2[0] + size/2., P2[1])  # lower center
-        self.top = pos
+    def geometric_features(self):
+        t = self.shapes['triangle']
+        r = self.shapes['rectangle']
+        d = {'pos': point(t.x[2], t.y[2]),  # "p2"/pos
+             'mid_support': r.geometric_features()['lower_mid']}
+        return d
 
 
 
 
 class ConstantBeamLoad(Shape):
 class ConstantBeamLoad(Shape):
@@ -1356,8 +1399,9 @@ class ConstantBeamLoad(Shape):
             x = lower_left_corner[0] + i*dx
             x = lower_left_corner[0] + i*dx
             self.shapes['arrow%d' % i] = Arrow1((x, y_top), (x, y_tip))
             self.shapes['arrow%d' % i] = Arrow1((x, y_top), (x, y_tip))
 
 
-        # Stored geometric features
-        self.mid_top = arr2D(lower_left_corner) + point(width/2., height)
+    def geometric_features(self):
+        return {'mid_top': self.shapes['box'].geometric_features()['upper_mid']}
+
 
 
 class Moment(Arc_wText):
 class Moment(Arc_wText):
     def __init__(self, text, center, radius,
     def __init__(self, text, center, radius,
@@ -1427,19 +1471,6 @@ class Spring(Shape):
     bar are given sensible default values if they are not specified
     bar are given sensible default values if they are not specified
     (these parameters can later be extracted as attributes, see table
     (these parameters can later be extracted as attributes, see table
     below).
     below).
-
-    Recorded geometric features:
-
-    ==================== =============================================
-    Attribute            Description
-    ==================== =============================================
-    start                Start point of spring.
-    end                  End point of spring.
-    width                Total width of spring.
-    bar_length           Length of first (and last) bar part.
-    num_windings         Number of windings.
-    ==================== =============================================
-
     """
     """
     spring_fraction = 1./2  # fraction of total length occupied by spring
     spring_fraction = 1./2  # fraction of total length occupied by spring
 
 
@@ -1475,6 +1506,9 @@ class Spring(Shape):
             f = Spring.spring_fraction
             f = Spring.spring_fraction
             s = L*(1-f)/2. # start of spring
             s = L*(1-f)/2. # start of spring
 
 
+        self.bar_length = s  # record
+        self.width = 2*w
+
         P0 = (B[0], B[1] + s)
         P0 = (B[0], B[1] + s)
         P1 = (B[0], B[1] + L-s)
         P1 = (B[0], B[1] + L-s)
         P2 = (B[0], B[1] + L)
         P2 = (B[0], B[1] + L)
@@ -1516,12 +1550,25 @@ class Spring(Shape):
                 'bar_length2': blength2}
                 'bar_length2': blength2}
         self.dimensions = dims
         self.dimensions = dims
 
 
-        # Stored geometric features
-        self.start = B
-        self.end = P2
-        self.bar_length = s
-        self.width = 2*w
-        self.num_windings = num_windings
+    def geometric_features(self):
+        """
+        Recorded geometric features:
+
+        ==================== =============================================
+        Attribute            Description
+        ==================== =============================================
+        start                Start point of spring.
+        end                  End point of spring.
+        width                Total width of spring.
+        bar_length           Length of first (and last) bar part.
+        ==================== =============================================
+        """
+        b1 = self.shapes['bar1']
+        d = {'start': b1.geometric_features()['start'],
+             'end': self.shapes['bar2'].geometric_features()['end'],
+             'bar_length': self.bar_length,
+             'width': self.width}
+        return d
 
 
 
 
 class Dashpot(Shape):
 class Dashpot(Shape):
@@ -1536,22 +1583,9 @@ class Dashpot(Shape):
 
 
     If some of `dashpot_length`, `bar_length`, `width` or `piston_pos`
     If some of `dashpot_length`, `bar_length`, `width` or `piston_pos`
     are not given, suitable default values are calculated. Their
     are not given, suitable default values are calculated. Their
-    values can be extracted as attributes given in the table of
-    recorded geometric features.
-
-    Recorded geometric features:
+    values can be extracted as keys in the dict returned from
+    ``geometric_features``.
 
 
-    ==================== =============================================
-    Attribute            Description
-    ==================== =============================================
-    start                Start point of dashpot.
-    end                  End point of dashpot.
-    bar_length           Length of first bar (from start to spring).
-    dashpot_length       Length of dashpot middle part.
-    width                Total width of dashpot.
-    piston_pos           Position of piston in dashpot, relative to
-                         start[1] + bar_length.
-    ==================== =============================================
     """
     """
     dashpot_fraction = 1./2            # fraction of total_length
     dashpot_fraction = 1./2            # fraction of total_length
     piston_gap_fraction = 1./6         # fraction of width
     piston_gap_fraction = 1./6         # fraction of width
@@ -1609,7 +1643,7 @@ class Dashpot(Shape):
         if piston_pos < 0:
         if piston_pos < 0:
             piston_pos = 0
             piston_pos = 0
         elif piston_pos > dashpot_length:
         elif piston_pos > dashpot_length:
-            piston_pos = dashpot_length - piston_tickness
+            piston_pos = dashpot_length - piston_thickness
 
 
         abs_piston_pos = P0[1] + piston_pos
         abs_piston_pos = P0[1] + piston_pos
 
 
@@ -1623,6 +1657,11 @@ class Dashpot(Shape):
 
 
         self.shapes = shapes
         self.shapes = shapes
 
 
+        self.bar_length = s
+        self.width = 2*w
+        self.piston_pos = piston_pos
+        self.dashpot_length = dashpot_length
+
         # Dimensions
         # Dimensions
         start = Text_wArrow('start', (B[0]-1.5*w,B[1]-1.5*w), B)
         start = Text_wArrow('start', (B[0]-1.5*w,B[1]-1.5*w), B)
         width = Distance_wText((B[0]-w, B[1]-3.5*w), (B[0]+w, B[1]-3.5*w),
         width = Distance_wText((B[0]-w, B[1]-3.5*w), (B[0]+w, B[1]-3.5*w),
@@ -1631,6 +1670,8 @@ class Dashpot(Shape):
                                   'dashpot_length', text_pos=(B[0]+w,B[1]-w))
                                   'dashpot_length', text_pos=(B[0]+w,B[1]-w))
         blength = Distance_wText((B[0]-2*w, B[1]), (B[0]-2*w, P0[1]),
         blength = Distance_wText((B[0]-2*w, B[1]), (B[0]-2*w, P0[1]),
                                  'bar_length', text_pos=(B[0]-6*w,P0[1]-w))
                                  'bar_length', text_pos=(B[0]-6*w,P0[1]-w))
+        ppos    = Distance_wText((B[0]-2*w, P0[1]), (B[0]-2*w, P0[1]+piston_pos),
+                                 'piston_pos', text_pos=(B[0]-6*w,P0[1]+piston_pos-w))
         tlength = Distance_wText((B[0]+4*w, B[1]), (B[0]+4*w, B[1]+L),
         tlength = Distance_wText((B[0]+4*w, B[1]), (B[0]+4*w, B[1]+L),
                                  'total_length',
                                  'total_length',
                                  text_pos=(B[0]+4.5*w, B[1]+L-2*w))
                                  text_pos=(B[0]+4.5*w, B[1]+L-2*w))
@@ -1638,16 +1679,34 @@ class Dashpot(Shape):
         pp = Text('abs_piston_pos', (B[0]+7*w, abs_piston_pos), alignment='left')
         pp = Text('abs_piston_pos', (B[0]+7*w, abs_piston_pos), alignment='left')
         dims = {'start': start, 'width': width, 'dashpot_length': dplength,
         dims = {'start': start, 'width': width, 'dashpot_length': dplength,
                 'bar_length': blength, 'total_length': tlength,
                 'bar_length': blength, 'total_length': tlength,
-                'abs_piston_pos': Composition({'line': line, 'text': pp})}
+                'piston_pos': ppos,}
+        #'abs_piston_pos': Composition({'line': line, 'text': pp})}
         self.dimensions = dims
         self.dimensions = dims
 
 
-        # Stored geometric features
-        self.start = B
-        self.end = point(B[0], B[1]+L)
-        self.bar_length = s
-        self.dashpot_length = dashpot_length
-        self.piston_pos = abs_piston_pos
-        self.width = 2*w
+    def geometric_features(self):
+        """
+        Recorded geometric features:
+
+        ==================== =============================================
+        Attribute            Description
+        ==================== =============================================
+        start                Start point of dashpot.
+        end                  End point of dashpot.
+        bar_length           Length of first bar (from start to spring).
+        dashpot_length       Length of dashpot middle part.
+        width                Total width of dashpot.
+        piston_pos           Position of piston in dashpot, relative to
+                             start[1] + bar_length.
+        ==================== =============================================
+        """
+        d = {'start': self.shapes['line start'].geometric_features()['start'],
+             'end': self.shapes['piston']['line'].geometric_features()['start'],
+             'bar_length': self.bar_length,
+             'piston_pos': self.piston_pos,
+             'width': self.width,
+             'dashpot_length': self.dashpot_length,
+             }
+        return d
 
 
 # COMPOSITE types:
 # COMPOSITE types:
 # MassSpringForce: Line(horizontal), Spring, Rectangle, Arrow/Line(w/arrow)
 # MassSpringForce: Line(horizontal), Spring, Rectangle, Arrow/Line(w/arrow)
@@ -1655,10 +1714,11 @@ class Dashpot(Shape):
 # Maybe extra dict: self.name['mass'] = Rectangle object - YES!
 # Maybe extra dict: self.name['mass'] = Rectangle object - YES!
 
 
 def test_Axis():
 def test_Axis():
-    set_coordinate_system(xmin=0, xmax=15, ymin=0, ymax=15, axis=True,
-                          instruction_file='tmp_Axis.py')
+    drawing_tool.set_coordinate_system(
+        xmin=0, xmax=15, ymin=-7, ymax=8, axis=True,
+        instruction_file='tmp_Axis.py')
     x_axis = Axis((7.5,2), 5, 'x', rotation_angle=0)
     x_axis = Axis((7.5,2), 5, 'x', rotation_angle=0)
-    y_axis = Axis((7.5,2), 5, 'y', below=False, rotation_angle=90)
+    y_axis = Axis((7.5,2), 5, 'y', rotation_angle=90)
     system = Composition({'x axis': x_axis, 'y axis': y_axis})
     system = Composition({'x axis': x_axis, 'y axis': y_axis})
     system.draw()
     system.draw()
     drawing_tool.display()
     drawing_tool.display()
@@ -1806,7 +1866,7 @@ def test_Spring():
 
 
     xpos = W
     xpos = W
     s1 = Spring((W,0), L, teeth=True)
     s1 = Spring((W,0), L, teeth=True)
-    s1_title = Text('Default Spring', s1.end + point(0,L/10))
+    s1_title = Text('Default Spring', s1.geometric_features()['end'] + point(0,L/10))
     s1.draw()
     s1.draw()
     s1_title.draw()
     s1_title.draw()
     #s1.draw_dimensions()
     #s1.draw_dimensions()
@@ -1824,7 +1884,7 @@ def test_Dashpot():
     W = 2.0
     W = 2.0
     xpos = 0
     xpos = 0
 
 
-    drawing_tool.set_coordinate_system(xmin=xpos, xmax=xpos+6*W,
+    drawing_tool.set_coordinate_system(xmin=xpos, xmax=xpos+5.5*W,
                                        ymin=-L/2, ymax=1.5*L,
                                        ymin=-L/2, ymax=1.5*L,
                                        axis=True,
                                        axis=True,
                                        instruction_file='tmp_Dashpot.py')
                                        instruction_file='tmp_Dashpot.py')
@@ -1834,7 +1894,7 @@ def test_Dashpot():
     # Default (simple) dashpot
     # Default (simple) dashpot
     xpos = 1.5
     xpos = 1.5
     d1 = Dashpot(start=(xpos,0), total_length=L)
     d1 = Dashpot(start=(xpos,0), total_length=L)
-    d1_title = Text('Dashpot (default)', d1.end + point(0,L/10))
+    d1_title = Text('Dashpot (default)', d1.geometric_features()['end'] + point(0,L/10))
     d1.draw()
     d1.draw()
     d1_title.draw()
     d1_title.draw()
 
 
@@ -1850,6 +1910,50 @@ def test_Dashpot():
     drawing_tool.savefig('tmp_Dashpot.png')
     drawing_tool.savefig('tmp_Dashpot.png')
 
 
 
 
+def diff_files(files1, files2, mode='HTML'):
+    import difflib, time
+    n = 3
+    for fromfile, tofile in zip(files1, files2):
+        fromdate = time.ctime(os.stat(fromfile).st_mtime)
+        todate = time.ctime(os.stat(tofile).st_mtime)
+        fromlines = open(fromfile, 'U').readlines()
+        tolines = open(tofile, 'U').readlines()
+        diff_html = difflib.HtmlDiff().\
+                    make_file(fromlines,tolines,
+                              fromfile,tofile,context=True,numlines=n)
+        diff_plain = difflib.unified_diff(fromlines, tolines, fromfile, tofile, fromdate, todate, n=n)
+        filename_plain = fromfile + '.diff.txt'
+        filename_html = fromfile + '.diff.html'
+        if os.path.isfile(filename_plain):
+            os.remove(filename_plain)
+        if os.path.isfile(filename_html):
+            os.remove(filename_html)
+        f = open(filename_plain, 'w')
+        f.writelines(diff_plain)
+        f.close()
+        size = os.path.getsize(filename_plain)
+        if size > 4:
+            print 'found differences:', fromfile, tofile
+            f = open(filename_html, 'w')
+            f.writelines(diff_html)
+            f.close()
+
+
+def test_test():
+    os.chdir('test')
+    funcs = [name for name in globals() if name.startswith('test_') and callable(globals()[name])]
+    funcs.remove('test_test')
+    new_files = []
+    res_files = []
+    for func in funcs:
+        mplfile = func.replace('test_', 'tmp_') + '.py'
+        #exec(func + '()')
+        new_files.append(mplfile)
+        resfile = mplfile.replace('tmp_', 'res_')
+        res_files.append(resfile)
+    diff_files(new_files, res_files)
+
+
 def _test1():
 def _test1():
     set_coordinate_system(xmin=0, xmax=10, ymin=0, ymax=10)
     set_coordinate_system(xmin=0, xmax=10, ymin=0, ymax=10)
     l1 = Line((0,0), (1,1))
     l1 = Line((0,0), (1,1))