Code

Added polar coordinates.
authortavmjong <tavmjong@users.sourceforge.net>
Fri, 22 Jun 2007 11:11:19 +0000 (11:11 +0000)
committertavmjong <tavmjong@users.sourceforge.net>
Fri, 22 Jun 2007 11:11:19 +0000 (11:11 +0000)
Added "Use" tab to dialog.

share/extensions/funcplot.inx
share/extensions/funcplot.py

index a093a3ff2be63ffbd2e7b9e133e383c5bfbfe357..11250c7c3d16dc2b4c4357642727767c0cd685c2 100644 (file)
@@ -5,17 +5,28 @@
        <dependency type="executable" location="extensions">inkex.py</dependency>\r
        <param name="tab" type="notebook">\r
            <page name="sampling" _gui-text="Range and Sampling">\r
-               <param name="xstart" type="float" min="-1000.0" max="1000.0" _gui-text="Start x-value">0.0</param>\r
-               <param name="xend" type="float" min="-1000.0" max="1000.0" _gui-text="End x-value">1.0</param>\r
-               <param name="times2pi" type="boolean" _gui-text="Multiply x-range by 2*pi">false</param>\r
-               <param name="ybottom" type="float" min="-1000.0" max="1000.0" _gui-text="y-value of rectangle's bottom">0.0</param>\r
-               <param name="ytop" type="float" min="-1000.0" max="1000.0" _gui-text="y-value of rectangle's top">1.0</param>\r
-               <param name="samples" type="int" min="2" max="1000" _gui-text="Samples">8</param>\r
-            <param name="isoscale" type="boolean" _gui-text="Isotropic scaling (uses smallest: width/xrange or height/yrange)">false</param>\r
+               <param name="xstart"   type="float" min="-1000.0" max="1000.0" _gui-text="Start x-value">0.0</param>\r
+               <param name="xend"     type="float" min="-1000.0" max="1000.0" _gui-text="End x-value">1.0</param>\r
+               <param name="times2pi" type="boolean"                          _gui-text="Multiply x-range by 2*pi">false</param>\r
+               <param name="ybottom"  type="float" min="-1000.0" max="1000.0" _gui-text="y-value of rectangle's bottom">0.0</param>\r
+               <param name="ytop"     type="float" min="-1000.0" max="1000.0" _gui-text="y-value of rectangle's top">1.0</param>\r
+               <param name="samples"  type="int"   min="2"       max="1000"   _gui-text="Samples">8</param>\r
+               <param name="isoscale" type="boolean" _gui-text="Isotropic scaling (uses smallest: width/xrange or height/yrange)">false</param>\r
+               <param name="polar"    type="boolean" _gui-text="Use polar coordinates">true</param>\r
            </page>\r
-           <page name="desc" _gui-text="Help">\r
-               <_param name="pythonfunctions" type="description">The following functions are available:\r
-(the available functions are the standard python math functions)\r
+           <page name="use" _gui-text="Use">\r
+               <_param name="funcplotuse" type="description">Select a rectangle before calling effect.\r
+Rectangle determines x and y scales.\r
+\r
+With polar coordinates:\r
+   Start and End x-values define the angle range in radians.\r
+   x scale is set so left and right edges of rectangle are at +/-1.\r
+   Isotropic scaling is disabled.\r
+   First derivative is always determined numerically.</_param>\r
+           </page>\r
+           <page name="desc" _gui-text="Functions">\r
+               <_param name="pythonfunctions" type="description">Standard python math functions are available:\r
+\r
 ceil(x); fabs(x); floor(x); fmod(x,y); frexp(x); ldexp(x,i); \r
 modf(x); exp(x); log(x [, base]); log10(x); pow(x,y); sqrt(x); \r
 acos(x); asin(x); atan(x); atan2(y,x); hypot(x,y); \r
@@ -25,11 +36,11 @@ cosh(x); sinh(x); tanh(x).
 The constants pi and e are also available. </_param>\r
            </page>\r
        </param>\r
-       <param name="fofx" type="string" _gui-text="Function">exp(-x*x)</param>\r
-       <param name="fponum" type="boolean" _gui-text="Calculate first derivative numerically">true</param>\r
-       <param name="fpofx" type="string" _gui-text="First derivative">x</param>\r
-       <param name="remove" type="boolean" _gui-text="Remove rectangle">true</param>\r
-    <param name="drawaxis" type="boolean" _gui-text="Draw Axes">false</param>\r
+       <param name="fofx"     type="string"  _gui-text="Function">exp(-x*x)</param>\r
+       <param name="fponum"   type="boolean" _gui-text="Calculate first derivative numerically">true</param>\r
+       <param name="fpofx"    type="string"  _gui-text="First derivative">x</param>\r
+       <param name="remove"   type="boolean" _gui-text="Remove rectangle">true</param>\r
+       <param name="drawaxis" type="boolean" _gui-text="Draw Axes">false</param>\r
     <effect>\r
                <object-type>rect</object-type>\r
                 <effects-menu>\r
