summaryrefslogtreecommitdiffstats
path: root/share/extensions/funcplot.py
diff options
context:
space:
mode:
Diffstat (limited to 'share/extensions/funcplot.py')
-rw-r--r--share/extensions/funcplot.py91
1 files changed, 70 insertions, 21 deletions
diff --git a/share/extensions/funcplot.py b/share/extensions/funcplot.py
index e478a4b30..482df634a 100644
--- a/share/extensions/funcplot.py
+++ b/share/extensions/funcplot.py
@@ -1,5 +1,6 @@
#!/usr/bin/env python
'''
+Copyright (C) 2007 Tavmjong Bah, tavmjong@free.fr
Copyright (C) 2006 Georg Wiora, xorx@quarkbox.de
Copyright (C) 2006 Johan Engelen, johan@shouraizou.nl
Copyright (C) 2005 Aaron Spike, aaron@ekips.org
@@ -21,6 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Changes:
* This program is a modified version of wavy.py by Aaron Spike.
* 22-Dec-2006: Wiora : Added axis and isotropic scaling
+ * 21-Jun-2007: Tavmjong: Added polar coordinates
'''
import inkex, simplepath, simplestyle
@@ -28,8 +30,8 @@ from math import *
from random import *
def drawfunction(xstart, xend, ybottom, ytop, samples, width, height, left, bottom,
- fx = "sin(x)", fpx = "cos(x)", fponum = True, times2pi = False, isoscale = True, drawaxis = True):
-
+ fx = "sin(x)", fpx = "cos(x)", fponum = True, times2pi = False, polar = False, isoscale = True, drawaxis = True):
+
if times2pi == True:
xstart = 2 * pi * xstart
xend = 2 * pi * xend
@@ -38,12 +40,18 @@ def drawfunction(xstart, xend, ybottom, ytop, samples, width, height, left, bott
scalex = width / (xend - xstart)
xoff = left
coordx = lambda x: (x - xstart) * scalex + xoff #convert x-value to coordinate
+ if polar : # Set scale so that left side of rectangle is -1, right side is +1.
+ # (We can't use xscale for both range and scale.)
+ centerx = left + width/2.0
+ polar_scalex = width/2.0
+ coordx = lambda x: x * polar_scalex + centerx #convert x-value to coordinate
+
scaley = height / (ytop - ybottom)
yoff = bottom
coordy = lambda y: (ybottom - y) * scaley + yoff #convert y-value to coordinate
-
+
# Check for isotropic scaling and use smaller of the two scales, correct ranges
- if isoscale:
+ if isoscale and not polar:
if scaley<scalex:
# compute zero location
xzero = coordx(0)
@@ -70,6 +78,7 @@ def drawfunction(xstart, xend, ybottom, ytop, samples, width, height, left, bott
# step is the distance between nodes on x
step = (xend - xstart) / (samples-1)
third = step / 3.0
+ ds = step * 0.001 # Step used in calculating derivatives
a = [] # path array
# add axis
@@ -87,29 +96,60 @@ def drawfunction(xstart, xend, ybottom, ytop, samples, width, height, left, bott
# initialize function and derivative for 0;
# they are carried over from one iteration to the next, to avoid extra function calculations.
- y0 = f(xstart)
- if fponum == True: # numerical derivative, using 0.001*step as the small differential
- d0 = (f(xstart + 0.001*step) - y0)/(0.001*step)
+ x0 = xstart
+ y0 = f(xstart)
+ if polar :
+ xp0 = y0 * cos( x0 )
+ yp0 = y0 * sin( x0 )
+ x0 = xp0
+ y0 = yp0
+ if fponum or polar: # numerical derivative, using 0.001*step as the small differential
+ x1 = xstart + ds # Second point AFTER first point (Good for first point)
+ y1 = f(x1)
+ if polar :
+ xp1 = y1 * cos( x1 )
+ yp1 = y1 * sin( x1 )
+ x1 = xp1
+ y1 = yp1
+ dx0 = (x1 - x0)/ds
+ dy0 = (y1 - y0)/ds
else: # derivative given by the user
- d0 = fp(xstart)
+ dx0 = 0 # Only works for rectangular coordinates
+ dy0 = fp(xstart)
# Start curve
- a.append([' M ',[coordx(xstart), coordy(y0)]]) # initial moveto
+ a.append([' M ',[coordx(x0), coordy(y0)]]) # initial moveto
for i in range(int(samples-1)):
- x = (i+1) * step + xstart
- y1 = f(x)
- if fponum == True: # numerical derivative
- d1 = (y1 - f(x - 0.001*step))/(0.001*step)
+ x1 = (i+1) * step + xstart
+ x2 = x1 - ds # Second point BEFORE first point (Good for last point)
+ y1 = f(x1)
+ y2 = f(x2)
+ if polar :
+ xp1 = y1 * cos( x1 )
+ yp1 = y1 * sin( x1 )
+ xp2 = y2 * cos( x2 )
+ yp2 = y2 * sin( x2 )
+ x1 = xp1
+ y1 = yp1
+ x2 = xp2
+ y2 = yp2
+ if fponum or polar: # numerical derivative
+ dx1 = (x1 - x2)/ds
+ dy1 = (y1 - y2)/ds
else: # derivative given by the user
- d1 = fp(x)
+ dx1 = 0 # Only works for rectangular coordinates
+ dy1 = fp(x1)
# create curve
- a.append([' C ',[coordx(x - step + third), coordy(y0 + (d0 * third)),
- coordx(x - third), coordy(y1 - (d1 * third)),
- coordx(x), coordy(y1)]])
- y0 = y1 # next segment's y0 is this segment's y1
- d0 = d1 # we assume the function is smooth everywhere, so carry over the derivative too
-
+ a.append([' C ',
+ [coordx(x0 + (dx0 * third)), coordy(y0 + (dy0 * third)),
+ coordx(x1 - (dx1 * third)), coordy(y1 - (dy1 * third)),
+ coordx(x1), coordy(y1)]
+ ])
+ x0 = x1 # Next segment's start is this segments end
+ y0 = y1
+ dx0 = dx1 # Assume the function is smooth everywhere, so carry over the derivative too
+ dy0 = dy1
return a
class FuncPlot(inkex.Effect):
@@ -127,6 +167,10 @@ class FuncPlot(inkex.Effect):
action="store", type="inkbool",
dest="times2pi", default=True,
help="Multiply x-range by 2*pi")
+ self.OptionParser.add_option("--polar",
+ action="store", type="inkbool",
+ dest="polar", default=False,
+ help="Plot using polar coordinates")
self.OptionParser.add_option("--ybottom",
action="store", type="float",
dest="ybottom", default=-1.0,
@@ -167,6 +211,10 @@ class FuncPlot(inkex.Effect):
action="store", type="string",
dest="tab", default="sampling",
help="The selected UI-tab when OK was pressed")
+ self.OptionParser.add_option("--funcplotuse",
+ action="store", type="string",
+ dest="funcplotuse", default="",
+ help="dummy")
self.OptionParser.add_option("--pythonfunctions",
action="store", type="string",
dest="pythonfunctions", default="",
@@ -191,7 +239,7 @@ class FuncPlot(inkex.Effect):
if t:
newpath.set('transform', t)
- # top and bottom where exchanhged
+ # top and bottom were exchanged
newpath.set('d', simplepath.formatPath(
drawfunction(self.options.xstart,
self.options.xend,
@@ -203,6 +251,7 @@ class FuncPlot(inkex.Effect):
self.options.fpofx,
self.options.fponum,
self.options.times2pi,
+ self.options.polar,
self.options.isoscale,
self.options.drawaxis)))
newpath.set('title', self.options.fofx)