曲线之美——塞尔曲线
计算机科学与技术一班 周星
在我们的电脑中有这样一个屏幕保护程序叫做贝塞尔曲线,不知道大家留意过没有?因为这个学期我既学了c语言,又学了matlab,所以对编程很感兴趣。我认为自己编出屏幕保护程序来既是一种学习知识的方式,也是一种开拓智力、放松心情的休闲方式。上网查了贝塞尔曲线的数学表示式之后,我就开始用自己可怜的一点matlab知识解决它(其实本学期matlab学的挺多的,只是本人掌握的少,辜负了老师的期望)。网上的给出的贝塞尔曲线的定义如下:
在图形图像编程时,我们常常需要根据一系列已知点坐标来确定一条光滑曲线。其中有些曲线需要严格地通过所有的已知点,而有些曲线却不一定需要。在后者中,比较有代表性的一类曲线是贝塞尔曲线(Bézier Splines)。 在历史上,研究贝塞尔曲线的人最初是按照已知曲线参数方程来确定四个点的思路设计出这种矢量曲线绘制法。涕淌为了向大家介绍贝塞尔曲线的公式,也故意把问题的已知和所求颠倒了一下位置:如果已知一条曲线的参数方程,系数都已知,并且两个方程里都含有一个参数t,它的值介于0、1之间,表现形式如下所示: x(t) = ax * t ^ 3 + bx * t ^ 2 + cx * t + x0 y(t) = ay * t ^ 3 + by * t ^ 2 + cy * t + y0 由于这条曲线的起点(x0,y0)是已知的,我们可以用以下的公式来求得剩余三个点的坐
标: x1 = x0 + cx / 3 x2 = x1 + ( cx + bx ) / 3 x3 = x0 + cx + bx + ax y1 = y0 + cy / 3 y2 = y1 + ( cy + by ) / 3 y3 = y0 + cy + by + ay 你细细观察一下就知道了,无论方程的已知和所求是什么,总是有六个未知数,并且我们总能找到六个等式(记住(x0,y0)总是已知的),也就是说,上面的方法是完全可逆的,因此我们可以根据四个已知点坐标来反求曲线参数公式的系数。稍微一变换就得到了下面这组公式: cx = 3 * ( x1 - x0 ) bx = 3 * ( x2 - x1 ) - cx ax = x3 - x0 - cx - bx cy = 3 * ( y1 - y0 )
by = 3 * ( y2 - y1 ) - cy ay = y3 - y0 - cy - by 所以说,对于坐标任意的四个已知点,你总能创建一条贝塞尔曲线 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/killwd/archive/2006/12/25/1460478.aspx 根据上面已经说得很清楚的数学语言,我们可以动手了。大致的算法是这样的:随机产生2X4的矩阵,然后算出六个变量。然后给t这个向量赋值0到1,然后作图。为了图像有动画效果还要不断地给t微小增量。为了奖励我们的眼睛,可以画多条。程序及注释如下:
clear %清除变量
f=figure; %创建图形窗口并取句柄
dt=0.01; %微小增量
while get(f,’currentcharacter’)~=char(27) %循环终止条件——按esc键终止
M=rand(2,4); %生成一个随机矩阵
cx=3*(M(1,2)-M(1,1)); %算出六个系数
bx=3*(M(1,3)-M(1,2))-cx;
ax=M(1,4)-M(1,1)-cx-bx;
cy=3*(M(2,2)-M(2,1));
by=3*(M(2,3)-M(2,2))-cy;
ay=M(2,4)-M(2,1)-cy-by;
M1=rand(2,4); cx1=3*(M1(1,2)-M1(1,1)); bx1=3*(M1(1,3)-M1(1,2))-cx1;
ax1=M1(1,4)-M1(1,1)-cx1-bx1;
cy1=3*(M1(2,2)-M1(2,1));
by1=3*(M1(2,3)-M1(2,2))-cy1;
ay1=M1(2,4)-M1(2,1)-cy1-by1;
%生成另一个随机矩阵%算出另外六个变量
t=0:0.05:1; %向量t,也是曲线的x的范围
for i=1:60 %每次生成的曲线移动六十次(动画效果)
xt=ax*t.^3+bx*t.^2+cx*t.^1+M(1,1); %第一簇贝塞尔曲线的x的参数方程
yt=ay*t.^3+by*t.^2+cy*t.^1+M(2,1); %第一簇曲线有三条
yt1=ay*t.^3+by*t.^2+cy*t.^1+M(2,1)+0.08;
yt2=ay*t.^3+by*t.^2+cy*t.^1+M(2,1)-0.08;
xta=ax1*t.^3+bx1*t.^2+cx1*t.^1+M1(1,1);%第二簇贝塞尔曲线的参数方程
yta=ay1*t.^3+by1*t.^2+cy1*t.^1+M1(2,1);%第二簇曲线也有三条
yta1=ay1*t.^3+by1*t.^2+cy1*t.^1+M1(2,1)+0.08;
yta2=ay1*t.^3+by1*t.^2+cy1*t.^1+M1(2,1)-0.08;
plot(xt,yt,'o-r',xt,yt1,'-.g',xt,yt2,'-*c',xta,yta,'y',xta,yta1,'.m',xta,yta2,'ow');%作图
axis off %不显示坐标轴(这样看起来更像屏保)
t=t+dt; pause(0.03); end drawnow; end 下面是运行过程中的几个截图:
%曲线移动dt
%移动慢一点以便引起人的视觉感受
%for循环结束
%画当前的图像
%结束
p.s.:谢谢周老师的辛勤栽培。
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- stra.cn 版权所有 赣ICP备2024042791号-4
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务