1 #!/usr/bin/env python
2 '''
3 Copyright (C) 2005 Aaron Spike, aaron@ekips.org
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 '''
19 import math, inkex, simplestyle, simplepath, bezmisc
21 class Motion(inkex.Effect):
22 def __init__(self):
23 inkex.Effect.__init__(self)
24 self.OptionParser.add_option("-a", "--angle",
25 action="store", type="float",
26 dest="angle", default=45.0,
27 help="direction of the motion vector")
28 self.OptionParser.add_option("-m", "--magnitude",
29 action="store", type="float",
30 dest="magnitude", default=100.0,
31 help="magnitude of the motion vector")
33 def makeface(self,last,(cmd, params)):
34 a = []
35 a.append(['M',last[:]])
36 a.append([cmd, params[:]])
38 #translate path segment along vector
39 np = params[:]
40 defs = simplepath.pathdefs[cmd]
41 for i in range(defs[1]):
42 if defs[3][i] == 'x':
43 np[i] += self.vx
44 elif defs[3][i] == 'y':
45 np[i] += self.vy
47 a.append(['L',[np[-2],np[-1]]])
49 #reverse direction of path segment
50 np[-2:] = last[0]+self.vx,last[1]+self.vy
51 if cmd == 'C':
52 c1 = np[:2], np[2:4] = np[2:4], np[:2]
53 a.append([cmd,np[:]])
55 a.append(['Z',[]])
56 face = inkex.etree.SubElement(self.facegroup,inkex.addNS('path','svg'),{'d':simplepath.formatPath(a)})
58 def effect(self):
59 self.vx = math.cos(math.radians(self.options.angle))*self.options.magnitude
60 self.vy = math.sin(math.radians(self.options.angle))*self.options.magnitude
61 for id, node in self.selected.iteritems():
62 if node.tag == inkex.addNS('path','svg'):
63 group = inkex.etree.SubElement(node.getparent(),inkex.addNS('g','svg'))
64 self.facegroup = inkex.etree.SubElement(group, inkex.addNS('g','svg'))
65 group.append(node)
67 t = node.get('transform')
68 if t:
69 group.set('transform', t)
70 node.set('transform','')
72 s = node.get('style')
73 self.facegroup.set('style', s)
75 p = simplepath.parsePath(node.get('d'))
76 for cmd,params in p:
77 tees = []
78 if cmd == 'C':
79 bez = (last,params[:2],params[2:4],params[-2:])
80 tees = [t for t in bezmisc.beziertatslope(bez,(self.vy,self.vx)) if 0<t<1]
81 tees.sort()
83 segments = []
84 if len(tees) == 0 and cmd in ['L','C']:
85 segments.append([cmd,params[:]])
86 elif len(tees) == 1:
87 one,two = bezmisc.beziersplitatt(bez,tees[0])
88 segments.append([cmd,list(one[1]+one[2]+one[3])])
89 segments.append([cmd,list(two[1]+two[2]+two[3])])
90 elif len(tees) == 2:
91 one,two = bezmisc.beziersplitatt(bez,tees[0])
92 two,three = bezmisc.beziersplitatt(two,tees[1])
93 segments.append([cmd,list(one[1]+one[2]+one[3])])
94 segments.append([cmd,list(two[1]+two[2]+two[3])])
95 segments.append([cmd,list(three[1]+three[2]+three[3])])
97 for seg in segments:
98 self.makeface(last,seg)
99 last = seg[1][-2:]
101 if cmd == 'M':
102 subPathStart = params[-2:]
103 if cmd == 'Z':
104 last = subPathStart
105 else:
106 last = params[-2:]
108 if __name__ == '__main__':
109 e = Motion()
110 e.affect()
113 # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99