% -------------------------------------------------------------------------
% 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