
背景
众所周知,笛卡尔是一位超越时代的数学家、物理学家和思想家。他在数学领域所创造的成就影响着自他之后所有的数学研究,他可以被称为解析几何之父。在哲学和心理学方面,笛卡尔也获得了非凡的成就,他是二元论唯心主义和理性主义的代表人物,曾留下了“我思故我在”的论断,开拓了欧陆理性主义哲学。[1]
如果提到笛卡尔的轶事,就不得不说他晚年与瑞典克里斯蒂娜女王的微妙关系。1649年笛卡尔受女王之邀来到瑞典首都斯德哥尔摩担任女王的私人教师。克里斯蒂娜女王最为人所知的地方在于她被认为是17世纪最博学的女性。她不仅仅在绘画、雕塑上有所造诣,还在宗教、哲学、数学上颇有研究。[2]正是因为在哲学和数学上的共同爱好,23岁的女王才会和当时已经53岁的笛卡尔结缘。而本文中所探讨的心形线据说是在笛卡尔临终之前为女王所作,聪慧的女王在拿到曲线方程的那一刻便明白了笛卡尔的心意。在笛卡尔患肺炎病逝之后,克里斯蒂娜女王为他心痛不已甚至改变了自己的宗教信仰,变成了天主教教徒。
心形线的介绍
心形线又被称为心脏线,顾名思义就是一条非常像爱心的曲线。但是它的真正的数学定义是有一个尖点的外摆线。也就是说,一个圆沿着另一个半径相同的圆滚动时,圆上一点的轨迹就是心形线。[3]
最早期的心形线是由笛卡尔用极坐标给出:

theta=-pi:0.001:pi;
r=1-sin(theta);
polar(theta,r,'r');从数学的角度来看,这个心形线的方程可以说是非常的简洁。但是从图形美观的角度,这样的曲线可能还不能称为一条完美的心形线。所以在笛卡尔的基础上,后来的研究者对心形线的构造变得更加丰富多彩,同时也将其的图形美感发挥到极致。
下面列出一些常见的心形线方程

当然本文的主要目的不是为了介绍心形线,而是为了记录用MATLAB实现心形线的过程,也算是为笔者自己的数学建模课做一个良好的开端。(当然这篇文章也是写给可爱的Iris,祝她爱心满满,天天开心!)
实现过程
本文所参考的心形线方程是
主要提供了以下四种方法来用MATLAB实现心形线:

