image thumbnail
from Light show by Tim Streeter
Light sources float around stationary spheres.

light_show(large_sphere_points,large_sphere_colors,...
% -------------------------------------------------------------------------
% light_show.m
% -------------------------------------------------------------------------
% Renders stationary inner spheres and moving light sources with optional
% smaller spheres.
% -------------------------------------------------------------------------
% Usage: light_show(large_sphere_points,large_sphere_colors,...
%    large_sphere_radius,large_sphere_transparency,...
%    number_of_lights,light_sphere_points,light_source_radius,...
%    light_colors,number_of_frames);
% -------------------------------------------------------------------------
% Inputs:
% -------------------------------------------------------------------------
%          large_sphere_points - number of points used in the stationary
%                                sphere rendering (see SPHERE.M).
%          large_sphere_colors - color array for stationary spheres.
%                                {size = [number of stationary spheres,3]}
%
%                                EXAMPLE:
%                                 3 spheres with 1st color red, 2cd blue
%                                 and 3rd green.
%
%                                 large_sphere_colors(1,:)=[1 0 0]; %red
%                                 large_sphere_colors(2,:)=[0 0 1]; %blue
%                                 large_sphere_colors(3,:)=[0 1 0]; %green
%                                   
%          large_sphere_radius - radius of stationary spheres.
%                                {size = [number of stationary spheres]}
%    large_sphere_transparency - transparency (FaceAlpha) values for
%                                stationary spheres.
%                                {size = [number of stationary spheres]}
%             number_of_lights - number of moving lights.
%          light_sphere_points - number of points used in the moving.
%                                sphere rendering.  Set to 0 for no moving
%                                sphere surfaces.
%          light_source_radius - radius of moving spheres
%                 light_colors - color array for moving light sources (same
%                                format as with large_sphere_colors
%                                example above).
%             number_of_frames - total number of animation frames
% -------------------------------------------------------------------------
% Outputs:
% -------------------------------------------------------------------------
%   NONE
% -------------------------------------------------------------------------
% T. Streeter, 19 DEC 2006
% -------------------------------------------------------------------------
function light_show(large_sphere_points,large_sphere_colors,...
    large_sphere_radius,large_sphere_transparency,...
    number_of_lights,light_sphere_points,light_source_radius,...
    light_colors,number_of_frames);
    
%Set figure window position:
screen_size=get(0,'ScreenSize');
fig_position=[screen_size(3)/4 screen_size(4)/4 ...
    screen_size(3)/2 screen_size(4)/2];

%generate default sphere surface for stationary spheres:
[x_inner,y_inner,z_inner]=sphere(large_sphere_points);

%Generate matrix for single color data array:
temp_color_matrix=ones(large_sphere_points+1,large_sphere_points+1);

%Render the inner stationary spheres:
%------------------------------------
figure,subplot('Position',[0 0 1 1]),hold on

for n_in=1:length(large_sphere_radius)
    
    S_inner(n_in)=surf(x_inner*large_sphere_radius(n_in),...
        y_inner*large_sphere_radius(n_in),...
        z_inner*large_sphere_radius(n_in));
    
    inner_sphere_color_data(:,:,1)=temp_color_matrix*large_sphere_colors(n_in,1);
    inner_sphere_color_data(:,:,2)=temp_color_matrix*large_sphere_colors(n_in,2);
    inner_sphere_color_data(:,:,3)=temp_color_matrix*large_sphere_colors(n_in,3);
    
    set(S_inner(n_in),'CData',inner_sphere_color_data,...
        'EdgeAlpha',0,'FaceAlpha',large_sphere_transparency(n_in),...
        'FaceLighting','gouraud','BackFaceLighting','reverselit',...
        'SpecularStrength',1,'SpecularColorReflectance',1)
    clear inner_sphere_color_data
    
end
clear x_inner y_inner z_inner

%render and figure settings:
shading flat, axis off
set(gcf,'Color','k','Position',fig_position,...
    'MenuBar','none','Name','light_show')

%generate default sphere surface for light spheres:
if light_sphere_points~=0 %if no sphere is requireed, do not render light spheres
    [light_xsurf,light_ysurf,light_zsurf]=sphere(light_sphere_points);
    light_xsurf=light_xsurf*light_source_radius;
    light_ysurf=light_ysurf*light_source_radius;
    light_zsurf=light_zsurf*light_source_radius;
end

%Generate matrix for single color data array:
temp_color_matrix=ones(light_sphere_points+1,light_sphere_points+1);

%Set initial light parameters:
light_elevation=(rand(1,number_of_lights)*2-1)*pi/2; %set random elevation
light_azimuth=rand(1,number_of_lights)*2*pi; %set random azimuth
light_distance=(.5+rand(1,number_of_lights)*.5)*max(large_sphere_radius); %set random distance

%Set motion parameters:
light_delta_elevation=(2*rand(1,number_of_lights)-1)*20; %elevation change
light_delta_azimuth=(2*rand(1,number_of_lights)-1)*40; %azimuth change
radius_modulation_frequency=(rand(1,number_of_lights)*3+3)/100; %distance moduation frequency
radius_modulation_phase=rand(1,number_of_lights)*2*pi; %distance modulation phase
radius_modulation=(rand(1,number_of_lights)+1)/2*min(light_distance)*2; %distance modulation magnitude

%Render lights and small spheres:
%--------------------------------
for nL=1:number_of_lights
    
    light_handle(nL)=light; %geneate a light
 
    %Translate spherical coordinates to Cartesian:
    [current_light_pos_x,current_light_pos_y,current_light_pos_z]=...
        sph2cart(light_azimuth(nL),light_elevation(nL),light_distance(nL));

    %Generate color data array:
    light_color_data(:,:,1)=temp_color_matrix*light_colors(nL,1);
    light_color_data(:,:,2)=temp_color_matrix*light_colors(nL,2);
    light_color_data(:,:,3)=temp_color_matrix*light_colors(nL,3);

    if light_sphere_points~=0 %if no sphere is requireed, do not render light spheres
        
        SL(nL)=surf(light_xsurf+current_light_pos_x,...
            light_ysurf+current_light_pos_y,...
            light_zsurf+current_light_pos_z);
        
        set(SL(nL),'CData',light_color_data,'EdgeAlpha',0,'FaceAlpha',.1,...
                'AmbientStrength',.6,'FaceLighting','gouraud',...
                'BackFaceLighting','reverselit','SpecularStrength',1,...
                'SpecularColorReflectance',1)
            
    end
    
    %Set light parameters:
    set(light_handle(nL),'Position',[current_light_pos_x current_light_pos_y current_light_pos_z],...
        'Color',light_colors(nL,:),'Style','local')
    
end

%Start animation:
%----------------
for nt=0:number_of_frames
    
    for nL=1:number_of_lights
        
        %Update azimuth and elevation light coordinates:
        light_elevation(nL)=light_elevation(nL)+light_delta_elevation(nL)*pi/180;
        light_azimuth(nL)=light_azimuth(nL)+light_delta_azimuth(nL)*pi/180;
        current_distance=light_distance(nL)+...
            radius_modulation(nL)*sin(2*pi*radius_modulation_frequency(nL)*nt+radius_modulation_phase(nL));

        %Translate spherical coordinates to Cartesian:
        [current_light_pos_x,current_light_pos_y,current_light_pos_z]=...
            sph2cart(light_azimuth(nL),light_elevation(nL),current_distance);

        if light_sphere_points~=0 %if no sphere is requireed, do not render light spheres
            
            %Updated surface data:
            xdata_temp=light_xsurf+current_light_pos_x;
            ydata_temp=light_ysurf+current_light_pos_y;
            zdata_temp=light_zsurf+current_light_pos_z;
            
            %This is left here for implementing changing light colors:
            light_color_data(:,:,1)=temp_color_matrix*light_colors(nL,1);
            light_color_data(:,:,2)=temp_color_matrix*light_colors(nL,2);
            light_color_data(:,:,3)=temp_color_matrix*light_colors(nL,3);

            set(SL(nL),'CData',light_color_data,'EdgeAlpha',0,'FaceAlpha',1,...
                'XData',xdata_temp,'YData',ydata_temp,'ZData',zdata_temp,...
                'BackFaceLighting','lit','AmbientStrength',.6,'FaceLighting','gouraud')
            
        end

        %Update lights:
        set(light_handle(nL),'Position',[current_light_pos_x current_light_pos_y current_light_pos_z],...
            'Color',light_colors(nL,:),'Style','local')

        axis equal
        axis([-1 1 -1 1 -1 1]*(max(light_distance)+max(radius_modulation))*.66)
        view([15 40])
        drawnow
        
    end
end

Contact us at files@mathworks.com