changeset 26029:700b9f046538

Implement "light" option for surfl (bug #54930). * surfl.m: Implement "light" option. Add new demo.
author Markus Mützel <markus.muetzel@gmx.de>
date Sat, 03 Nov 2018 16:33:35 +0100
parents 8eb4b42771ff
children a21d7d269472
files scripts/plot/draw/surfl.m
diffstat 1 files changed, 39 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/plot/draw/surfl.m	Sun Nov 04 14:25:08 2018 -0800
+++ b/scripts/plot/draw/surfl.m	Sat Nov 03 16:33:35 2018 +0100
@@ -38,13 +38,14 @@
 ##
 ## The default lighting mode @qcode{"cdata"}, changes the cdata property of the
 ## surface object to give the impression of a lighted surface.
-## @strong{Warning:} The alternative mode @qcode{"light"} mode which creates a
-## light object to illuminate the surface is not implemented (yet).
+##
+## The alternate mode @qcode{"light"} creates a light object to illuminate the
+## surface.
 ##
-## The light source location can be specified using @var{lsrc}.  It can be
-## given as a 2-element vector [azimuth, elevation] in degrees, or as a
-## 3-element vector [lx, ly, lz].  The default value is rotated 45 degrees
-## counterclockwise to the current view.
+## The light source location may be specified using @var{lsrc} which can be
+## a 2-element vector [azimuth, elevation] in degrees, or a 3-element vector
+## [lx, ly, lz].  The default value is rotated 45 degrees counterclockwise to
+## the current view.
 ##
 ## The material properties of the surface can specified using a 4-element
 ## vector @var{P} = [@var{AM} @var{D} @var{SP} @var{exp}] which defaults to
@@ -93,8 +94,6 @@
   if (ischar (varargin{end}))
     switch (tolower (varargin{end}))
       case "light"
-        warning ("surfl: light method not supported (yet), using cdata method instead");
-        ## This can be implemented when light objects are supported.
         use_cdata = false;
       case "cdata"
         use_cdata = true;
@@ -144,10 +143,9 @@
     hax = newplot (hax);
 
     htmp = surface (varargin{:});
-    __update_normals__ (htmp);
     if (! ishold ())
       set (hax, "view", [-37.5, 30],
-                "xgrid", "on", "ygrid", "on", "zgrid", "on", "clim", [0 1]);
+                "xgrid", "on", "ygrid", "on", "zgrid", "on");
     endif
 
     ## Get view vector (vv).
@@ -163,23 +161,32 @@
       lv = (R * vv.').';
     endif
 
-    vn = get (htmp, "vertexnormals");
-    dar = get (hax, "dataaspectratio");
-    vn(:,:,1) *= dar(1);
-    vn(:,:,2) *= dar(2);
-    vn(:,:,3) *= dar(3);
+    if (use_cdata)
+      set (hax, "clim", [0 1]);
+
+      __update_normals__ (htmp);
+      vn = get (htmp, "vertexnormals");
+      dar = get (hax, "dataaspectratio");
+      vn(:,:,1) *= dar(1);
+      vn(:,:,2) *= dar(2);
+      vn(:,:,3) *= dar(3);
 
-    ## Normalize vn.
-    vn ./= repmat (sqrt (sumsq (vn, 3)), [1, 1, 3]);
-    [nr, nc] = size (get (htmp, "zdata"));
+      ## Normalize vn.
+      vn ./= repmat (sqrt (sumsq (vn, 3)), [1, 1, 3]);
+      [nr, nc] = size (get (htmp, "zdata"));
 
-    ## Ambient, diffuse, and specular term.
-    cdata = (  r(1) * ones (nr, nc)
-             + r(2) * diffuse  (vn(:,:,1), vn(:,:,2), vn(:,:,3), lv)
-             + r(3) * specular (vn(:,:,1), vn(:,:,2), vn(:,:,3), lv, vv, r(4)));
-    cdata ./= sum (r(1:3));
+      ## Ambient, diffuse, and specular term.
+      cdata = (  r(1) * ones (nr, nc)
+               + r(2) * diffuse  (vn(:,:,1), vn(:,:,2), vn(:,:,3), lv)
+               + r(3) * specular (vn(:,:,1), vn(:,:,2), vn(:,:,3), lv, vv, r(4)));
+      cdata ./= sum (r(1:3));
 
-    set (htmp, "cdata", cdata);
+      set (htmp, "cdata", cdata);
+    else
+      light (hax, "position", lv);
+      set (htmp, "ambientstrength", r(1), "diffusestrength", r(2), ...
+                 "specularstrength", r(3), "specularexponent", r(4));
+    endif
 
   unwind_protect_cleanup
     if (! isempty (oldfig))
@@ -209,3 +216,11 @@
 %! surfl (X,Y,Z, [62.50,30], [0.2 0.6 0.4 25]);
 %! shading interp;
 %! title ("surfl() with lighting vector and material properties");
+
+%!demo
+%! clf;
+%! [X, Y] = meshgrid (-3:1/8:3);
+%! Z = peaks (X, Y);
+%! surfl (X, Y, Z, "light");
+%! shading interp;
+%! title ("surfl() with light object");