2

以下是我的代码:

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)

这不是很有效。我想先生成所有数据然后打补丁,但我不知道如何正确使用。另外,我的代码可以写成用于循环吗?

4

3 回答 3

8

您编写一个函数来生成数据并编写另一个函数来绘制数据的想法是一个好主意 - 将数据生成与处理以及处理与输出分开通常是个好主意。我会这样做:

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

这将创建一个长度结构3^n,其中的每个条目都包含谢尔宾斯基三角形中一个小三角形的坐标。您绘制它的代码可能看起来像

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

这在我的机器上崩溃了(似乎 Matlab 不能很好地处理同一个图上的数千个补丁)但是一个类似的循环在每个小三角形的角处绘制一个点。

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

产生这个情节

在此处输入图像描述

于 2013-09-10T10:00:05.533 回答
0

我没有准备好任何代码示例,但是:

您可以尝试在一个大的补丁中绘制所有三角形,而不是将每个三角形绘制为单个补丁对象。基本上,您只需要连接由 NaN 分隔的每个三角形的 x 和 y 坐标 - 这将防止补丁绘制连接各个三角形的线。例如,以下行产生两个独立的三角形:

p = patch( [0 0.5 1 0 NaN 2 2.5 3 2 NaN ], [ 0 1 0 0 NaN 2 3 2 2 NaN], 'k')

请注意,要获得一个闭合三角形,您需要以这种方式每个三角形 4 个点,最后一个点与第一个点相同。

于 2013-09-10T10:41:56.230 回答
0

编辑:对于每个递归级别,您可以“擦除”中心三角形,因此您必须修补更少的三角形。例如,在第一级,您有三个“向上”三角形和一个“向下”三角形。您可以路径这个,而不是其他三个。一个更紧凑的例程是:

function sierpinski(rec)
  [x, x0] = deal(cat(3, [1 0]', [-1 0]', [0 sqrt(3)]')); 
  for k = 1 : rec x = x(:,:) + x0 * 2 ^ k / 2; 
end 
patch('Faces', reshape(1 : 3 * 3 ^ k, 3, '')', 'Vertices', x(:,:)') 
end

所以你必须填充更少的三角形,如果......

function sierpinski(rec)
close all
%Main Triangle
hFig=figure;
units=get(hFig,'units');
set(hFig,'units','normalized','outerposition',[0 0 1 1], 'Color', 'white');
set(hFig,'units',units); clear units
hold on
Vx=[0 0.5 1]; Vy=[0 realsqrt(3)/2 0];
fill(Vx,Vy,'b')
%the number of white triangles = sum(3.^(0:1:rec-1))
whitex=NaN(3,sum(3.^(0:1:rec-1))); whitey=whitex; K=1;
for S=1:rec
    [Vx,Vy]=sierpinskisect;
end
fill(whitex,whitey,'w')

function [outX,outY]=sierpinskisect
    %the number of blue triangles = 3^S
    L=size(Vx,1);
    outX=NaN(3*L,3); outY=outX; J=1;
    for I=1:L
        %left blue triangle
        outX(J,:)=[Vx(I,1) mean(Vx(I,(1:2))) mean(Vx(I,([1 3])))];
        outY(J,:)=[Vy(I,1) mean(Vy(I,(1:2))) mean(Vy(I,([1 3])))];
        J=J+1;
        %right blue triangle
        outX(J,:)=[mean(Vx(I,([1 3]))) mean(Vx(I,(2:3))) Vx(I,3)];
        outY(J,:)=[mean(Vy(I,([1 3]))) mean(Vy(I,(2:3))) Vy(I,3)];
        J=J+1;
        %upper blue triangle
        outX(J,:)=[mean(Vx(I,(1:2))) Vx(I,2) mean(Vx(I,(2:3)))];
        outY(J,:)=[mean(Vy(I,(1:2))) Vy(I,2) mean(Vy(I,(2:3)))];
        J=J+1;
        %white triangle
        whitex(:,K)=[outX(J-3,2);outX(J-3,3);outX(J-2,2)];
        whitey(:,K)=[outY(J-3,2);outY(J-3,3);outY(J-2,2)];
        K=K+1;
    end
end

结尾

于 2018-04-28T13:50:45.000 回答