Code covered by the BSD License  

Highlights from
Fractal generator

image thumbnail
from Fractal generator by Jakob Laugesen
Function to generate fractal structures Excellent for educational demonstrations.

hs=fractal(N,axiom,gen,cns,scal)
function hs=fractal(N,axiom,gen,cns,scal)
% Function to generate fractal geometries.
% Works in two ways: 1) Generation of one of the three
% predefined geometries or 2) general use, where axiom
% and generator must be specified.
%
% Pre-defined use of the function:
% -------------------------------------------------------------------------
% N =           the level to be generated.
% axiom =       geometry type:
%               1: Sierpinski's pyramide
%               2: Sierpinski's triangle
%               3: Menger's sponge
% EXAMPLES:
% fractal(2,1); % show the Sierpinski's triangle with 2 levels.
% fractal(0,3); % show the axiom of the Menger's sponge.
% fractal(1,3); % show the generator of the Menger's sponge.
%
% The remaining arguments are only used for the general use of the
% function.
%
% General use of the function: NOT WELL TESTED !!!
% -------------------------------------------------------------------------
% N =           the level to be generated.
% axiom =       is the coordinates of the faces (NOT just the corner coordinates).
% generator =   is the coordinates of the pattern faces.
% cns =         is the number of coordinates in the axiom that belongs to each face.
%               (The length of cns must equal the number of faces).
% scal =        the scaling factor.
% hs =          handles to surfaces.
% -------------------------------------------------------------------------
% Copyright (C) Jakob L. Laugesen, laugesen@fysik.dtu.dk / jakob@sensory.dk,
% Chaos Group and BioSim, Dep. of Physics, DTU, Denmark.
% Created: 16/11/09
% Version 1
% -------------------------------------------------------------------------
if nargin==2
    if (axiom==1 || axiom==2) && N>6
        disp('At most six levels for Sierpinski''s triangle and pyramide.');
        return;
    end
    if (axiom==3) && N>3
        disp('At most three levels for Menger''s sponge');
        return;
    end
end
axiomc=[0,0,0];hs=[];N=N-1;
if nargin==2
    if axiom==1 % pyramide
        scal=2;
        h=sqrt(3)/2;
        axiom=[-0.5 -0.5 -h/2;...
            0.5 -0.5 -h/2;...
            0.5 0.5 -h/2;...
            -0.5 0.5 -h/2;...
            -0.5 -0.5 -h/2;...
            0.5 -0.5 -h/2;...
            0 0 h/2;...
            0.5 -0.5 -h/2;...
            0.5 0.5 -h/2;...
            0 0 h/2;...
            0.5 0.5 -h/2;...
            -0.5 0.5 -h/2;...
            0 0 h/2;...
            -0.5 -0.5 -h/2;...
            -0.5 0.5 -h/2;...
            0 0 h/2];
        r=size(axiom,1);
        gen=[axiom/2+repmat([-0.25 -0.25 -h/4],r,1); axiom/2+repmat([-0.25 0.25 -h/4],r,1);...
            axiom/2+repmat([0.25 -0.25 -h/4],r,1);   axiom/2+repmat([0.25 0.25 -h/4],r,1);...
            axiom/2+repmat([0 0 h/4],r,1)];
        cns=[4 3 3 3 3];
    elseif axiom==2 % triangle
        scal=2;
        h1=1/(2*cos(pi/6));
        h2=sqrt(3)/2-h1;
        h3=sqrt(1-h1^2);
        axiom=[-0.5 -h2 -h3/2;...
            0.5 -h2 -h3/2;...
            0.5 -h2 -h3/2;...
            -0.5 -h2 -h3/2;...
            0.5 -h2 -h3/2;...
            0.0 0.0 h3/2;...
            -0.5 -h2 -h3/2;...
            0.0 h1 -h3/2;...
            0.0 0.0 h3/2;...
            0.5 -h2 -h3/2;...
            0.0 h1 -h3/2;...
            0.0 0.0 h3/2];
        gen=[axiom/2+repmat([-0.25 -h2/2 -h3/4],12,1); axiom/2+repmat([0.25 -h2/2 -h3/4],12,1);...
            axiom/2+repmat([0 h1/2 -h3/4],12,1); axiom/2+repmat([0 0 h3/4],12,1)];
        cns=[3 3 3 3];
    elseif axiom==3 % menger sponge
        scal=3;
        e=1/scal;
        axiom=[ -0.5 -0.5 -0.5;...
            0.5 -0.5 -0.5;...
            0.5  0.5 -0.5;...
            -0.5  0.5 -0.5;...
            -0.5 -0.5 0.5;...
            0.5 -0.5 0.5;...
            0.5  0.5 0.5;...
            -0.5  0.5 0.5;...
            0.5  -0.5 -0.5;...
            0.5   0.5 -0.5;...
            0.5   0.5  0.5;...
            0.5  -0.5  0.5;...
            -0.5  -0.5 -0.5;...
            -0.5   0.5 -0.5;...
            -0.5   0.5  0.5;...
            -0.5  -0.5  0.5;...
            0.5   0.5 -0.5;...
            0.5   0.5  0.5;...
            -0.5   0.5  0.5;...
            -0.5   0.5 -0.5;...
            0.5   -0.5 -0.5;...
            0.5   -0.5  0.5;...
            -0.5   -0.5  0.5;...
            -0.5   -0.5 -0.5];
        D=size(axiom,1);
        gen=[axiom/scal+repmat([-e -e -e],D,1); axiom/scal+repmat([0 -e -e],D,1);   axiom/scal+repmat([e -e -e],D,1);...
            axiom/scal+repmat([-e -e 0],D,1);   axiom/scal+repmat([e -e 0],D,1);...
            axiom/scal+repmat([-e -e e],D,1);   axiom/scal+repmat([0 -e e],D,1);    axiom/scal+repmat([e -e e],D,1);...
            axiom/scal+repmat([-e 0 -e],D,1);   axiom/scal+repmat([e 0 -e],D,1);...
            axiom/scal+repmat([-e 0 e],D,1);    axiom/scal+repmat([e 0 e],D,1);...
            axiom/scal+repmat([-e e -e],D,1);   axiom/scal+repmat([0 e -e],D,1);    axiom/scal+repmat([e e -e],D,1);...
            axiom/scal+repmat([-e e 0],D,1);    axiom/scal+repmat([e e 0],D,1);...
            axiom/scal+repmat([-e e e],D,1);    axiom/scal+repmat([0 e e],D,1);     axiom/scal+repmat([e e e],D,1)];
        cns=[4 4 4 4 4 4];
    end
