Hans Petter Langtangen před 13 roky
rodič
revize
ea9d794325

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

@@ -1,17 +0,0 @@
-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.

+ 1 - 1
doc/src/sketcher/make.sh

@@ -31,7 +31,7 @@ pdflatex -shell-escape $main
 doconce format sphinx $main --skip_inline_comments
 rm -rf sphinx-rootdir
 doconce sphinx_dir author="H. P. Langtangen" version=0.1 theme=pyramid $main
-python automake-sphinx.py
+python automake_sphinx.py
 
 cp ${main}_primer.pdf ../../tutorial/pysketcher_blue.pdf
 cp ${main}.pdf ../../tutorial/pysketcher.pdf

+ 51 - 0
doc/src/sketcher/src-sketcher/fd_demo.py

@@ -0,0 +1,51 @@
+from pysketcher import *
+
+#test_test()
+drawing_tool.set_coordinate_system(0, 7, 2, 6, axis=False)
+
+f = SketchyFunc1('$f(x)$')
+x = 3                 # center point where we want the derivative
+xb = 2                # x point used for backward difference
+xf = 4                # x point used for forward difference
+p = (x, f(x))         # center point
+pf = (xf, f(xf))      # forward point
+pb = (xb, f(xb))      # backward point
+r = 0.1               # radius of circles placed at key points
+c = Circle(p, r).set_linecolor('blue')
+cf = Circle(pf, r).set_linecolor('red')
+cb = Circle(pb, r).set_linecolor('green')
+domain = [1, 5]
+domain2 = [2, 5]
+lf = Line(p, pf).new_interval(x=domain2).set_linestyle('dashed').set_linecolor('red')
+lb = Line(pb, p).new_interval(x=domain).set_linestyle('dashed').set_linecolor('green')
+lc = Line(pb, pf).new_interval(x=domain).set_linestyle('dashed').set_linecolor('blue')
+h = 1E-3
+le = Line((x+h, f(x+h)), (x-h, f(x-h))).new_interval(x=domain).set_linestyle('dotted').set_linecolor('black')
+
+forward = Composition(dict(tangent=lf, point1=c, point2=cf,
+                      name=Text('forward',
+                                lf.geometric_features()['end'] + point(0.1,0),
+                                alignment='left')))
+backward = Composition(dict(tangent=lb, point1=c, point2=cb,
+                      name=Text('backward',
+                                lb.geometric_features()['end'] + point(0.1,0),
+                                alignment='left')))
+centered = Composition(dict(tangent=lc, point1=cb, point2=cf,
+                       name=Text('centered',
+                                 lc.geometric_features()['end'] + point(0.1,0),
+                                 alignment='left')))
+
+exact = Composition(dict(graph=f, tangent=le))
+forward = Composition(dict(difference=forward, exact=exact)).set_name('forward')
+backward = Composition(dict(difference=backward, exact=exact)).set_name('backward')
+centered = Composition(dict(difference=centered, exact=exact)).set_name('centered')
+all = Composition(dict(exact=exact, forward=forward, backward=backward,
+                       centered=centered)).set_name('all')
+
+for fig in all, forward, backward, centered:
+    drawing_tool.erase()
+    fig.draw()
+    drawing_tool.display()
+    drawing_tool.savefig(fig.get_name())
+raw_input()
+

+ 39 - 0
doc/src/sketcher/src-sketcher/fd_func.py

@@ -0,0 +1,39 @@
+from pysketcher import *
+
+u = SketchyFunc1('$u(t)$', name_pos='end')
+t_mesh = [0, 2, 4, 6, 8]
+
+u = SketchyFunc2('$u(t)$', name_pos='end')
+n = 7
+t_mesh = [i*2.25/(n-1) for i in range(n)]
+
+t_min1 = t_mesh[0] - 0.2*(t_mesh[-1] - t_mesh[0])
+t_max1 = t_mesh[-1] + 0.2*(t_mesh[-1] - t_mesh[0])
+t_min2 = t_mesh[0] - 0.3*(t_mesh[-1] - t_mesh[0])
+t_max2 = t_mesh[-1] + 0.3*(t_mesh[-1] - t_mesh[0])
+u_max = 1.3*max([u(t) for t in t_mesh])
+u_min = -0.2*u_max
+
+drawing_tool.set_coordinate_system(t_min2, t_max2, u_min, u_max, axis=False)
+drawing_tool.set_linecolor('black')
+
+r = 0.005*(t_max2-t_min2)     # radius of circles placed at mesh points
+discrete_u = Composition({i: Circle(point(t, u(t)), r).\
+                          set_filled_curves('black')
+                          for i, t in enumerate(t_mesh)})
+print repr(discrete_u)
+axes = Composition(dict(x=Axis(point(0,0), t_max2, '$t$'),
+                        y=Axis(point(0,0), 0.8*u_max, '$u$',
+                               rotation_angle=90)))
+h = 0.03*u_max  # tickmarks height
+nodes = Composition({i: Composition(dict(
+    node=Line(point(t,h), point(t,-h)),
+    name=Text('$t_%d$' % i, point(t,-3.5*h))))
+                     for i, t in enumerate(t_mesh)})
+fig = Composition(dict(u=discrete_u, mesh=nodes, axes=axes)).set_name('fdm_u')
+drawing_tool.erase()
+fig.draw()
+drawing_tool.display()
+drawing_tool.savefig(fig.get_name())
+raw_input()
+

