2
\$\begingroup\$

I used recursion to generate fractal and got the desired result but I think my code can be better

I started using MATLAB a few days ago and since than trying and learning new things.
Now this code generates the fractal exactly as I wanted but I feel like it can a little bit neater.
Any suggestions are welcome (even off topic but related to how to use MATLAB) as I am a beginner in MATLAB, they will definitely help me in future.

hold on
x=[0 1 1/2];                %Coordinates of a equilateral triangle 
fill(x,y,'k');
axis equal
axis off
abc(list)                   

function abc(listnew)
    if abs(listnew(1,1)-listnew(1,2))>0.002
        listold=listnew;
        t=size(listold,2)/3;
        for j=1:t
        listnew(1,(j-1)*3+1:j*3)=[(listold(1,(j-1)*3+2)+listold(1,(j-1)*3+1))/2  (listold(1,(j-1)*3+3)+listold(1,(j-1)*3+2))/2 (listold(1,(j-1)*3+1)+listold(1,(j-1)*3+3))/2];
        listnew(2,(j-1)*3+1:j*3)=[listold(2,(j-1)*3+1) (listold(2,(j-1)*3+3)+listold(2,(j-1)*3+2))/2 (listold(2,(j-1)*3+1)+listold(2,(j-1)*3+3))/2];
        end
        pause(2)
        tri(listnew);
        k=size(listnew,2)/3;
        for m=1:k
            f=(m-1)*(3^2);
            l(1,(f+1):(f+3))=[listold(1,(m-1)*3+1) listnew(1,(m-1)*3+1) listnew(1,(m-1)*3+3)];
            l(2,(f+1):(f+3))=[listold(2,(m-1)*3+1) listnew(2,(m-1)*3+1) listnew(2,(m-1)*3+3)];

            l(1,(f+4):(f+6))=[listnew(1,(m-1)*3+1) listold(1,(m-1)*3+2) listnew(1,(m-1)*3+2)];
            l(2,(f+4):(f+6))=[listnew(2,(m-1)*3+1) listold(2,(m-1)*3+2) listnew(2,(m-1)*3+2)];

            l(1,(f+7):(f+9))=[listnew(1,(m-1)*3+3) listnew(1,(m-1)*3+2) listold(1,(m-1)*3+3)];
            l(2,(f+7):(f+9))=[listnew(2,(m-1)*3+3) listnew(2,(m-1)*3+2) listold(2,(m-1)*3+3)];
        end
        abc(l);
    end
end

function tri(list)
    for i =1:(size(list,2)/3)
        fill(list(1,(i-1)*3+1:i*3),list(2,(i-1)*3+1:i*3),'w');
    end
end
\$\endgroup\$
1
\$\begingroup\$

Though MATLAB allows to expand the size of a matrix by assigning to elements outside its bounds, it is always best to preallocate the array to its final size.

The for m=1:k loop has a lot of repeated code. First, m is always used as m-1. You could instead do for m=0:k-1 and simplify the code a bit. Next,

l(1,(f+1):(f+3))=[listold(1,(m-1)*3+1) listnew(1,(m-1)*3+1) listnew(1,(m-1)*3+3)];

can be written as

l(1,(f+1):(f+3)) = listold(1,(m-1)*3+[1,1,3]);

and you do the same for both elements along the 1 dimension, which can be written as

l(:,(f+1):(f+3)) = listold(:,(m-1)*3+[1,1,3]);

All 6 statements in this loop can be summarized as

l(:,(f+1):(f+9)) = listold(:,(m-1)*3+[1,1,3,1,2,2,3,2,3]);

It is possible to replace the whole loop, but that just makes the code less readable, I don’t recommend it.

It is common in MATLAB code to not use spaces, but I think code is more readable with spaces in it. Especially around the = assignment operator. In any case, make sure you use consistent spacing, for i =1:(size(list,2)/3) is rather unsettling to me. ;)

Likewise, be consistent with indentation. The loop for j=1:t is not indented.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks. I will take notes. \$\endgroup\$ Nov 10 at 8:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.