1.用MATLAB内置函数来实现图像
从MATLAB内置的help函数中可以找到ezplot函数的描述和可行代码:
ezplot函数
是一种易用的函数绘图函数,此 MATLAB 函数绘制表达式 fun(x) 在默认定义域 -2π < x < 2π 上的图形,其中 fun(x) 仅是 x 的显函数。
ezplot(fun)
ezplot(fun,[xmin,xmax])
ezplot(fun2)
ezplot(fun2,[xymin,xymax])
ezplot(fun2,[xmin,xmax,ymin,ymax])
ezplot(funx,funy)
ezplot(funx,funy,[tmin,tmax])
ezplot(...,fig)
ezplot(ax,...)
h = ezplot(...)笔者采用了第二种可行代码,并以下面的方式进行实现:
tic;
ezplot('x.^2+(y-(x.^2).^(1/3)).^2-1');%用隐函数的方式实现图像
grid;%给坐标轴标网格
toc;%计算程序运行时间
该代码的运行时间0.194122 秒。
2.用极坐标变换来实现心形线
首先对原方程进行坐标变换,用三角函数代换来重新生成x,y从而得到两列向量,用plot函数来完成心形线的作图
笔者实现该方案的代码如下
tic;
theta=-pi:0.001:pi;%规定theta的取值
x=cos(theta);
y=sin(theta)+((cos(theta)).^2).^(1/3);%对原方程作三角代换
plot(x,y,'r');%用红色曲线画图
grid;%画网格
toc;%计算代码运行时间
该代码运行的时间为 0.070545 秒。
3. 用曲线的显式表达来实现心形线
首先可以将原方程改写成两个显式方程,将两个显式函数同时画在一张图上,这样就能构造出一个完整的心形线。实现这一个步骤需要用到的MATLAB函数有hold on和hold off。
笔者实现此方法的代码如下:
x=-1:0.001:1;%规定x的取值
y1=(x.^2).^(1/3)+(1-x.^2).^(1/2);%心形曲线的上半部分
y2=(x.^2).^(1/3)-(1-x.^2).^(1/2);%心形曲线的下半部分
plot(x,y1,'r');%画出心形曲线的上半部分
hold on;%保持图像
plot(x,y2,'r');%画出心形曲线的下半部分
hold off;%完成图像
grid;%画网格
该代码运行的时间为 0.073224 秒。
4.用蒙特卡洛模拟来实现图像
蒙特卡洛模拟
(英语:Monte Carlo method),也称统计模拟方法,是1940年代中期由于科学技术的发展和电子计算机的发明,而提出的一种以概率统计理论为指导的数值计算方法。是指使用随机数(或更常见的伪随机数)来解决很多计算问题的方法。 [4]
蒙特卡洛模拟的思想就是生成随机数组,验证这些随机数组构成的点在X-Y平面上是否在曲线方程上,如果在曲线方程上就输出,如果不在就记为该点在原点。
笔者实现这个方法的代码为:
tic;
n=100000;%蒙特卡洛模拟次数
x=zeros(n,1);%初始化x向量
y=zeros(n,1);%初始化y向量
for i=1:n
x0=-1+2*rand(1,1);
y0=-1+2.5*rand(1,1);%生成随机点坐标(x0,y0)
if (x0.^2+(y0-(x0.^2).^(1/3)).^2)-1<0.01&&(x0.^2+(y0-(x0.^2).^(1/3)).^2)-1>-0.01%验证是否在曲线方程上
x(i)=x0;
y(i)=y0;%将点赋给向量x,y中的各个位置
end
end
plot(x,y,'.');%作图
grid;%画网格
toc;
该代码运行的时间为0.243665 秒。
拓展
笔者由二维的心形线的作图实现中联想到对于三维空间中的心形用同样的方式实现。
下面的拓展部分就是笔者由上面介绍的代码,再加以扩充用MATLAB实现最后生成的图像。(下面就只展示生成的三维图像不再附上代码部分)

总结与反思
整个实现过程做下来感触最深的一点是作三维的图形的难度要远大于作二维图形。这也应该与笔者对MATLAB中三维函数的图像实现函数的不熟悉,以及和三维函数的复杂程度要比二维函数的复杂程度要高有关。
还有一点是笔者对如何调节图像中点、线、面的颜色和大小还是非常不熟悉,无论是从内置函数的角度还是从最后生成图形中都显得十分生疏。这也是笔者需要在之后的数学建模课中要重点突破的部分。
再说说模型本身,可以从各个程序运行时间的角度得出以下结论:
- 蒙特卡洛模拟的用时最长;这跟其运算次数较多有密切关系
- MATLAB内置函数运行时间其次;这跟MATLAB自身的算法有关
- 用三角代换和显式坐标表达程序运行时间相对较少;这可能是人为减少计算量的好处
最后再说说笔者自己的一点感触和写这一篇文章的缘由:
因为笔者被困在湖北接近两个月,与可爱的Iris千里相隔。最近正好在上数学模型课,就想用自己学到的一些知识来实现这个爱心。这个爱心不仅仅是二维坐标纸上的一条曲线或是三维坐标系一个区域,也是我千里之外和思念和在这困境中的慰藉。希望疫情快点过去,生活回归正常,相隔两地的家人能够团聚,身处异地的恋人能够相拥。
END
参考
- ^https://wiki.hk.wjbk.site/wiki/%E7%AC%9B%E5%8D%A1%E5%B0%94
- ^https://wiki.hk.wjbk.site/baike-%E5%85%8B%E9%87%8C%E6%96%AF%E8%92%82%E5%A8%9C%E5%A5%B3%E7%8E%8B
- ^https://wiki.hk.wjbk.site/baike-%E5%BF%83%E8%84%8F%E7%BA%BF
- ^https://wiki.hk.wjbk.site/baike-%E8%92%99%E5%9C%B0%E5%8D%A1%E7%BE%85%E6%96%B9%E6%B3%95