+ 0 - 35
doc/src/sketcher/src-sketcher/fdm.py

@@ -1,35 +0,0 @@
-from pysketcher import *
-
-#test_test()
-drawing_tool.set_coordinate_system(0, 7, 0, 8, axis=True)
-
-f = SketchyFunc('$f(x)$')
-x = 3
-xb = 2
-xf = 4
-p = (x, f(x))
-pf = (xf, f(xf))
-pb = (xb, f(xb))
-r = 0.1
-c = Circle(p, r).set_linecolor('blue')
-cf = Circle(pf, r).set_linecolor('blue')
-cb = Circle(pb, r).set_linecolor('blue')
-domain = [1, 5]
-domain2 = [2, 5]
-lf = Line(p, pf).new_interval(x=domain2).set_linestyle('dashed').set_linecolor('blue')
-lb = Line(pb, p).new_interval(x=domain).set_linestyle('dashed').set_linecolor('blue')
-lc = Line(pb, pf).new_interval(x=domain).set_linestyle('dashed').set_linecolor('blue')
-h = 1E-3
-le = Line((x+h, f(x+h)), (x-h, f(x-h))).new_interval(x=domain).set_linestyle('dotted').set_linecolor('black')
-
-f.draw()
-c.draw()
-cb.draw()
-cf.draw()
-lf.draw()
-lb.draw()
-lc.draw()
-le.draw()
-drawing_tool.display()
-raw_input()
-

+ 20 - 12
pysketcher/shapes.py

@@ -139,6 +139,13 @@ class Shape:
             'Do not call Shape.__init__!' % \
             self.__class__.__name__)
 
+    def set_name(self, name):
+        self.name = name
+        return self
+
+    def get_name(self):
+        return self.name if hasattr(self, 'name') else None
+
     def __iter__(self):
         # We iterate over self.shapes many places, and will
         # get here if self.shapes is just a Shape object and
@@ -546,10 +553,6 @@ class Curve(Shape):
         self.arrow = style
         return self
 
-    def set_name(self, name):
-        self.name = name
-        return self
-
     def set_filled_curves(self, color='', pattern=''):
         self.fillcolor = color
         self.fillpattern = pattern
@@ -606,32 +609,37 @@ class SketchyFunc1(Spline):
     """
     A typical function curve used to illustrate an "arbitrary" function.
     """
-    def __init__(self, name=None):
+    domain = [1, 6]
+    def __init__(self, name=None, name_pos='start'):
         x = [1, 2,   3,   4, 5,   6]
         y = [5, 3.5, 3.8, 3, 2.5, 2.4]
         Spline.__init__(self, x, y)
         self.shapes['smooth'].set_linecolor('black')
         if name is not None:
-            self.shapes['name'] = Text(name, self.geometric_features()['start'] + point(0,0.1))
+            self.shapes['name'] = Text(name, self.geometric_features()[name_pos] + point(0,0.1))
 
 
 class SketchyFunc2(Shape):
     """
     A typical function curve used to illustrate an "arbitrary" function.
     """
-    def __init__(self, name=None):
-        def f(x):
-            return 0.5+x*(2-x)*(0.9-x) # on [0, 2.25]
+    domain = [0, 2.25]
+    def __init__(self, name=None, name_pos='end'):
 
         a = 0; b = 2.25
         resolution = 100
-        x = np.linspace(a, b, resolution+1)
+        x = linspace(a, b, resolution+1)
+        f = self  # for calling __call__
         y = f(x)
-        self.shapes['smooth'] = Curve(x, y)
+        self.shapes = {'smooth': Curve(x, y)}
         self.shapes['smooth'].set_linecolor('black')
+
+        pos = point(a, f(a)) if name_pos == 'start' else point(b, f(b))
         if name is not None:
-            self.shapes['name'] = Text(name, point(b, y(b)) + point(0,0.1))
+            self.shapes['name'] = Text(name, pos + point(0,0.1))
 
+    def __call__(self, x):
+        return 0.5+x*(2-x)*(0.9-x) # on [0, 2.25]
 
 class Point(Shape):
     """A point (x,y) which can be rotated, translated, and scaled."""