Search code examples
matlabrecursionfractals

Efficient code for draw a sierpinski triangle with matlab


Following is my code:

function sierpinski(A, B, C, n)
    if n == 0
        patch([A(1), B(1), C(1)], [A(2), B(2), C(2)], [0.0 0.0 0.0]);
    else
       sierpinski(A, (A + B)/2, (A + C)/2, n-1);
       sierpinski(B, (B + A)/2, (B + C)/2, n-1);
       sierpinski(C, (C + A)/2, (C + B)/2, n-1);
end

% sierpinski([0 0], [1 0], [.5 .8], 8)

It's not very effectly. I want to first generating all data then patched, but I don't know how to correctly used. Also, can my code be written use for loops?


Solution

  • Your idea to write one function to generate the data and another to plot it is a good one - it's often a good idea to separate data generation from processing, and processing from output. I would do it something like this:

    function out = sierpinski(a, b, c, n)
    
        if n == 0
            out.xvals = [a(1), b(1), c(1)];
            out.yvals = [a(2), b(2), c(2)];
        else
            out1 = sierpinski(a, (a+b)/2, (a+c)/2, n-1);
            out2 = sierpinski(b, (a+b)/2, (b+c)/2, n-1);
            out3 = sierpinski(c, (a+c)/2, (b+c)/2, n-1);
            out = [out1, out2, out3];
        end
    
    end
    

    This creates a struct of length 3^n, each entry of which contains the coordinates of one of the small triangles in the sierpinski triangle. Your code to plot it might then look like

    >> out = sierpinski([0,0], [1,0], [0.5, sqrt(3)/2], 8);
    >> figure(); hold on;
    >> for i = 1:length(out)
           patch(out(i).xvals, out(i).yvals, 'k');
       end
    

    That crashes on my machine (it seems that Matlab doesn't handle thousands of patches on the same plot very well) but a similar loop which plots one point at the corner of each small triangle.

    >> x = [out.xvals];
    >> y = [out.yvals];
    >> plot(x, y, '.');
    

    which produces this plot

    enter image description here