Code

Remove LPESlant.
[inkscape.git] / share / extensions / grid_cartesian.py
1 #!/usr/bin/env python 
2 '''
3 Copyright (C) 2007 John Beard john.j.beard@gmail.com
5 ##This extension allows you to draw a Cartesian grid in Inkscape.
6 ##There is a wide range of options including subdivision, subsubdivions
7 ## and logarithmic scales. Custom line widths are also possible.
8 ##All elements are grouped with similar elements (eg all x-subdivs)
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23 '''\r
25 import inkex
26 import simplestyle, sys
27 from math import *
29 def log_N(base, x): #computes the base-n log of x
30     return log(x)/log(base)
32 def draw_SVG_line(x1, y1, x2, y2, width, name, parent):
33     style = { 'stroke': '#000000', 'stroke-width':str(width), 'fill': 'none' }
34     line_attribs = {'style':simplestyle.formatStyle(style),
35                     'inkscape:label':name,
36                     'd':'M '+str(x1)+','+str(y1)+' L '+str(x2)+','+str(y2)}
37     inkex.etree.SubElement(parent, inkex.addNS('path','svg'), line_attribs )
38     
39 def draw_SVG_rect(x,y,w,h, width, fill, name, parent):
40     style = { 'stroke': '#000000', 'stroke-width':str(width), 'fill':fill}
41     rect_attribs = {'style':simplestyle.formatStyle(style),
42                     'inkscape:label':name,
43                     'x':str(x), 'y':str(y), 'width':str(w), 'height':str(h)}
44     inkex.etree.SubElement(parent, inkex.addNS('rect','svg'), rect_attribs )
46 class Grid_Polar(inkex.Effect):
47     def __init__(self):
48         inkex.Effect.__init__(self)
49         self.OptionParser.add_option("--x_divs",
50                         action="store", type="int", 
51                         dest="x_divs", default=5,
52                         help="Major X Divisions")
53         self.OptionParser.add_option("--dx",
54                         action="store", type="float", 
55                         dest="dx", default=100.0,
56                         help="Major X divison Spacing")
57         self.OptionParser.add_option("--x_subdivs",
58                         action="store", type="int", 
59                         dest="x_subdivs", default=2,
60                         help="Subdivisions per Major X division")
61         self.OptionParser.add_option("--x_log",
62                         action="store", type="inkbool", 
63                         dest="x_log", default=False,
64                         help="Logarithmic x subdivisions if true")
65         self.OptionParser.add_option("--x_subsubdivs",
66                         action="store", type="int", 
67                         dest="x_subsubdivs", default=5,
68                         help="Subsubdivisions per Minor X division")
69         self.OptionParser.add_option("--x_half_freq",
70                         action="store", type="int", 
71                         dest="x_half_freq", default=4,
72                         help="Halve Subsubdiv. Frequency after 'n' Subdivs. (log only)")
73         self.OptionParser.add_option("--x_divs_th",
74                         action="store", type="float", 
75                         dest="x_divs_th", default=2,
76                         help="Major X Division Line thickness")
77         self.OptionParser.add_option("--x_subdivs_th",
78                         action="store", type="float", 
79                         dest="x_subdivs_th", default=1,
80                         help="Minor X Division Line thickness")
81         self.OptionParser.add_option("--x_subsubdivs_th",
82                         action="store", type="float", 
83                         dest="x_subsubdivs_th", default=1,
84                         help="Subminor X Division Line thickness")
85         self.OptionParser.add_option("--y_divs",
86                         action="store", type="int", 
87                         dest="y_divs", default=6,
88                         help="Major Y Divisions")
89         self.OptionParser.add_option("--dy",
90                         action="store", type="float", 
91                         dest="dy", default=100.0,
92                         help="Major Gridline Increment")
93         self.OptionParser.add_option("--y_subdivs",
94                         action="store", type="int", 
95                         dest="y_subdivs", default=2,
96                         help="Minor Divisions per Major Y division")
97         self.OptionParser.add_option("--y_log",
98                         action="store", type="inkbool", 
99                         dest="y_log", default=False,
100                         help="Logarithmic y subdivisions if true")
101         self.OptionParser.add_option("--y_subsubdivs",
102                         action="store", type="int", 
103                         dest="y_subsubdivs", default=5,
104                         help="Subsubdivisions per Minor Y division")
105         self.OptionParser.add_option("--y_half_freq",
106                         action="store", type="int", 
107                         dest="y_half_freq", default=4,
108                         help="Halve Y Subsubdiv. Frequency after 'n' Subdivs. (log only)")
109         self.OptionParser.add_option("--y_divs_th",
110                         action="store", type="float", 
111                         dest="y_divs_th", default=2,
112                         help="Major Y Division Line thickness")
113         self.OptionParser.add_option("--y_subdivs_th",
114                         action="store", type="float", 
115                         dest="y_subdivs_th", default=1,
116                         help="Minor Y Division Line thickness")
117         self.OptionParser.add_option("--y_subsubdivs_th",
118                         action="store", type="float", 
119                         dest="y_subsubdivs_th", default=1,
120                         help="Subminor Y Division Line thickness")
121         self.OptionParser.add_option("--border_th",
122                         action="store", type="float", 
123                         dest="border_th", default=3,
124                         help="Border Line thickness")
127     def effect(self):
128         
129         #find the pixel dimensions of the overall grid
130         ymax = self.options.dy * self.options.y_divs
131         xmax = self.options.dx * self.options.x_divs
132         
133         # Embed grid in group
134         #Put in in the centre of the current view
135         t = 'translate(' + str( self.view_center[0]- xmax/2.0) + ',' + \
136                            str( self.view_center[1]- ymax/2.0) + ')'
137         g_attribs = {inkex.addNS('label','inkscape'):'Grid_Polar:X' + \
138                      str( self.options.x_divs )+':Y'+str( self.options.y_divs ),
139                     'transform':t }
140         grid = inkex.etree.SubElement(self.current_layer, 'g', g_attribs)
141         
142         #Group for major x gridlines
143         g_attribs = {inkex.addNS('label','inkscape'):'MajorXGridlines'}
144         majglx = inkex.etree.SubElement(grid, 'g', g_attribs)
146         #Group for major y gridlines
147         g_attribs = {inkex.addNS('label','inkscape'):'MajorYGridlines'}
148         majgly = inkex.etree.SubElement(grid, 'g', g_attribs)
149         
150         #Group for minor x gridlines
151         if self.options.x_subdivs > 1:#if there are any minor x gridlines
152             g_attribs = {inkex.addNS('label','inkscape'):'MinorXGridlines'}
153             minglx = inkex.etree.SubElement(grid, 'g', g_attribs)
154         
155         #Group for subminor x gridlines
156         if self.options.x_subsubdivs > 1:#if there are any minor minor x gridlines
157             g_attribs = {inkex.addNS('label','inkscape'):'SubMinorXGridlines'}
158             mminglx = inkex.etree.SubElement(grid, 'g', g_attribs)
159         
160         #Group for minor y gridlines
161         if self.options.y_subdivs > 1:#if there are any minor y gridlines
162             g_attribs = {inkex.addNS('label','inkscape'):'MinorYGridlines'}
163             mingly = inkex.etree.SubElement(grid, 'g', g_attribs)
164         
165         #Group for subminor y gridlines
166         if self.options.y_subsubdivs > 1:#if there are any minor minor x gridlines
167             g_attribs = {inkex.addNS('label','inkscape'):'SubMinorYGridlines'}
168             mmingly = inkex.etree.SubElement(grid, 'g', g_attribs)
170             
171         draw_SVG_rect(0, 0, xmax, ymax, self.options.border_th,
172                       'none', 'Border', grid) #border rectangle
173         
174         #DO THE X DIVISONS======================================
175         sd  = self.options.x_subdivs #sub divs per div
176         ssd = self.options.x_subsubdivs #subsubdivs per subdiv
177         
178         for i in range(0, self.options.x_divs): #Major x divisons
179             if i>0: #dont draw first line (we made a proper border)
180                 draw_SVG_line(self.options.dx*i, 0,
181                               self.options.dx*i,ymax,
182                               self.options.x_divs_th,
183                               'MajorXDiv'+str(i), majglx)
184             
185             if self.options.x_log: #log x subdivs
186                 for j in range (1, sd):
187                     if j>1: #the first loop is only for subsubdivs
188                         draw_SVG_line(self.options.dx*(i+log_N(sd, j)), 0,
189                                       self.options.dx*(i+log_N(sd, j)), ymax,
190                                       self.options.x_subdivs_th,
191                                       'MinorXDiv'+str(i)+':'+str(j), minglx)
192                                   
193                     for k in range (1, ssd): #subsub divs
194                         if (j <= self.options.x_half_freq) or (k%2 == 0):#only draw half the subsubdivs past the half-freq point
195                             if (ssd%2 > 0) and (j > self.options.y_half_freq): #half frequency won't work with odd numbers of subsubdivs,
196                                 ssd2 = ssd+1 #make even
197                             else:
198                                 ssd2 = ssd #no change
199                             draw_SVG_line(self.options.dx*(i+log_N(sd, j+k/float(ssd2) )), 0,
200                                           self.options.dx*(i+log_N(sd, j+k/float(ssd2) )), ymax,
201                                           self.options.x_subsubdivs_th,'SubminorXDiv'+str(i)+':'+str(j)+':'+str(k), mminglx)
202             
203             else: #linear x subdivs
204                 for j in range (0, sd):
205                     if j>0: #not for the first loop (this loop is for the subsubdivs before the first subdiv)
206                         draw_SVG_line(self.options.dx*(i+j/float(sd)), 0,
207                                       self.options.dx*(i+j/float(sd)), ymax,
208                                       self.options.x_subdivs_th,
209                                       'MinorXDiv'+str(i)+':'+str(j), minglx)
210                     
211                     for k in range (1, ssd): #subsub divs
212                         draw_SVG_line(self.options.dx*(i+(j*ssd+k)/((float(sd)*ssd))) , 0,
213                                       self.options.dx*(i+(j*ssd+k)/((float(sd)*ssd))) , ymax,
214                                       self.options.x_subsubdivs_th,
215                                       'SubminorXDiv'+str(i)+':'+str(j)+':'+str(k), mminglx)
216          
217         #DO THE Y DIVISONS========================================
218         sd  = self.options.y_subdivs    #sub divs per div
219         ssd = self.options.y_subsubdivs #subsubdivs per subdiv
220                                       
221         for i in range(0, self.options.y_divs): #Major y divisons
222             if i>0:#dont draw first line (we will make a border)
223                 draw_SVG_line(0, self.options.dy*i,
224                               xmax, self.options.dy*i,
225                               self.options.y_divs_th,
226                               'MajorYDiv'+str(i), majgly)
227             
228             if self.options.y_log: #log y subdivs
229                 for j in range (1, sd):
230                     if j>1: #the first loop is only for subsubdivs
231                         draw_SVG_line(0,    self.options.dy*(i+1-log_N(sd, j)),
232                                       xmax, self.options.dy*(i+1-log_N(sd, j)),
233                                       self.options.y_subdivs_th,
234                                       'MinorXDiv'+str(i)+':'+str(j), mingly)
235                     
236                     for k in range (1, ssd): #subsub divs
237                         if (j <= self.options.y_half_freq) or (k%2 == 0):#only draw half the subsubdivs past the half-freq point
238                             if (ssd%2 > 0) and (j > self.options.y_half_freq): #half frequency won't work with odd numbers of subsubdivs,
239                                 ssd2 = ssd+1
240                             else:
241                                 ssd2 = ssd #no change
242                             draw_SVG_line(0,    self.options.dx*(i+1-log_N(sd, j+k/float(ssd2) )),
243                                           xmax, self.options.dx*(i+1-log_N(sd, j+k/float(ssd2) )),
244                                           self.options.y_subsubdivs_th,
245                                           'SubminorXDiv'+str(i)+':'+str(j)+':'+str(k), mmingly)
246             else: #linear y subdivs
247                 for j in range (0, self.options.y_subdivs):
248                     if j>0:#not for the first loop (this loop is for the subsubdivs before the first subdiv)
249                         draw_SVG_line(0,    self.options.dy*(i+j/float(sd)),
250                                       xmax, self.options.dy*(i+j/float(sd)),
251                                       self.options.y_subdivs_th,
252                                       'MinorXYiv'+str(i)+':'+str(j), mingly)
253                     
254                     for k in range (1, ssd): #subsub divs
255                         draw_SVG_line(0,    self.options.dy*(i+(j*ssd+k)/((float(sd)*ssd))),
256                                       xmax, self.options.dy*(i+(j*ssd+k)/((float(sd)*ssd))),
257                                       self.options.y_subsubdivs_th,
258                                       'SubminorXDiv'+str(i)+':'+str(j)+':'+str(k), mmingly)
262 e = Grid_Polar()
263 e.affect()