index e478a4b304ccd9b90589cfc7d6d27c386b9e8eb2..482df634a84c9d514e499e9c69ee4d6fbcb79431 100644 (file)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python \r
 '''\r
+Copyright (C) 2007 Tavmjong Bah, tavmjong@free.fr\r
 Copyright (C) 2006 Georg Wiora, xorx@quarkbox.de\r
 Copyright (C) 2006 Johan Engelen, johan@shouraizou.nl\r
 Copyright (C) 2005 Aaron Spike, aaron@ekips.org\r
@@ -21,6 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 Changes:\r
  * This program is a modified version of wavy.py by Aaron Spike.\r
  * 22-Dec-2006: Wiora : Added axis and isotropic scaling\r
+ * 21-Jun-2007: Tavmjong: Added polar coordinates\r
 \r
 '''\r
 import inkex, simplepath, simplestyle\r
@@ -28,8 +30,8 @@ from math import *
 from random import *\r
 \r
 def drawfunction(xstart, xend, ybottom, ytop, samples, width, height, left, bottom, \r
-    fx = "sin(x)", fpx = "cos(x)", fponum = True, times2pi = False, isoscale = True, drawaxis = True):\r
-    \r
+    fx = "sin(x)", fpx = "cos(x)", fponum = True, times2pi = False, polar = False, isoscale = True, drawaxis = True):\r
+\r
     if times2pi == True:\r
         xstart = 2 * pi * xstart\r
         xend   = 2 * pi * xend   \r
