Christmas scene with Matlab

(c) by Anselm Ivanovas, anselm.ivanovas@student.unisg.ch (2008)

adapted by

Numerical Factory (2018)

Contents

3D christmas scene

Basically just a nice plot for some christmas fun. 3D Plot of a christmas tree with some presents and snow.

Conical tree

We start building a conical tree using the cylinder function of Matlab and defining the radious of the contour.

totSlices = 101; %slices to define the contour
rad(1) = 0; %tree root
rad(2:10) = 1.5; % redefine trunk basis
rad(11:totSlices) = 8:-8/90:0; % tree crown radious (from 8 to 0)
plot(rad,1:101);

A Cone from a Cylinder

Matlab brings the cylinder function that becomes a cone if the radious is decreasing along the vertical direction. Each slice of the cylinder is a circle subdivided in 20 parts. That is, 21 points on the contour circle when you identify the extremal points. By default the cylinder heigth is 1.

[X,Y,Z] = cylinder(rad); %produce a tree formed cylinder
Z = Z*25; %scale the heigth to have a higher tree (25m)
surf(X,Y,Z) %show the cone tree
view([-37.5,4]) %Change the 3D camera view to see better the 3D tree

Crease the tree surface:

Since the tree is very regular and smooth, we add some diffusion to the surface points of the tree to make it look more real.

numContHorizt = 21;
numContVert = totSlices;
treeDiffusion = rand(numContVert,numContHorizt)-0.5; %some horizontal diffusion data computed for all points together

%add this diffusion to the grid points
for contH = 1:numContHorizt
    for contV = 11:numContVert %starting above the trunk
        %get the angle to always diffuse in direction of the radius
        angle = atan(Y(contV,contH)/X(contV,contH));
        %split the diffusion in the two coordinates, depending on the angle
        X(contV,contH) = X(contV,contH)+cos(angle)*treeDiffusion(contV,contH);
        Y(contV,contH) = Y(contV,contH)+sin(angle)*treeDiffusion(contV,contH);
        %some small Vertical diffusion for each point
        Z(contV,contH) = Z(contV,contH)+(rand-0.5)*0.5;
    end
end
%draw the present tree
surfl(X,Y,Z,'light')
view([-37.5,4]) %Change the 3D camera view to see better the 3D tree

Color, view and format

Use as nice green color map (darker at the bottom, lighter at the top)

r = (0.0430:(0.2061/50):0.2491)'; %red   component
g = (0.2969:(0.4012/50):0.6981)'; %green component
b = (0.0625:(0.2696/50):0.3321)'; %blue  component
map = [r,g,b]; %join in a color map table
for cnt = 1:5  %change the lower part to brown for the trunk
    map(cnt,:) = [77,63,5]/265;
end

colormap(map); %set the map
view([-37.5,4])%Change the view to see a little more of the Actual 3D tree
lighting phong %some nice lighting
shading interp %remove grid and smoothen the surface color
axis equal     %takes care of display in the right proportion
axis([-10 10 -10 10 0 30]) %give some more axis space (for the snow later)
axis off %don't show axis
hold on  %remain open to draw the rest
title('Merry Christmas')

Presents

Draw some presents around the tree (each with random color), we use a function listed below that plots a present box according to the following parameters for translation and scale: drawPresent(px,py,pz,scalex,scaley,scalez)

drawPresent(2,-4,0,3,3,2);
drawPresent(-4,3,0,2,3,1.5);
drawPresent(5,3,0,4,3,3);
drawPresent(-14,-5,0,6,3,1);
drawPresent(-9,-10,0,2,2,2);
drawPresent(0,4,0,4,3,3);
drawPresent(-6,-13,0,3,3,3);

Setup Snow

Create some random 3D coordinates for the snow. Some snowflakes will end up inside the tree but just can't be seen then.

snow = 800;     % number of snowflakes
snowX = (rand(snow,1)*25-12.5);
snowY = (rand(snow,1)*25-12.5);
snowZ = (rand(snow,1)*27);
plot3(snowX,snowY,snowZ,'w*') %plot coordinates as white snowflakes
hold off %the scene is done

Function for Present Drawing

Draws a present box with the given coordinate + size in a random color Note: Given coordinates apply to the lower front + left corner of the present (the one closest to the viewer) as seen in the plot

function drawPresent(dx,dy,dz,scalex,scaley,scalez)
% the standard present coordinates: [0,1]x[0,1]x[0,1] cube
    presentX = [0.5 0.5 0.5 0.5 0.5; 0 1 1 0 0; 0 1 1 0 0; 0 1 1 0 0; 0.5 0.5 0.5 0.5 0.5];
    presentY = [0.5 0.5 0.5 0.5 0.5; 0 0 1 1 0; 0 0 1 1 0; 0 0 1 1 0; 0.5 0.5 0.5 0.5 0.5];
    presentZ = [0 0 0 0 0; 0 0 0 0 0; 0.5 0.5 0.5 0.5 0.5; 1 1 1 1 1; 1 1 1 1 1];
% scale present and move it to the right place and get the plot handle
    myHandle = surf((presentX*scalex+dx),(presentY*scaley+dy), (presentZ*scalez+dz));
% draw some presents with random colors
    randColorMap(:,:,1) = repmat(rand,[5,5]);%r component
    randColorMap(:,:,2) = repmat(rand,[5,5]);%g component
    randColorMap(:,:,3) = repmat(rand,[5,5]);%b component
% Assign colormap just to the plot handle object of the present, so the tree
% does not change color
    set(myHandle,'CData',randColorMap)
    shading interp % Nice shading + without grid
end % of function

Exercise:

Try to figure out how to get snow flakes folling down (....and record a video!!!)

Numerical Factory (2018)

% https://es.mathworks.com/matlabcentral/fileexchange/22478-a-christmas-tree-plot
% Copyright (c) 2008, Anselm
% All rights reserved.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are
% met:
%
%     * Redistributions of source code must retain the above copyright
%       notice, this list of conditions and the following disclaimer.
%     * Redistributions in binary form must reproduce the above copyright
%       notice, this list of conditions and the following disclaimer in
%       the documentation and/or other materials provided with the distribution
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
% POSSIBILITY OF SUCH DAMAGE.