Changeset 662
- Timestamp:
- 08/19/03 00:52:30 (5 years ago)
- Files:
-
- trunk/RBRapier/RBRapier/Formats/Attic/SVG.old/Renderers/RapierObjects.py (modified) (2 diffs)
- trunk/RBRapier/RBRapier/Formats/Attic/SVG.old/SVGSkin/RenderItems/Groups.py (modified) (1 diff)
- trunk/RBRapier/RBRapier/Formats/SVG/RapierRenderItems.py (modified) (8 diffs)
- trunk/RBRapier/RBRapier/Formats/SVG/SVGSkin/SVGItems/PathBuilder.py (modified) (6 diffs)
- trunk/RBRapier/RBRapier/Tools/Geometry/Curves.py (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/RBRapier/RBRapier/Formats/Attic/SVG.old/Renderers/RapierObjects.py
r643 r662 27 27 from OpenGL import GL 28 28 29 from RBRapier.Tools.Geometry import Curves 29 30 from RBRapier.Tools.Geometry.gluPolygonTesselation import gluPolygonTesselator 30 31 … … 186 187 187 188 class RapierPathFactory(Abstract.AbstractPathFactory): 188 __slots__ = 'pos', 'pathlist' 189 steps = 64 190 pos = (0,0) 191 controlpoint = None 192 193 command_table = { 194 'M': 'move', 195 'm': 'move_rel', 196 'Z': 'closepath', 197 'z': 'closepath', 198 'L': 'line', 199 'l': 'line_rel', 200 'H': 'hline', 201 'h': 'hline_rel', 202 'V': 'vline', 203 'v': 'vline_rel', 204 'C': 'cubicbezier', 205 'c': 'cubicbezier_rel', 206 'S': 'smoothcurve', 207 's': 'smoothcurve_rel', 208 'Q': 'quadraticbezier', 209 'q': 'quadraticbezier_rel', 210 'T': 'smoothquadraticbezier', 211 't': 'smoothquadraticbezier_rel', 212 'A': 'ellipticarc', 213 'a': 'ellipticarc_rel'} 189 214 190 215 def BeginPath(self, pathstr): 191 216 self.pathlist = [] 192 self.pos = 0., 0.193 217 194 218 def AddPathElement(self, name, *args): 195 name, relative = self.command_table[name] 196 getattr(self, name.lower())(relative, *args) 219 name = self.command_table.get(name, '') 220 transformfn = getattr(self, name, None) 221 if transformfn is not None: 222 transformfn(*args) 197 223 198 224 def EndPath(self, pathstr): 199 225 pass 200 226 201 def move(self, relative, x, y): 202 if relative: 203 dx, dy = self.pos 204 x += dx 205 y += dy 206 self.pathlist.append([(x,y)]) 207 self.pos = x,y 208 209 def closepath(self, relative): 210 lastpath = self.pathlist[-1] 211 self.pos = lastpath[0] 212 lastpath.append(self.pos) 213 214 def line(self, relative, x, y): 215 if relative: 216 dx, dy = self.pos 217 x += dx 218 y += dy 227 def move_rel(self, x, y): 228 dx, dy = self.pos 229 return self.move(x+dx, y+dy) 230 def move(self, x, y): 231 if not self.pathlist or self.pathlist[-1]: 232 self.pathlist.append([(x,y)]) 233 else: 234 self.pathlist[-1][:] = [(x,y)] 235 self._savepos((x,y)) 236 237 def closepath(self): 238 if self.pathlist[-1]: 239 lastpath = self.pathlist[-1] 240 pos = lastpath[0] 241 lastpath.append(pos) 242 self.pathlist.append([]) 243 self._savepos(pos) 244 245 def line_rel(self, x, y): 246 dx, dy = self.pos 247 return self.line(x+dx, y+dy) 248 def line(self, x, y): 219 249 self.pathlist[-1].append((x,y)) 220 self.pos = x,y 221 222 def hline(self, relative, x): 223 dx, y = self.pos 224 if relative: 225 x += dx 250 self._savepos((x,y)) 251 252 def hline_rel(self, x): 253 dx = self.pos[0] 254 return self.hline(x+dx) 255 def hline(self, x): 256 y = self.pos[1] 226 257 self.pathlist[-1].append((x,y)) 227 self.pos = x,y 228 229 def vline(self, relative, y): 230 x, dy = self.pos 231 if relative: 232 y += dy 258 self._savepos((x,y)) 259 260 def vline_rel(self, y): 261 dy = self.pos[1] 262 return self.vline(y+dy) 263 def vline(self, y): 264 x = self.pos[0] 233 265 self.pathlist[-1].append((x,y)) 234 self.pos = x,y 235 236 def cubicbezier(self, relative, x1, y1, x2, y2, x, y): 237 if relative: 238 dx, dy = self.pos 239 x1 += dx 240 y1 += dy 241 x2 += dx 242 y2 += dy 243 x += dx 244 y += dy 245 warnings.warn( "TODO: path.cubicbezier") 246 self.pathlist[-1].append((x,y)) 247 self.pos = x,y 248 249 def smoothcurve(self, relative, x2, y2, x, y): 250 if relative: 251 dx, dy = self.pos 252 x2 += dx 253 y2 += dy 254 x += dx 255 y += dy 256 warnings.warn( "TODO: path.smoothcurve") 257 self.pathlist[-1].append((x,y)) 258 self.pos = x,y 259 260 def quadraticbezier(self, relative, x1, y1, x, y): 261 if relative: 262 dx, dy = self.pos 263 x1 += dx 264 y1 += dy 265 x += dx 266 y += dy 267 warnings.warn( "TODO: path.quadraticbezier") 268 self.pathlist[-1].append((x,y)) 269 self.pos = x,y 270 271 def smoothquadraticbezier(self, relative, x, y): 272 if relative: 273 dx, dy = self.pos 274 x += dx 275 y += dy 276 warnings.warn( "TODO: path.smoothquadraticbezier") 277 self.pathlist[-1].append((x,y)) 278 self.pos = x,y 279 280 def ellipticarc(self, relative, rx, ry, xrotation, largeArcFlag, sweepFlag, x, y): 281 if relative: 282 dx, dy = self.pos 283 x += dx 284 y += dy 285 warnings.warn( "TODO: path.ellipticarc") 286 self.pathlist[-1].append((x,y)) 287 self.pos = x,y 266 self._savepos((x,y)) 267 268 def cubicbezier_rel(self, x1, y1, x2, y2, x, y): 269 dx, dy = self.pos 270 return self.cubicbezier(x1+dx, y1+dy, x2+dx, y2+dy, x+dx, y+dy) 271 def cubicbezier(self, x1, y1, x2, y2, x, y): 272 bezier = Curves.CubicBezier(self.pos, (x1, y1), (x2, y2), (x, y), steps=self.steps) 273 self.pathlist[-1].extend(list(bezier)) 274 self._savepos((x,y), (x2, y2)) 275 276 def smoothcurve_rel(self, x2, y2, x, y): 277 dx, dy = self.pos 278 return self.smoothcurve(x2+dx, y2+dy, x+dx, y+dy) 279 def smoothcurve(self, x2, y2, x, y): 280 x1r, y1r = self._getControlPoint() 281 return self.cubicbezier(x1r, y1r, x2, y2, x, y) 282 283 def quadraticbezier_rel(self, x1, y1, x, y): 284 dx, dy = self.pos 285 return self.quadraticbezier(x1+dx, y1+dy, x+dx, y+dy) 286 def quadraticbezier(self, x1, y1, x, y): 287 bezier = Curves.QuadraticBezier(self.pos, (x1, y1), (x, y), steps=self.steps) 288 self.pathlist[-1].extend(list(bezier)) 289 self._savepos((x,y), (x1,y1)) 290 291 def smoothquadraticbezier_rel(self, x, y): 292 dx, dy = self.pos 293 return self.smoothquadraticbezier(x+dx, y+dy) 294 def smoothquadraticbezier(self, x, y): 295 x1r, y1r = self._getControlPoint() 296 return self.quadraticbezier(x1r, y1r, x, y) 297 298 def ellipticarc_rel(self, rx, ry, xrotation, largeArcFlag, sweepFlag, x, y): 299 dx, dy = self.pos 300 return self.ellipticarc_rel(rx, ry, xrotation, largeArcFlag, sweepflag, x+dx, y+dy) 301 def ellipticarc(self, rx, ry, xrotation, largeArcFlag, sweepFlag, x, y): 302 ellipse = Curves.Ellipse.fromArc(self.pos, (x,y), rx, ry, xrotation, largeArcFlag, sweepFlag, inDegrees=True, steps=self.steps) 303 self.pathlist[-1].extend(list(ellipse)) 304 self._savepos((x,y)) 305 306 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 307 308 def _savepos(self, pos, controlpoint=None): 309 self.pos = pos 310 self.controlpoint = controlpoint 311 312 def _getControlPoint(self): 313 if self.controlpoint is None: 314 return self.pos 315 else: 316 x,y = self.pos 317 xcp, ycp = self.controlpoint 318 return 2*x-xcp, 2*y-ycp 288 319 289 320 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ trunk/RBRapier/RBRapier/Formats/Attic/SVG.old/SVGSkin/RenderItems/Groups.py
r656 r662 83 83 raise ValueError, '"height" attribute can not be negative"' 84 84 self._height = height 85 #height = property(GetHeight, SetHeight)85 height = property(GetHeight, SetHeight) 86 86 87 87 def GetViewBox(self): trunk/RBRapier/RBRapier/Formats/SVG/RapierRenderItems.py
r660 r662 35 35 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 36 36 37 NumericType = Numeric.Float3237 _NumericType = Numeric.Float32 38 38 39 39 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ … … 45 45 self._style = {} 46 46 map(self._style.update, styles) 47 48 def copy(self): 49 result = self.__class__() 50 result._style = self._style.copy() 51 52 def __iadd__(self, other): 53 self._style.update(other._style) 54 return self 47 55 48 56 def __add__(self, other): … … 70 78 71 79 class Transform(Transformations2d.Composite): 80 def copy(self): 81 result = self.__class__() 82 result.collection = self.collection[:] 83 72 84 def translate(self, x=0.0, y=0.0): 73 85 self.Add(Transformations2d.Translate((x,y))) … … 107 119 fromSVGTransforms = classmethod(fromSVGTransforms) 108 120 109 def TransformPoints(points, transform=None): 110 points = Numeric.asarray(points, NumericType) 111 112 if transform is None: 113 return points 114 else: 115 # add the homogeneous coordinate 116 points = Numeric.concatenate((points, Numeric.ones((len(points), 1), NumericType)), 1) 117 result = Numeric.transpose(Numeric.dot(transform.asArray3x3(), Numeric.transpose(points))) 118 return result[:,:-1] # trim the homogenous coordinate -- assumes that they are all still 1. 119 121 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 122 123 class PathConnector(object): 124 pos = (0,0) 125 controlpoint = None 126 steps = 64 127 128 command_table = { 129 'M': 'move', 130 'm': 'move_rel', 131 'Z': 'closepath', 132 'z': 'closepath', 133 'L': 'line', 134 'l': 'line_rel', 135 'H': 'hline', 136 'h': 'hline_rel', 137 'V': 'vline', 138 'v': 'vline_rel', 139 'C': 'cubicbezier', 140 'c': 'cubicbezier_rel', 141 'S': 'smoothcurve', 142 's': 'smoothcurve_rel', 143 'Q': 'quadraticbezier', 144 'q': 'quadraticbezier_rel', 145 'T': 'smoothquadraticbezier', 146 't': 'smoothquadraticbezier_rel', 147 'A': 'ellipticarc', 148 'a': 'ellipticarc_rel'} 149 150 def __init__(self): 151 self.pathlist = [] 152 153 def AddSVGPath(self, path): 154 def AddPathElement(commandidx, *args): 155 name = self.command_table.get(name, '') 156 transformfn = getattr(self, name, None) 157 if transformfn is not None: 158 transformfn(*args) 159 path.RestoreToEx(onadd=AddPathElement) 160 161 def fromSVGPath(klass, path): 162 result = klass() 163 result.AddSVGPath(path) 164 return result 165 fromSVGPath = classmethod(fromSVGPath) 166 167 def move_rel(self, x, y): 168 dx, dy = self.pos 169 return self.move(x+dx, y+dy) 170 def move(self, x, y): 171 if not self.pathlist or self.pathlist[-1]: 172 self.pathlist.append([(x,y)]) 173 else: 174 self.pathlist[-1][:] = [(x,y)] 175 self._savepos((x,y)) 176 177 def closepath(self): 178 if self.pathlist[-1]: 179 lastpath = self.pathlist[-1] 180 pos = lastpath[0] 181 lastpath.append(pos) 182 self.pathlist.append([]) 183 self._savepos(pos) 184 185 def line_rel(self, x, y): 186 dx, dy = self.pos 187 return self.line(x+dx, y+dy) 188 def line(self, x, y): 189 self.pathlist[-1].append((x,y)) 190 self._savepos((x,y)) 191 192 def hline_rel(self, x): 193 dx = self.pos[0] 194 return self.hline(x+dx) 195 def hline(self, x): 196 y = self.pos[1] 197 self.pathlist[-1].append((x,y)) 198 self._savepos((x,y)) 199 200 def vline_rel(self, y): 201 dy = self.pos[1] 202 return self.vline(y+dy) 203 def vline(self, y): 204 x = self.pos[0] 205 self.pathlist[-1].append((x,y)) 206 self._savepos((x,y)) 207 208 def cubicbezier_rel(self, x1, y1, x2, y2, x, y): 209 dx, dy = self.pos 210 return self.cubicbezier(x1+dx, y1+dy, x2+dx, y2+dy, x+dx, y+dy) 211 def cubicbezier(self, x1, y1, x2, y2, x, y): 212 bezier = Curves.CubicBezier(self.pos, (x1, y1), (x2, y2), (x, y), steps=self.steps) 213 self.pathlist[-1].extend(list(bezier)) 214 self._savepos((x,y), (x2, y2)) 215 216 def smoothcurve_rel(self, x2, y2, x, y): 217 dx, dy = self.pos 218 return self.smoothcurve(x2+dx, y2+dy, x+dx, y+dy) 219 def smoothcurve(self, x2, y2, x, y): 220 x1r, y1r = self._getControlPoint() 221 return self.cubicbezier(x1r, y1r, x2, y2, x, y) 222 223 def quadraticbezier_rel(self, x1, y1, x, y): 224 dx, dy = self.pos 225 return self.quadraticbezier(x1+dx, y1+dy, x+dx, y+dy) 226 def quadraticbezier(self, x1, y1, x, y): 227 bezier = Curves.QuadraticBezier(self.pos, (x1, y1), (x, y), steps=self.steps) 228 self.pathlist[-1].extend(list(bezier)) 229 self._savepos((x,y), (x1,y1)) 230 231 def smoothquadraticbezier_rel(self, x, y): 232 dx, dy = self.pos 233 return self.smoothquadraticbezier(x+dx, y+dy) 234 def smoothquadraticbezier(self, x, y): 235 x1r, y1r = self._getControlPoint() 236 return self.quadraticbezier(x1r, y1r, x, y) 237 238 def ellipticarc_rel(self, rx, ry, xrotation, largeArcFlag, sweepFlag, x, y): 239 dx, dy = self.pos 240 return self.ellipticarc_rel(rx, ry, xrotation, largeArcFlag, sweepflag, x+dx, y+dy) 241 def ellipticarc(self, rx, ry, xrotation, largeArcFlag, sweepFlag, x, y): 242 ellipse = Curves.Ellipse.fromArc(self.pos, (x,y), rx, ry, xrotation, largeArcFlag, sweepFlag, inDegrees=True, steps=self.steps) 243 self.pathlist[-1].extend(list(ellipse)) 244 self._savepos((x,y)) 245 246 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 247 248 def _savepos(self, pos, controlpoint=None): 249 self.pos = pos 250 self.controlpoint = controlpoint 251 252 def _getControlPoint(self): 253 if self.controlpoint is None: 254 return self.pos 255 else: 256 x,y = self.pos 257 xcp, ycp = self.controlpoint 258 return 2*x-xcp, 2*y-ycp 259 260 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 261 262 class GLGeometry(object): 263 def SetPoints(self, points, transform=None): 264 points = Numeric.asarray(points, _NumericType) 265 if transform is not None: 266 # add the homogeneous coordinate 267 points = Numeric.concatenate((points, Numeric.ones((len(points), 1), _NumericType)), 1) 268 points = Numeric.transpose(Numeric.dot(transform.asArray3x3(), Numeric.transpose(points))) 269 points = result[:,:-1] # trim the homogenous coordinate -- assumes that they are all still 1. 270 self.points = points 271 272 def SetSingleColor(self, color): 273 assert self.points, "SetPoints must be called before SetSingleColor" 274 self.SetColors([color]*len(self.points)) 275 276 def SetColors(self, colors): 277 self.colors = Numeric.asarray(colors, _NumericType) 278 279 class GLStroke(GLGeometry): 280 def AddLines(self, indexes): 281 pass 282 283 def AddLineStrip(self, indexes): 284 pass 285 286 class GLFill(GLGeometry): 287 def AddTriles(self, indexes): 288 pass 289 290 def AddTriStrip(self, indexes): 291 pass 292 293 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 294 #~ Render Items 120 295 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 121 296 … … 135 310 pass 136 311 #style, transform = self._GetStyleAndTransform(style, transform) 137 138 def CountItems(self):139 return 1140 def CountGroups(self):141 return 0142 312 143 313 #~ SVG Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ … … 161 331 def _GetStyleAndTransform(self, style=None, transform=None): 162 332 if style is None: 163 style = self.style 333 style = self.style.copy() 164 334 elif self.style is not None: 165 style = style +self.style335 style += self.style 166 336 if transform is None: 167 transform = self.transform 337 transform = self.transform.copy() 168 338 elif self.transform is not None: 169 transform = transform *self.transform339 transform *= self.transform 170 340 return style, transform 171 341 … … 179 349 for child in self.children: 180 350 child.Compile(style, transform) 181 182 def CountItems(self):183 return reduce(int.__add__, [x.CountItems() for x in self.children], 0)184 def CountGroups(self):185 return reduce(int.__add__, [x.CountGroups() for x in self.children], 1)186 351 187 352 def SetChildren(self, children): … … 270 435 271 436 class Path(RenderItem): 272 Curves.QuadraticBezier273 Curves.CubicBezier274 Curves.EllipticArc275 Curves.Ellipse276 437 #~ SVG Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 277 438 trunk/RBRapier/RBRapier/Formats/SVG/SVGSkin/SVGItems/PathBuilder.py
r660 r662 99 99 } 100 100 101 def BeginPath(self, path str):101 def BeginPath(self, pathcmd): 102 102 raise NotImplementedError 103 def AddPathElement(self, name, relative,*args):103 def AddPathElement(self, name, *args): 104 104 raise NotImplementedError 105 def EndPath(self, path str):105 def EndPath(self, pathcmd): 106 106 raise NotImplementedError 107 107 … … 130 130 131 131 class SavePathFactory(AbstractPathFactory): 132 __slots__ = ('path str', 'pathelements')133 134 def BeginPath(self, path str):135 self.path str = pathstr136 self.path elements= []132 __slots__ = ('pathcmd', 'path') 133 134 def BeginPath(self, pathcmd): 135 self.pathcmd = pathcmd 136 self.path = [] 137 137 138 138 def AddPathElement(self, *args): 139 self.path elements.append(args)139 self.path.append(args) 140 140 141 def EndPath(self, path str):142 assert self.pathstr is pathstr141 def EndPath(self, pathcmd): 142 pass 143 143 144 144 def RestoreTo(self, pathfactory): 145 pathfactory.BeginPath(self.pathstr)146 for args in self.pathelements:147 pathfactory.AddPathElement(*args)148 pathfactory.EndPath(self.pathstr)145 self.RestoreToEx( 146 onbegin=transformfactory.BeginPath, 147 onadd=transformfactory.AddPathElement, 148 onend=transformfactory.EndPath) 149 149 return pathfactory 150 151 def RestoreToEx(self, onbegin=lambda xformcmd:None, onadd=lambda name, *args:None, onend=lambda xformcmd:None): 152 onbegin(self.transformcmd) 153 for args in self.path: 154 onadd(*args) 155 onend(self.transformcmd) 150 156 151 157 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ … … 206 212 return list(self.Build(*args, **kw)) 207 213 208 def Build(self, path str, pathfactory=None):214 def Build(self, pathcmd, pathfactory=None): 209 215 pathfactory = pathfactory or self.pathfactory 210 216 211 pathfactory.BeginPath(path str)217 pathfactory.BeginPath(pathcmd) 212 218 213 219 matchidx = 0 214 220 # MoveTo absolute is the default command 215 221 commandidx = 'M' 216 while matchidx < len(path str):222 while matchidx < len(pathcmd): 217 223 # Find out what command we're dealing with 218 commandmatch = self._re_command.match(path str, matchidx)224 commandmatch = self._re_command.match(pathcmd, matchidx) 219 225 if commandmatch is not None: 220 226 commandidx = commandmatch.groups()[0] or commandidx … … 224 230 arguments = [] 225 231 for argre, argvalue in self.path_args[commandidx]: # CommandArguments 226 argmatch = argre.match(path str, matchidx)232 argmatch = argre.match(pathcmd, matchidx) 227 233 if argmatch is None: 228 raise ValueError, "Error parsing argument of path at index %d (path=%r)" % (matchidx, path str)234 raise ValueError, "Error parsing argument of path at index %d (path=%r)" % (matchidx, pathcmd) 229 235 else: 230 236 arguments.append(argvalue(argmatch.groups()[0])) … … 237 243 commandidx = self.path_transitions.get(commandidx, commandidx) 238 244 239 pathfactory.EndPath(path str)245 pathfactory.EndPath(pathcmd) 240 246 return pathfactory 241 247 … … 248 254 def __iter__(self): 249 255 return iter(self.results) 250 def BeginPath(self, path str):256 def BeginPath(self, pathcmd): 251 257 self.results = ["begin()"] 252 258 def AddPathElement(self, name, *args): 253 259 name, relative = self.command_table[name] 254 260 self.results.append('%s%r' % (name, (relative,) + args)) 255 def EndPath(self, path str):261 def EndPath(self, pathcmd): 256 262 self.results.append("end()") 257 263 trunk/RBRapier/RBRapier/Tools/Geometry/Curves.py
r661 r662 11 11 _rad2deg = 180.0/Numeric.pi 12 12 _deg2rad = Numeric.pi/180.0 13 _2pi = 2 * Numeric.pi 13 14 14 15 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ … … 31 32 def Interpolate(self): 32 33 raise NotImplementedError 34 35 def __iter__(self): 36 return iter(self.Interpolate()) 33 37 34 38 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ … … 132 136 rx = 1. 133 137 ry = 1. 134 sweep = (0., 2*Numeric.pi)135 rotation = 0138 sweep = (0., _2pi) 139 xrotation = 0 136 140 137 141 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ … … 139 143 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 140 144 141 def __init__(self, center=(0., 0.), rx=1., ry=1., startangle=0, endangle=360, rotation=0, inDegrees=True, **kw):145 def __init__(self, center=(0., 0.), rx=1., ry=1., startangle=0, endangle=360, xrotation=0, inDegrees=True, **kw): 142 146 CurveBase.__init__(self, **kw) 143 147 self.SetCenter(center) … … 145 149 if inDegrees: 146 150 self.SetSweepAngles(startangle, endangle) 147 self.Set RotationAngle(rotation)151 self.SetXRotationAngle(xrotation) 148 152 else: 149 153 self.SetSweep(startangle, endangle) 150 self.Set Rotation(rotation)151 152 153 def fromArc(klass, fromxy, toxy, rx=1., ry=1., rotation=0, largearcflag=False, sweepflag=False, inDegrees=True, **kw):154 self.SetXRotation(xrotation) 155 156 157 def fromArc(klass, fromxy, toxy, rx=1., ry=1., xrotation=0, largearcflag=False, sweepflag=False, inDegrees=True, **kw): 154 158 """ 155 159 Derived from SVG Specification: … … 157 161 """ 158 162 if inDegrees: 159 rotation *= _deg2rad163 xrotation *= _deg2rad 160 164 fromxy = Numeric.asarray(fromxy, klass.NumericType) 161 165 toxy = Numeric.asarray(toxy, klass.NumericType) 162 if rotation:163 x, y = Numeric.dot(klass._RotationMatrix( rotation), 0.5*(fromxy-toxy))166 if xrotation: 167 x, y = Numeric.dot(klass._RotationMatrix(xrotation), 0.5*(fromxy-toxy)) 164 168 else: 165 169 x, y = 0.5*(fromxy-toxy) … … 182 186 scale = sign * Numeric.sqrt((rx2*ry2-tmp)/tmp) 183 187 184 cxP, cyP = rx*y/ry, -ry*x/rx185 if True orrotation:186 rot = klass._RotTranMatrix( rotation, (0.5*(fromxy+toxy)))188 cxP, cyP = scale*rx*y/ry, -scale*ry*x/rx 189 if xrotation: 190 rot = klass._RotTranMatrix(xrotation, (0.5*(fromxy+toxy))) 187 191 center = Numeric.dot(rot, Numeric.asarray([cxP, cyP, 1.], klass.NumericType))[:2] 188 192 center2 = Numeric.asarray([cxP, cyP]) + (0.5*(fromxy+toxy)) … … 190 194 center = Numeric.asarray([cxP, cyP]) + (0.5*(fromxy+toxy))[:2] 191 195 192 homept = (1., 0.)193 196 startpt = ((x-cxP)/rx, (y-cyP)/ry) 194 197 endpt = ((-x-cxP)/rx, (-y-cyP)/ry) 195 startangle = klass._FindAngle(homept, startpt) 196 endangle = klass._FindAngle(startpt, endpt) 197 if sweepflag and endangle > 0: 198 endangle -= 2*Numeric.pi 199 200 return klass(center, rx, ry, startangle, endangle, rotation, inDegrees=False, **kw) 198 startradians = klass._FindAngle((1., 0.), startpt) 199 sweepradians = klass._FindAngle(startpt, endpt) 200 if sweepflag: 201 if sweepradians < 0: 202 sweepradians += _2pi 203 else: 204 if sweepradians > 0: 205 sweepradians -= _2pi 206 207 endradians = startradians + sweepradians 208 return klass(center, rx, ry, startradians, endradians, xrotation, inDegrees=False, **kw) 201 209 fromArc = classmethod(fromArc) 202 210 … … 221 229 return self.sweep 222 230 223 def SetRotationAngle(self, rotationAngle): 224 self.SetRotation(_deg2rad*rotationAngle) 225 def SetRotation(self, rotationRadians): 226 self.rotation = rotationRadians 231 def SetXRotationAngle(self, xrotationAngle): 232 self.SetXRotation(_deg2rad*xrotationAngle) 233 def SetXRotation(self, xrotationRadians): 234 self.xrotation = xrotationRadians 235 def GetXRotation(self): 236 return self.xrotation 227 237 228 238 def Interpolate(self): 229 239 sweep = self._GetSweepVector() 230 240 rx, ry = self.GetRadii() 231 if self.rotation: 241 xrotation = self.GetXRotation() 242 if xrotation: 232 243 ellipse = Numeric.asarray([rx*Numeric.cos(sweep), ry*Numeric.sin(sweep), Numeric.ones(len(sweep), self.NumericType)], self.NumericType) 233 rot = self._RotTranMatrix( self.rotation, self.GetCenter())244 rot = self._RotTranMatrix(xrotation, self.GetCenter()) 234 245 ellipse = Numeric.dot(rot, ellipse) 235 246 return Numeric.transpose(ellipse[:-1,:]) … … 250 261 cosr = Numeric.cos(radians) 251 262 sinr = Numeric.sin(radians) 252 return Numeric.asarray([[cosr, -sinr],[sinr, cosr]], klass.NumericType)263 return Numeric.asarray([[cosr, sinr],[-sinr, cosr]], klass.NumericType) 253 264 _RotationMatrix = classmethod(_RotationMatrix) 254 265 … … 256 267 cosr = Numeric.cos(radians) 257 268 sinr = Numeric.sin(radians) 258 return Numeric.asarray([[cosr, -sinr, tx],[sinr, cosr, ty], [0., 0., 1.]], klass.NumericType)269 return Numeric.asarray([[cosr, sinr, tx],[-sinr, cosr, ty], [0., 0., 1.]], klass.NumericType) 259 270 _RotTranMatrix = classmethod(_RotTranMatrix) 260 271 261 272 def _FindAngle(klass, u, v): 262 273 cosangle = Numeric.dot(u,v)/Numeric.sqrt(Numeric.dot(u,u)*Numeric.dot(v,v)) 263 sign = Numeric.sign(u[0]*v[1]-u[1]*v[0]) 274 sign = Numeric.sign(u[0]*v[1]-u[1]*v[0]) or 1. # 0 is neither poistive or negative... but just make it positive for argument's sake... 264 275 return sign*Numeric.arccos(cosangle) 265 276 _FindAngle = classmethod(_FindAngle)