@@ -38,12 +40,18 @@ def drawfunction(xstart, xend, ybottom, ytop, samples, width, height, left, bott
     scalex = width / (xend - xstart)\r
     xoff = left\r
     coordx = lambda x: (x - xstart) * scalex + xoff  #convert x-value to coordinate\r
+    if polar :  # Set scale so that left side of rectangle is -1, right side is +1.\r
+                # (We can't use xscale for both range and scale.)\r
+        centerx = left + width/2.0\r
+        polar_scalex = width/2.0\r
+        coordx = lambda x: x * polar_scalex + centerx  #convert x-value to coordinate\r
+\r
     scaley = height / (ytop - ybottom)\r
     yoff = bottom\r
     coordy = lambda y: (ybottom - y) * scaley + yoff  #convert y-value to coordinate\r
-    \r
+\r
     # Check for isotropic scaling and use smaller of the two scales, correct ranges\r
-    if isoscale:\r
+    if isoscale and not polar:\r
       if scaley<scalex:\r
         # compute zero location\r
         xzero = coordx(0)\r
@@ -70,6 +78,7 @@ def drawfunction(xstart, xend, ybottom, ytop, samples, width, height, left, bott
     # step is the distance between nodes on x\r
     step = (xend - xstart) / (samples-1)\r
     third = step / 3.0\r
+    ds = step * 0.001 # Step used in calculating derivatives\r
 \r
     a = [] # path array \r
     # add axis\r
@@ -87,29 +96,60 @@ def drawfunction(xstart, xend, ybottom, ytop, samples, width, height, left, bott
 \r
     # initialize function and derivative for 0;\r
     # they are carried over from one iteration to the next, to avoid extra function calculations. \r
-    y0 = f(xstart) \r
-    if fponum == True: # numerical derivative, using 0.001*step as the small differential\r
-        d0 = (f(xstart + 0.001*step) - y0)/(0.001*step)\r
+    x0 =   xstart\r
+    y0 = f(xstart)\r
+    if polar :\r
+      xp0 = y0 * cos( x0 )\r
+      yp0 = y0 * sin( x0 )\r
+      x0 = xp0\r
+      y0 = yp0\r
+    if fponum or polar: # numerical derivative, using 0.001*step as the small differential\r
+        x1 = xstart + ds # Second point AFTER first point (Good for first point)\r
+        y1 = f(x1)\r
+        if polar :\r
+            xp1 = y1 * cos( x1 )\r
+            yp1 = y1 * sin( x1 )\r
+            x1 = xp1\r
+            y1 = yp1\r
+        dx0 = (x1 - x0)/ds \r
+        dy0 = (y1 - y0)/ds\r
     else: # derivative given by the user\r
-        d0 = fp(xstart)\r
+        dx0 = 0 # Only works for rectangular coordinates\r
+        dy0 = fp(xstart)\r
 \r
     # Start curve\r
-    a.append([' M ',[coordx(xstart), coordy(y0)]]) # initial moveto\r
+    a.append([' M ',[coordx(x0), coordy(y0)]]) # initial moveto\r
 \r
     for i in range(int(samples-1)):\r
-        x = (i+1) * step + xstart\r
-        y1 = f(x)\r
-        if fponum == True: # numerical derivative\r
-            d1 = (y1 - f(x - 0.001*step))/(0.001*step)\r
+        x1 = (i+1) * step + xstart\r
+        x2 = x1 - ds # Second point BEFORE first point (Good for last point)\r
+        y1 = f(x1)\r
+        y2 = f(x2)\r
+        if polar :\r
+            xp1 = y1 * cos( x1 )\r
+            yp1 = y1 * sin( x1 )\r
+            xp2 = y2 * cos( x2 )\r
+            yp2 = y2 * sin( x2 )\r
+            x1 = xp1\r
+            y1 = yp1\r
+            x2 = xp2\r
+            y2 = yp2\r
+        if fponum or polar: # numerical derivative\r
+            dx1 = (x1 - x2)/ds\r
+            dy1 = (y1 - y2)/ds\r
         else: # derivative given by the user\r
-            d1 = fp(x)\r
+            dx1 = 0 # Only works for rectangular coordinates\r
+            dy1 = fp(x1)\r
         # create curve\r
-        a.append([' C ',[coordx(x - step + third), coordy(y0 + (d0 * third)), \r
-            coordx(x - third), coordy(y1 - (d1 * third)),\r
-            coordx(x), coordy(y1)]])\r
-        y0 = y1 # next segment's y0 is this segment's y1\r
-        d0 = d1 # we assume the function is smooth everywhere, so carry over the derivative too\r
-            \r
+        a.append([' C ',\r
+                  [coordx(x0 + (dx0 * third)), coordy(y0 + (dy0 * third)), \r
+                   coordx(x1 - (dx1 * third)), coordy(y1 - (dy1 * third)),\r
+                   coordx(x1),                 coordy(y1)]\r
+                  ])\r
+        x0  = x1  # Next segment's start is this segments end\r
+        y0  = y1\r
+        dx0 = dx1 # Assume the function is smooth everywhere, so carry over the derivative too\r
+        dy0 = dy1    \r
     return a\r
 \r
 class FuncPlot(inkex.Effect):\r
@@ -127,6 +167,10 @@ class FuncPlot(inkex.Effect):
                         action="store", type="inkbool", \r
                         dest="times2pi", default=True,\r
                         help="Multiply x-range by 2*pi")    \r
+        self.OptionParser.add_option("--polar",\r
+                        action="store", type="inkbool", \r
+                        dest="polar", default=False,\r
+                        help="Plot using polar coordinates")    \r
         self.OptionParser.add_option("--ybottom",\r
                         action="store", type="float", \r
                         dest="ybottom", default=-1.0,\r
@@ -167,6 +211,10 @@ class FuncPlot(inkex.Effect):
                         action="store", type="string", \r
                         dest="tab", default="sampling",\r
                         help="The selected UI-tab when OK was pressed") \r
+        self.OptionParser.add_option("--funcplotuse",\r
+                        action="store", type="string", \r
+                        dest="funcplotuse", default="",\r
+                        help="dummy") \r
         self.OptionParser.add_option("--pythonfunctions",\r
                         action="store", type="string", \r
                         dest="pythonfunctions", default="",\r
@@ -191,7 +239,7 @@ class FuncPlot(inkex.Effect):
                 if t:\r
                     newpath.set('transform', t)\r
                     \r
-                # top and bottom where exchanhged\r
+                # top and bottom were exchanged\r
                 newpath.set('d', simplepath.formatPath(\r
                             drawfunction(self.options.xstart,\r
                                 self.options.xend,\r
@@ -203,6 +251,7 @@ class FuncPlot(inkex.Effect):
                                 self.options.fpofx,\r
                                 self.options.fponum,\r
                                 self.options.times2pi,\r
+                                self.options.polar,\r
                                 self.options.isoscale,\r
                                 self.options.drawaxis)))\r
                 newpath.set('title', self.options.fofx)\r