Parametric plot3d




On Wed, 12 May 2010, Krzysztof Miernik wrote:

< Hello,
< 
< Since Maxima update to 5.21.1 I am not able to plot 3D parametric function
< which depends on single parameter only. Example is a helix:
< 
< plot3d([t,sin(t),cos(t)],[t,0,30],[x,-1,1]);
< plot3d: wrong number of variables: [t]. There should be two
<  -- an error. To debug this try: debugmode(true);
< 
< This plot would work fine with previous version of Maxima. Any ideas how to
< present helix defined in Cartesian coordinates with Maxima now?
 
This is a hack:

plot3d([t,sin(t),cos(t)+1e-230*x],[t,0,30],[x,-1,1]);

----------------------------------------

I've looked at the relevant bit of code and I think it
is needlessly prevents the user from plotting a parameterised
curve without a hack like that above.

I'd like to add the patch below. Note that the patch fixes
a bug in the present code, which swallows something like

plot3d([1,1,1+a],[t,-1,1],[x,-1,1]);

without complaint and without plotting anything.

Leo

------------------------------------------

Index: plot.lisp
===================================================================
RCS file: /cvsroot/maxima/maxima/src/plot.lisp,v
retrieving revision 1.160
diff -u -r1.160 plot.lisp
--- plot.lisp   10 May 2010 04:53:26 -0000      1.160
+++ plot.lisp   12 May 2010 21:03:30 -0000
@@ -1846,7 +1846,10 @@
            (case (length domain)
              (1
               ;; exprn is a parametric representation of a surface
-              (let (vars1 vars2 vars3)
+             ;; or a curve
+              (let ((expr-vars ($listofvars (mfuncall
+                                            (coerce-float-fun exprn lvars)
+                                            (second lvars) (third lvars))))
                 ;; list fun should have two valid ranges after exprn
                 (setq xrange (check-range (pop fun)))
                 (setq yrange (check-range (pop fun)))
@@ -1854,20 +1857,9 @@
                 (setq lvars `((mlist),(second xrange) ,(second yrange)))
                 ;; make sure that the 3 parametric equations depend only
                 ;; on the two variables in lvars
-                (setq vars1
-                      ($listofvars (mfuncall
-                                    (coerce-float-fun (second exprn)
                                     lvars)
-                                    (second lvars) (third lvars))))
-                (setq vars2
-                      ($listofvars (mfuncall
-                                    (coerce-float-fun (third exprn)
                                     lvars)
-                                    (second lvars) (third lvars))))
-                (setq vars3
-                      ($listofvars (mfuncall
-                                    (coerce-float-fun (fourth exprn)
                                     lvars)
-                                    (second lvars) (third lvars))))
-                (setq lvars ($listofvars `((mlist) ,vars1 ,vars2
                 ,vars3)))
-                (if (= 2 ($length lvars))
+                (if (every #'(lambda (v)
+                              (member v lvars :test #'equal))
+                          expr-vars)
                     ;; we do have a valid parametric set. Push it into
                     ;; the functions stack, along with their domain
                     (progn
@@ -1881,8 +1873,8 @@
                         (setf (getf features :const-expr)
                               ($float (meval (fourth exprn))))))
                     (merror
-                     (intl:gettext "plot3d: there must be two
                      variables; found: ~M")
-                     lvars))))
+                     (intl:gettext "plot3d: there must be one or two
variables in ~M;~%found: ~M")
+                     exprn lvars))))

              (3
               ;; expr is a simple function with its own domain. Push
the


-- 
The University of Edinburgh is a charitable body, registered in
Scotland, with registration number SC005336.