Ticket #6098: trac6098_bezier3d.patch
File trac6098_bezier3d.patch, 9.7 KB (added by , 14 years ago) |
---|
-
sage/graphs/graph_plot.py
# HG changeset patch # User Emily Kirkman <> # Date 1242874073 25200 # Node ID f49d216fe07bb1d352f380f77d4225c1e970bc2d # Parent 54cc8d2ba3ffdc64f99805b63edc5171844a0de6 3d bezier path implementation diff -r 54cc8d2ba3ff -r f49d216fe07b sage/graphs/graph_plot.py
a b 443 443 dist = self._options['dist']*2 444 444 loop_size = self._options['loop_size'] 445 445 max_dist = self._options['max_dist'] 446 from sage.calculus.calculus import SymbolicVariable446 447 447 from sage.calculus.calculus import sqrt as Sqrt 448 448 for (a,b) in tmp: 449 449 if a == b: -
sage/plot/bezier_path.py
diff -r 54cc8d2ba3ff -r f49d216fe07b sage/plot/bezier_path.py
a b 15 15 # 16 16 # http://www.gnu.org/licenses/ 17 17 #***************************************************************************** 18 from sage.plot.primitive import GraphicPrimitive 18 from sage.plot.primitive import GraphicPrimitive_xydata 19 19 from sage.plot.misc import options, to_mpl_color, rename_keyword 20 20 21 class BezierPath(GraphicPrimitive ):21 class BezierPath(GraphicPrimitive_xydata): 22 22 """ 23 23 Path of Bezier Curves graphics primitive. 24 24 """ … … 40 40 codes += (len(curve))*[len(curve)+1] 41 41 self.codes = codes 42 42 self.vertices = np.array(vertices, np.float) 43 GraphicPrimitive .__init__(self, options)43 GraphicPrimitive_xydata.__init__(self, options) 44 44 45 45 def _allowed_options(self): 46 46 """ … … 62 62 'thickness':'How thick the border of the polygon is.', 63 63 'rgbcolor':'The color as an rgb tuple.', 64 64 'zorder':'The layer level in which to draw', 65 'linestyle':"The style of the line, which is one of 'dashed', 'dotted', 'solid', 'dashdot'."} 66 65 'linestyle':"The style of the line, which is one of 'dashed', 'dotted', 'solid', 'dashdot'."} 66 67 def _plot3d_options(self, options=None): 68 """ 69 Updates BezierPath options to those allowed by 3d implementation. 70 71 EXAMPLES: 72 73 sage: from sage.plot.bezier_path import BezierPath 74 sage: B = BezierPath([[(0,0),(.5,.5),(1,0)],[(.5,1),(0,0)]],{'linestyle':'dashed'}) 75 sage: B._plot3d_options() 76 Traceback (most recent call last): 77 ... 78 NotImplementedError: Invalid 3d line style: dashed 79 sage: B = BezierPath([[(0,0),(.5,.5),(1,0)],[(.5,1),(0,0)]],{'fill':False, 'thickness':2}) 80 sage: B._plot3d_options() 81 {'thickness': 2} 82 """ 83 if options == None: 84 options = dict(self.options()) 85 options_3d = {} 86 if 'thickness' in options: 87 options_3d['thickness'] = options['thickness'] 88 del options['thickness'] 89 if 'fill' in options: 90 if options['fill']: 91 raise NotImplementedError, "Invalid 3d fill style. Must set fill to False." 92 del options['fill'] 93 if 'linestyle' in options: 94 if options['linestyle'] != 'solid': 95 raise NotImplementedError, "Invalid 3d line style: %s" % options['linestyle'] 96 del options['linestyle'] 97 options_3d.update(GraphicPrimitive_xydata._plot3d_options(self, options)) 98 return options_3d 99 100 def plot3d(self, **kwds): 101 """ 102 Returns a 3d plot (Jmol) of the bezier path. Since a BezierPath primitive contains 103 only x,y coordinates, the path will be drawn in the z=0 plane. To create a bezier path 104 with nonzero z coordinates in the path and control points, use the constructor bezier3d 105 instead of bezier_path. 106 107 EXAMPLES: 108 sage: b = bezier_path([[(0,0),(0,1),(1,0)]]) 109 sage: b.plot3d() 110 sage: bezier3d([[(0,0,0),(1,0,0),(0,1,0),(0,1,1)]]) 111 """ 112 from sage.plot.plot3d.shapes2 import bezier3d 113 options = self._plot3d_options() 114 options.update(kwds) 115 return bezier3d([[(x,y,0) for x,y in self.path[i]] for i in range(len(self.path))], **options) 116 67 117 def _repr_(self): 68 118 return "Bezier path from %s to %s"%(self.path[0][0],self.path[-1][-1]) 69 119 -
sage/plot/plot3d/all.py
diff -r 54cc8d2ba3ff -r f49d216fe07b sage/plot/plot3d/all.py
a b 6 6 7 7 from platonic import tetrahedron, cube, octahedron, dodecahedron, icosahedron 8 8 9 from shapes2 import sphere, line3d, polygon3d, point3d, text3d 9 from shapes2 import sphere, line3d, polygon3d, point3d, text3d, bezier3d 10 10 11 11 from shapes import arrow3d 12 12 -
sage/plot/plot3d/shapes2.py
diff -r 54cc8d2ba3ff -r f49d216fe07b sage/plot/plot3d/shapes2.py
a b 104 104 w._set_extra_kwds(kwds) 105 105 return w 106 106 107 @options(opacity=1, color="red", aspect_ratio=[1,1,1], thickness=2) 108 def bezier3d(path, **options): 109 """ 110 Draws a 3-dimensional bezier path. Input is similar to bezier_path, but each 111 point in the path and each control point is required to have 3 coordinates. 112 113 INPUT: 114 115 - ``path`` - a list of curves, which each is a list of points. See further 116 detail below. 117 118 - ``thickness`` - (default: 2) 119 120 - ``color`` - a word that describes a color 121 122 - ``opacity`` - (default: 1) if less than 1 then is 123 transparent 124 125 - ``aspect_ratio`` - (default:[1,1,1]) 126 127 The path is a list of curves, and each curve is a list of points. 128 Each point is a tuple (x,y,z). 129 130 The first curve contains the endpoints as the first and last point 131 in the list. All other curves assume a starting point given by the 132 last entry in the preceding list, and take the last point in the list 133 as their opposite endpoint. A curve can have 0, 1 or 2 control points 134 listed between the endpoints. In the input example for path below, 135 the first and second curves have 2 control points, the third has one, 136 and the fourth has no control points: 137 138 path = [[p1, c1, c2, p2], [c3, c4, p3], [c5, p4], [p5], ...] 139 140 In the case of no control points, a striaght line will be drawn 141 between the two endpoints. If one control point is supplied, then 142 the curve at each of the endpoints will be tangent to the line from 143 that endpoint to the control point. Similarly, in the case of two 144 control points, at each endpoint the curve will be tangent to the line 145 connecting that endpoint with the control point immediately after or 146 immediately preceding it in the list. 147 148 So in our example above, the curve between p1 and p2 is tangent to the 149 line through p1 and c1 at p1, and tangent to the line through p2 and c2 150 at p2. Similarly, the curve between p2 and p3 is tangent to line(p2,c3) 151 at p2 and tangent to line(p3,c4) at p3. Curve(p3,p4) is tangent to 152 line(p3,c5) at p3 and tangent to line(p4,c5) at p4. Curve(p4,p5) is a 153 straight line. 154 155 EXAMPLES: 156 sage: path = [[(0,0,0),(.5,.1,.2),(.75,3,-1),(1,1,0)],[(.5,1,.2),(1,.5,0)],[(.7,.2,.5)]] 157 sage: b = bezier3d(path, color='green') 158 sage: b 159 160 To construct a simple curve, create a list containing a single list: 161 162 sage: path = [[(0,0,0),(1,0,0),(0,1,0),(0,1,1)]] 163 sage: curve = bezier3d(path, thickness=5, color='blue') 164 sage: curve 165 """ 166 import parametric_plot3d as P3D 167 from sage.modules.free_module_element import vector 168 from sage.calculus.calculus import SymbolicVariable 169 170 p0 = vector(path[0][-1]) 171 t = SymbolicVariable('t') 172 if len(path[0]) > 2: 173 B = (1-t)**3*vector(path[0][0])+3*t*(1-t)**2*vector(path[0][1])+3*t**2*(1-t)*vector(path[0][-2])+t**3*p0 174 G = P3D.parametric_plot3d(list(B), (0, 1), color=options['color'], aspect_ratio=options['aspect_ratio'], thickness=options['thickness'], opacity=options['opacity']) 175 else: 176 G = line3d([path[0][0], p0], color=options['color'], thickness=options['thickness'], opacity=options['opacity']) 177 178 for curve in path[1:]: 179 if len(curve) > 1: 180 p1 = vector(curve[0]) 181 p2 = vector(curve[-2]) 182 p3 = vector(curve[-1]) 183 B = (1-t)**3*p0+3*t*(1-t)**2*p1+3*t**2*(1-t)*p2+t**3*p3 184 G += P3D.parametric_plot3d(list(B), (0, 1), color=options['color'], aspect_ratio=options['aspect_ratio'], thickness=options['thickness'], opacity=options['opacity']) 185 else: 186 G += line3d([p0,curve[0]], color=options['color'], thickness=options['thickness'], opacity=options['opacity']) 187 p0 = curve[-1] 188 return G 189 107 190 @rename_keyword(alpha='opacity') 108 191 @options(opacity=1, color=(0,0,1)) 109 192 def polygon3d(points, **options): -
sage/plot/primitive.py
diff -r 54cc8d2ba3ff -r f49d216fe07b sage/plot/primitive.py
a b 103 103 if 'alpha' in options: 104 104 options_3d['opacity'] = options['alpha'] 105 105 del options['alpha'] 106 if 'zorder' in options: 107 del options['zorder'] 106 108 if len(options) != 0: 107 109 raise NotImplementedError, "Unknown plot3d equivalent for %s" % ", ".join(options.keys()) 108 110 return options_3d