Code

Removing seemingly dead/unused extension files that are causing a menu problem -...
[inkscape.git] / share / extensions / grid_polar.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 polar grid in Inkscape.
6 ##There is a wide range of options including subdivision and labels.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21 '''\r
23 import inkex
24 import simplestyle, sys
25 from math import *
27 def log_N(base, x): #computes the base-n log of x
28     return log(x)/log(base)
30 def draw_SVG_ellipse(rx, ry, cx, cy, width, fill, name, parent):
31     style = { 'stroke': '#000000', 'stroke-width':str(width), 'fill': fill }
32     circ_attribs = {'style':simplestyle.formatStyle(style),
33                     'inkscape:label':name,
34                     'sodipodi:cx':str(cx), 'sodipodi:cy':str(cy), 
35                     'sodipodi:rx':str(rx), 'sodipodi:ry':str(ry), 
36                     'sodipodi:type':'arc'}
37     inkex.etree.SubElement(parent, inkex.addNS('path','svg'), circ_attribs )
39 def draw_SVG_line(x1, y1, x2, y2, width, name, parent):
40     style = { 'stroke': '#000000', 'stroke-width':str(width), 'fill': 'none' }
41     line_attribs = {'style':simplestyle.formatStyle(style),
42                     'inkscape:label':name,
43                     'd':'M '+str(x1)+','+str(y1)+' L '+str(x2)+','+str(y2)}
44     inkex.etree.SubElement(parent, inkex.addNS('path','svg'), line_attribs )
45     
46 def draw_SVG_label_centred(x, y, string, font_size, name, parent):
47     style = {'text-align': 'center', 'vertical-align': 'top',
48              'text-anchor': 'middle', 'font-size': str(font_size)+'px',
49              'fill-opacity': '1.0', 'stroke': 'none',
50              'font-weight': 'normal', 'font-style': 'normal', 'fill': '#000000'}
51     label_attribs = {'style':simplestyle.formatStyle(style),
52                      'inkscape:label':name,
53                      'x':str(x), 'y':str(y)}
54     label = inkex.etree.SubElement(parent, inkex.addNS('text','svg'), label_attribs)
55     label.text = string
57 class Grid_Polar(inkex.Effect):
58     def __init__(self):
59         inkex.Effect.__init__(self)
60         self.OptionParser.add_option("--r_divs",
61                         action="store", type="int", 
62                         dest="r_divs", default=5,
63                         help="Circular Divisions")
64         self.OptionParser.add_option("--dr",
65                         action="store", type="float", 
66                         dest="dr", default=50,
67                         help="Circular Division Spacing")
68         self.OptionParser.add_option("--r_subdivs",
69                         action="store", type="int", 
70                         dest="r_subdivs", default=3,
71                         help="Circular Subdivisions per Major division")
72         self.OptionParser.add_option("--r_log",
73                         action="store", type="inkbool", 
74                         dest="r_log", default=False,
75                         help="Logarithmic subdivisions if true")
76         self.OptionParser.add_option("--r_divs_th",
77                         action="store", type="float", 
78                         dest="r_divs_th", default=2,
79                         help="Major Circular Division Line thickness")
80         self.OptionParser.add_option("--r_subdivs_th",
81                         action="store", type="float", 
82                         dest="r_subdivs_th", default=1,
83                         help="Minor Circular Division Line thickness")
84         self.OptionParser.add_option("--a_divs",
85                         action="store", type="int", 
86                         dest="a_divs", default=24,
87                         help="Angle Divisions")
88         self.OptionParser.add_option("--a_divs_cent",
89                         action="store", type="int", 
90                         dest="a_divs_cent", default=4,
91                         help="Angle Divisions at Centre")
92         self.OptionParser.add_option("--a_subdivs",
93                         action="store", type="int", 
94                         dest="a_subdivs", default=1,
95                         help="Angcular Subdivisions per Major division")
96         self.OptionParser.add_option("--a_subdivs_cent",
97                         action="store", type="int", 
98                         dest="a_subdivs_cent", default=1,
99                         help="Angular Subdivisions end 'n' major circular divisions before the centre")
100         self.OptionParser.add_option("--a_divs_th",
101                         action="store", type="float", 
102                         dest="a_divs_th", default=2,
103                         help="Major Angular Division Line thickness")
104         self.OptionParser.add_option("--a_subdivs_th",
105                         action="store", type="float", 
106                         dest="a_subdivs_th", default=1,
107                         help="Minor Angular Division Line thickness")
108         self.OptionParser.add_option("--c_dot_dia",
109                         action="store", type="float", 
110                         dest="c_dot_dia", default=5.0,
111                         help="Diameter of Centre Dot")
112         self.OptionParser.add_option("--a_labels",
113                         action="store", type="string", 
114                         dest="a_labels", default='deg',
115                         help="The kind of labels to apply")
116         self.OptionParser.add_option("--a_label_size",
117                         action="store", type="int", 
118                         dest="a_label_size", default=18,
119                         help="The nominal pixel size of the circumferential labels")
120         self.OptionParser.add_option("--a_label_outset",
121                         action="store", type="float", 
122                         dest="a_label_outset", default=24,
123                         help="The radial outset of the circumferential labels")
125     def effect(self):
126     
127         # Embed grid in group
128         #Put in in the centre of the current view
129         t = 'translate(' + str( self.view_center[0] ) + ',' + str( self.view_center[1] ) + ')'
130         g_attribs = {inkex.addNS('label','inkscape'):'Grid_Polar:R' +
131                                  str( self.options.r_divs )+':A'+str( self.options.a_divs ),
132                    'transform':t }
133         grid = inkex.etree.SubElement(self.current_layer, 'g', g_attribs)
135         dr = self.options.dr                        #Distance between neighbouring circles
136         dtheta = 2 * pi / self.options.a_divs_cent  #Angular change between adjacent radial lines at centre
137         rmax = self.options.r_divs * dr
138         
139         #Create SVG circles
140         for i in range(1, self.options.r_divs+1):
141             draw_SVG_ellipse(i*dr, i*dr, 0, 0, #major div circles
142                              self.options.r_divs_th, 'none',
143                              'MajorDivCircle'+str(i)+':R'+str(i*dr), grid)
144             
145             if self.options.r_log: #logarithmic subdivisions
146                 for j in range (2, self.options.r_subdivs):
147                     draw_SVG_ellipse(i*dr-(1-log_N(self.options.r_subdivs, j))*dr, #minor div circles
148                                      i*dr-(1-log_N(self.options.r_subdivs, j))*dr, 0, 0, 
149                                      self.options.r_subdivs_th, 'none',
150                                      'MinorDivCircle'+str(i)+':Log'+str(j), grid)
151             else: #linear subdivs
152                 for j in range (1, self.options.r_subdivs):
153                     draw_SVG_ellipse(i*dr-j*dr/self.options.r_subdivs, #minor div circles
154                                      i*dr-j*dr/self.options.r_subdivs, 0, 0, 
155                                      self.options.r_subdivs_th, 'none',
156                                      'MinorDivCircle'+str(i)+':R'+str(i*dr), grid)
157         
158         if self.options.a_divs == self.options.a_divs_cent: #the lines can go from the centre to the edge
159             for i in range(0, self.options.a_divs):
160                 draw_SVG_line(0, 0, rmax*sin(i*dtheta), rmax*cos(i*dtheta), 
161                               self.options.a_divs_th, 'RadialGridline'+str(i), grid)
162         
163         else: #we need separate lines
164             for i in range(0, self.options.a_divs_cent): #lines that go to the first circle
165                 draw_SVG_line(0, 0, dr*sin(i*dtheta), dr*cos(i*dtheta), 
166                               self.options.a_divs_th, 'RadialGridline'+str(i), grid)
167         
168             dtheta = 2 * pi / self.options.a_divs #work out the angle change for outer lines
169             
170             for i in range(0, self.options.a_divs): #lines that go from there to the edge
171                 draw_SVG_line(  dr*sin(i*dtheta+pi/2.0),   dr*cos(i*dtheta+pi/2.0), 
172                               rmax*sin(i*dtheta+pi/2.0), rmax*cos(i*dtheta+pi/2.0), 
173                               self.options.a_divs_th, 'RadialGridline'+str(i), grid)
174         
175         if self.options.a_subdivs > 1: #draw angular subdivs
176             for i in range(0, self.options.a_divs): #for each major divison
177                 for j in range(1, self.options.a_subdivs): #draw the subdivisions
178                     angle = i*dtheta-j*dtheta/self.options.a_subdivs+pi/2.0 # the angle of the subdivion line
179                     draw_SVG_line(dr*self.options.a_subdivs_cent*sin(angle),
180                                   dr*self.options.a_subdivs_cent*cos(angle), 
181                                   rmax*sin(angle), rmax*cos(angle), 
182                                   self.options.a_subdivs_th, 'RadialMinorGridline'+str(i), grid)
183         
184         if self.options.c_dot_dia <> 0: #if a non-zero diameter, draw the centre dot
185             draw_SVG_ellipse(self.options.c_dot_dia /2.0, self.options.c_dot_dia/2.0,
186                              0, 0, 0, '#000000', 'CentreDot', grid)
187         
188         if self.options.a_labels == 'deg':
189             label_radius = rmax+self.options.a_label_outset  #radius of label centres
190             label_size = self.options.a_label_size
191             numeral_size = 0.73*label_size #numerals appear to be 0.73 the height of the nominal pixel size of the font in "Sans"
192             
193             for i in range(0, self.options.a_divs):#self.options.a_divs): #radial line labels
194                 draw_SVG_label_centred(sin(i*dtheta+pi/2.0)*label_radius,        #0 at the RHS, mathematical style
195                                        cos(i*dtheta+pi/2.0)*label_radius+ numeral_size/2.0, #centre the text vertically 
196                                        str(i*360/self.options.a_divs), 
197                                        label_size, 'Label'+str(i), grid)
199 e = Grid_Polar()
200 e.affect()