问题一:
问题描述:
斐波那契螺旋线,以斐波那契数为边的正 方形拼成的长方形,然后在正方形里面画一个90度的扇形,连起来的弧线就是斐波那契螺旋线。
问题求解算法:
我们可以通过模拟的方法把每一段弧线所对应的圆心和半径都找出来,然后画出对应的弧线。
MATLAB程序:
Clear
//计算斐波那契数即计算半径
f = [1 1];
for k = 1:100
f(k + 2) = f(k) + f(k + 1);
if f(k) > 100
break;
end
k = k + 1;
end
//模拟出每段弧线对应的圆心
x = [0 0];
y = [0 0];
for i = 3:7
if mod(i,4) == 1
x(i) = x(i - 1) - f(i - 1) + f(i);
y(i) = y(i - 1);
elseif mod(i,4) == 2
x(i) = x(i - 1);
y(i) = y(i - 1) - f(i - 1) + f(i);
elseif mod(i,4) == 3
x(i) = x(i - 1) + f(i - 1) - f(i);
y(i) = y(i - 1);
elseif mod(i,4) == 0
x(i) = x(i - 1);
y(i) = y(i - 1) + f(i - 1) - f(i);
end
end
//根据圆心和半径画出每段弧线
theta = [0 0];
for i = 3:7
theta(i) = theta(i - 1) + pi / 2;
end
for i = 2:7
a = theta(i) - pi / 2:pi/100:theta(i);
x1 = x(i) + cos(a) * f(i);
y1 = y(i) + sin(a) * f(i);
hold on
plot(x1,y1);
end
axis equal
结果分析:
改代码很好的绘制出了斐波那契螺旋线,但是不够灵活因此对其进行了函数的包装进行了以下优化:
优化代码:
function F = drawfibonnaci(n)
f = [1 1];
for k = 1:n + 10
f(k + 2) = f(k) + f(k + 1);
k = k + 1;
end
x = [0 0];
y = [0 0];
for i = 3:n
if mod(i,4) == 1
x(i) = x(i - 1) - f(i - 1) + f(i);
y(i) = y(i - 1);
elseif mod(i,4) == 2
x(i) = x(i - 1);
y(i) = y(i - 1) - f(i - 1) + f(i);
elseif mod(i,4) == 3
x(i) = x(i - 1) + f(i - 1) - f(i);
y(i) = y(i - 1);
elseif mod(i,4) == 0
x(i) = x(i - 1);
y(i) = y(i - 1) + f(i - 1) - f(i);
end
end
theta = [0 0];
for i = 3:n
theta(i) = theta(i - 1) + pi / 2;
end
for i = 2:n
a = theta(i) - pi / 2:pi/100:theta(i);
x1 = x(i) + cos(a) * f(i);
y1 = y(i) + sin(a) * f(i);
hold on
plot(x1,y1);
end
axis equal
end
问题二:
问题描述:
绘制谢尔宾斯基三角形 (Sierpinskitriangle) 是一 种分形,由波兰数学家谢尔宾斯基在1915年提出,它是一种典型 的自相似集。其生成过程为:取一个实心的三角形(通常使用 等边三角形),沿三边中点的连线,将它分成四个小三角形, 然后去掉中间的那一个小三角形。接下来对其余三个小三角形
重复上述操作。
问题求解算法:
我们分析问题不难发现,对于每一次操作其本质上都是一样的,大三角形与其内部的小三角有着父子关系,因此我们可以通过递归的方式来解决。
MATLAB程序:
//画三角形递归
function f = drawtriangle(x1,y1,x2,y2,x3,y3,cnt)
x12 = (x1 + x2) / 2;
y12 = (y1 + y2) / 2;
x23 = (x2 + x3) / 2;
y23 = (y2 + y3) / 2;
x13 = (x1 + x3) / 2;
y13 = (y1 + y3) / 2;
if cnt <= 3
drawline(x1,y1,x2,y2);
drawline(x1,y1,x3,y3);
drawline(x3,y3,x2,y2);
drawtriangle(x1,y1,x12,y12,x13,y13,cnt + 1);
drawtriangle(x12,y12,x2,y2,x23,y23,cnt + 1);
drawtriangle(x23,y23,x13,y13,x3,y3,cnt + 1);
end
end
//画直线
function ff = drawline(x1,y1,x2,y2)
a = x1:(x2 - x1) / 100:x2;
if y2 == y1
y = y1 + a - a;
hold on
plot(a,y);
else
k = (x2 - x1) / (y2 - y1);
b = y1 - k * x1;
y = k * a + b;
hold on
plot(a,y);
end
end
上述代码没法解决竖直线的问题,后经翻阅matlab函数发现有line函数,以下是优化后的代码:
function ff = drawline(x1,y1,x2,y2)
hold on
line([x1,x2], [y1,y2]);
end
结果分析:
改代码很好的绘制出了任意情况下的谢尔宾斯基三角形但存在无法控制深度的问题因此进而对画三角的代码进行了优化:
function f = drawtriangle(x1,y1,x2,y2,x3,y3,cnt)
x12 = (x1 + x2) / 2;
y12 = (y1 + y2) / 2;
x23 = (x2 + x3) / 2;
y23 = (y2 + y3) / 2;
x13 = (x1 + x3) / 2;
y13 = (y1 + y3) / 2;
if cnt > 0
drawline(x1,y1,x2,y2);
drawline(x1,y1,x3,y3);
drawline(x3,y3,x2,y2);
drawtriangle(x1,y1,x12,y12,x13,y13,cnt - 1);
drawtriangle(x12,y12,x2,y2,x23,y23,cnt - 1);
drawtriangle(x23,y23,x13,y13,x3,y3,cnt - 1);
end
end
优化完的代码虽然对深度实现了可控化,但是运行速度却十分缓慢,这是因为它的复杂度是3^n级别的。