end
genc=[];
for n=1:size(axiom,1):size(gen,1)
    genc=[genc;mean(gen(n:n+size(axiom,1)-1,:))];
end

xyz1=gen;cen1=axiomc;
if N==-1
    xyz2=axiom;
elseif N==0
    xyz2=gen;
else
    for n=1:N
        cen2=[];
        xyz2=[];
        for t=1:size(cen1,1)
            centers=repmat(cen1(t,:),size(genc,1),1)+genc/(scal^(n-1));
            cen2=[cen2;centers];
            xyz2=[];
            if n==N
                for tt=1:size(cen2,1)
                    temp=repmat(cen2(tt,:),size(gen,1),1)+gen/(scal^n);
                    xyz2=[xyz2;temp];
                end
            end
        end
        cen1=cen2;
    end
end
figure('Renderer','zbuffer');
view(3);
for n=1:size(axiom,1):length(xyz2)
    [h]=filltri(xyz2(n:n+size(axiom,1)-1,:),cns);
    hs=[hs;h];
    try
        x=cell2mat(get(hs,'XData')');
        y=cell2mat(get(hs,'YData')');
        z=cell2mat(get(hs,'ZData')');
        ee=unique(([x' y' z']),'rows');
        x=ee(:,1:4)';
        y=ee(:,5:8)';
        z=ee(:,9:12)';
        delete(hs(2:end));
        set(hs(1),'XData',x);
        set(hs(1),'YData',y);
        set(hs(1),'ZData',z);
        set(hs(1),'LineStyle','none');
        hs=hs(1);
    end
end
% T=[0.1822 -0.9833  0       0.4005;...
%     0.0343  0.0064  0.9994 -0.5200;...
%     0.9827  0.1821 -0.0349  8.0953;...
%     0       0       0       1.0000];
% T=[   -1.1511   -0.0905   -0.0000    0.6208;...
%     0.0339   -0.4312    0.9272   -0.2649;...
%     0.0840   -1.0673   -0.3746   10.2533;...
%          0         0         0    1.0000];
% 
% T=[    0.3067   -1.0269         0    0.3601;...
%     1.1598    0.2598    0.2079   -0.8138;...
%     0.2465    0.0552   -0.9781    9.8579;...
%          0         0         0    1.0000    ]; 
% T=[    0.0416   -0.3407         0    0.1495;...
%     0.0301    0.0023    0.3415   -0.1869;...
%     0.4309    0.0328   -0.0239    3.0308;...
%          0         0         0    0.0010]*1000;
% T=[   -0.3007    0.9537   -0.0000   -0.3265;...
%    -0.3261   -0.1028    0.9397   -0.2554;...
%    -0.8962   -0.2826   -0.3420    9.4206;...
%          0         0         0    1.0000];
T=[    1.1273   -0.2500   -0.0000   -0.4387;...
    0.0174    0.0786    0.9976   -0.5468;...
    0.2494    1.1246   -0.0697    8.9222;...
         0         0         0    1.0000]    
view(T);
light('Position',[0 0.1 0],'Color',[1 0 0],'Style','infinite');
set(gca,'XColor','white');
set(gca,'YColor','white');
set(gca,'ZColor','white');
set(gca,'XTick',[]);
set(gca,'YTick',[]);
set(gca,'ZTick',[]);
axis equal;


function [hs]=filltri(x,cns)
hold on;
hs=[];
co=1;
for n=1:length(cns)
    k=co:co+cns(n)-1;
    h=fill3(x(k,1),x(k,2),x(k,3),'cyan');
    hs=[hs;h];
    co=co+cns(n);
end

Contact us at files@mathworks.com