从gnuplot到GeoGebra的艰难之旅

来源:互联网 发布:矩阵的计算方法 编辑:程序博客网 时间:2024/05/18 01:19

请不要对题目中的bra有过多的臆测,它是和ge连在一起的,意思是代数,前面的geo…我就不多说了,几何的意思…
个周末比较忙超级假,节奏如下,加班,中暑,愤怒,打电话投诉中国电信,测试我的远程遥控器,去深圳北站接小小妈和小小…但有一件事不能忘,那就是写点东西,先写一篇关于几何作图的,然后再写一篇关于我DIY的远程遥控器的。
  本文是关于几何作图的,在叙述故事的同时,我默默地推荐了一个工具,这个工具是Geobebra。
  一般而言,我是不写这类Howto的,最终还是写了这篇并不意味着我违背了自己的初衷。之所以会用Geogebra是因为前段时间玩微积分,量子力学的时候需要实时的看到一些动态效果,需要各种曲线作图…当我发现其它的工具都有这样那样的问题正要绝望的时候,发现了Geogebra…因此,这也是一篇有感而发的软文,和普通的Howto完全不同。

我的简单需求

需求很简单,我需要画一个y=sin(x)的泰勒展开式的曲线,并动态展示sin(x)的泰勒展开与原函数曲线的拟合关系。

艰难的历程

起初我是使用gnuplot的,当然,它完成了我的需求,效果如下:

这里写图片描述

然而你们知道这个动画背后的代码是多么不堪入目吗?当然,这跟我不想把时间浪费在gnuplot本身有关系(我并不真懂gnuplot,只是在之前分析TCP数据的时候假装用过),但不管怎样,让我以这种方式起步,我是说什么也无感了。在决定使用Python炫技之前,看下我这个gnuplot代码吧,这个代码是我基于gnuplot的一个例子比葫芦画瓢写出来的:

set term gif animate delay 50set output "c://new//sinx_taylor.gif"set samples 1000set xrange [-20:20]set yrange [-3:3]unset keyset tics textcolor rgb "orange"set border lc rgb "orange"set grid lc rgb "orange"i=0load 'c://new//sinx.plot'set output

以下就是sinx.plot:

i=i+1if (i==1) plot sin(x) lw 3 lc rgb "red" notitle,x lw 3 lc rgb "green" notitleif (i==2) plot sin(x) lw 3 lc rgb "red" notitle,x-x**3/3! lw 3 lc rgb "green" notitleif (i==3) plot sin(x) lw 3 lc rgb "red" notitle,x-x**3/3!+x**5/5! lw 3 lc rgb "green" notitleif (i==4) plot sin(x) lw 3 lc rgb "red" notitle,x-x**3/3!+x**5/5!-x**7/7! lw 3 lc rgb "green" notitleif (i==5) plot sin(x) lw 3 lc rgb "red" notitle,x-x**3/3!+x**5/5!-x**7/7!+x**9/9! lw 3 lc rgb "green" notitleif (i==6) plot sin(x) lw 3 lc rgb "red" notitle,x-x**3/3!+x**5/5!-x**7/7!+x**9/9!-x**11/11! lw 3 lc rgb "green" notitleif (i==7) plot sin(x) lw 3 lc rgb "red" notitle,x-x**3/3!+x**5/5!-x**7/7!+x**9/9!-x**11/11!+x**13/13! lw 3 lc rgb "green" notitleif (i==8) plot sin(x) lw 3 lc rgb "red" notitle,x-x**3/3!+x**5/5!-x**7/7!+x**9/9!-x**11/11!+x**13/13!-x**15/15! lw 3 lc rgb "green" notitleif (i==9) plot sin(x) lw 3 lc rgb "red" notitle,x-x**3/3!+x**5/5!-x**7/7!+x**9/9!-x**11/11!+x**13/13!-x**15/15!+x**17/17! lw 3 lc rgb "green" notitleif (i==10) plot sin(x) lw 3 lc rgb "red" notitle,x-x**3/3!+x**5/5!-x**7/7!+x**9/9!-x**11/11!+x**13/13!-x**15/15!+x**17/17!-x**19/19! lw 3 lc rgb "green" notitleif (i==11) plot sin(x) lw 3 lc rgb "red" notitle,x-x**3/3!+x**5/5!-x**7/7!+x**9/9!-x**11/11!+x**13/13!-x**15/15!+x**17/17!-x**19/19!+x**21/21! lw 3 lc rgb "green" notitleif (i==12) plot sin(x) lw 3 lc rgb "red" notitle,x-x**3/3!+x**5/5!-x**7/7!+x**9/9!-x**11/11!+x**13/13!-x**15/15!+x**17/17!-x**19/19!+x**21/21!-x**23/23! lw 3 lc rgb "green" notitleif (i==13) plot sin(x) lw 3 lc rgb "red" notitle,x-x**3/3!+x**5/5!-x**7/7!+x**9/9!-x**11/11!+x**13/13!-x**15/15!+x**17/17!-x**19/19!+x**21/21!-x**23/23!+x**25/25! lw 3 lc rgb "green" notitleif (i==14) plot sin(x) lw 3 lc rgb "red" notitle,x-x**3/3!+x**5/5!-x**7/7!+x**9/9!-x**11/11!+x**13/13!-x**15/15!+x**17/17!-x**19/19!+x**21/21!-x**23/23!+x**25/25!-x**27/27! lw 3 lc rgb "green" notitleif (i==15) plot sin(x) lw 3 lc rgb "red" notitle,x-x**3/3!+x**5/5!-x**7/7!+x**9/9!-x**11/11!+x**13/13!-x**15/15!+x**17/17!-x**19/19!+x**21/21!-x**23/23!+x**25/25!-x**27/27!+x**29/29! lw 3 lc rgb "green" notitleif (i==16) plot sin(x) lw 3 lc rgb "red" notitle,x-x**3/3!+x**5/5!-x**7/7!+x**9/9!-x**11/11!+x**13/13!-x**15/15!+x**17/17!-x**19/19!+x**21/21!-x**23/23!+x**25/25!-x**27/27!+x**29/29!-x**31/31! lw 3 lc rgb "green" notitleif (i==17) plot sin(x) lw 3 lc rgb "red" notitle,x-x**3/3!+x**5/5!-x**7/7!+x**9/9!-x**11/11!+x**13/13!-x**15/15!+x**17/17!-x**19/19!+x**21/21!-x**23/23!+x**25/25!-x**27/27!+x**29/29!-x**31/31!+x**33/33! lw 3 lc rgb "green" notitleif (i==18) plot sin(x) lw 3 lc rgb "red" notitle,x-x**3/3!+x**5/5!-x**7/7!+x**9/9!-x**11/11!+x**13/13!-x**15/15!+x**17/17!-x**19/19!+x**21/21!-x**23/23!+x**25/25!-x**27/27!+x**29/29!-x**31/31!+x**33/33!-x**35/35! lw 3 lc rgb "green" notitleif (i==19) plot sin(x) lw 3 lc rgb "red" notitle,x-x**3/3!+x**5/5!-x**7/7!+x**9/9!-x**11/11!+x**13/13!-x**15/15!+x**17/17!-x**19/19!+x**21/21!-x**23/23!+x**25/25!-x**27/27!+x**29/29!-x**31/31!+x**33/33!-x**35/35!+x**37/37! lw 3 lc rgb "green" notitleif (i==20) plot sin(x) lw 3 lc rgb "red" notitle,x-x**3/3!+x**5/5!-x**7/7!+x**9/9!-x**11/11!+x**13/13!-x**15/15!+x**17/17!-x**19/19!+x**21/21!-x**23/23!+x**25/25!-x**27/27!+x**29/29!-x**31/31!+x**33/33!-x**35/35!+x**37/37!-x**39/39! lw 3 lc rgb "green" notitleif (i==21) plot sin(x) lw 3 lc rgb "red" notitle,x-x**3/3!+x**5/5!-x**7/7!+x**9/9!-x**11/11!+x**13/13!-x**15/15!+x**17/17!-x**19/19!+x**21/21!-x**23/23!+x**25/25!-x**27/27!+x**29/29!-x**31/31!+x**33/33!-x**35/35!+x**37/37!-x**39/39!+x**41/41! lw 3 lc rgb "green" notitleif (i<23) reread

我不晓得如何用一种简单的方式用循环去实现一个代数式的拼接,因此就写成了上面的样子,如果有谁知道,麻烦告诉我,大恩不言谢!
  在我厌倦了gnuplot的不友好之后,我向主音吉他手抱怨了几句,主音吉他手告诉我gnuplot就是个画图的,哪有那么多的编程功能,不过还是给我参考了一下他写的一些例子,希望能对我有帮助,在此我推荐一下主音吉他手的github:https://github.com/wuxx 他给我参考的gnuplot例子是这个:https://github.com/wuxx/gnuplot/tree/master/RC-charge
显然并没有什么帮助,于是我转向了用Python的库自己写。
  然而Python在Win7上的安装时出现了问题,我的Linux系统有没有图形环境,折腾半个周末仍未果…
  主音吉他手再次建议我使用matlab,我嫌太重,没有力量搬不动,我的需求就是想拼接个级数而已啊,我并不是想掌握一个强大的数学软件!在彻底失望前,主音吉他手又推来了Wolfram,主音告诉我这个编程语言可以编写整个世界,什么都可以做到,完全没有问题!这让我想起了Box2D,也是模拟整个世界的,然而我当年创造出来的世界是如此的简陋,以至于在创生伊始就被我灭了。更可恶的是,Wolfram是收费的,这让我觉得讨厌,主音吉他手则主张赚钱并没有错,于是我只有另辟途径。
  我突然想到了可以使用几何画板,这玩意儿在我中学的时候就用过,我记得它也是收费的,但不管怎样,找到破解版就能上手,毕竟我对它很熟悉了,于是随意在网上搜索几何画板的资源…
  没有得到太多令我满意的,反而有一个叫做Geogebra的东西吸引了我,很多人拿Geogebra来跟几何画板做对比,可见它们是同一样东西,而且Geogebra还是免费的。
  好吧,就它了!

Geogebra如何满足我的需求

Geogebra非常简单,下面是一个满足我最初需求的一个Howto.
  打开Geogebra,它是下面的样子:

这里写图片描述

然后在下面的输入框里输入“y=sin(x)”并回车:

这里写图片描述

这就画出了y=sin(x)的图像,接下来开始关于泰勒展开的细节。
  首先点击界面右下角的小问号,并在帮助栏中定位到“函数与微积分”:

这里写图片描述

然后定位到“泰勒公式”,并按照帮助提示在输入框输入:

这里写图片描述

输入完成后回车键将会使泰勒展开的表达式和拟合图像同时出现:

这里写图片描述

再次点击界面右下角的小问号,帮助栏就消失了,干干净净的:

这里写图片描述

现在的问题是,如何让这一切动起来,即动态显示随着求导阶数的增加,拟合程度会越来越精确这一事实。
  很简单,Geogebra内置了很多的控件,其中就有一个类似进度条的滑块,我们将这个滑动的刻度和求导阶数结合起来就行了。接下来我们添加一个滑块:

这里写图片描述

这里写图片描述

点击“确定”按钮后,完成配置,此时我们会看到,界面里多了一个可以用鼠标左右滑动的滑动条:

这里写图片描述

然而,任你怎么滑动,函数曲线似乎没有任何变化。这是必然的,因为我们还没有建立滑动条刻度n与泰勒展开阶数的关联。
  还记得在输入泰勒公式时的那个格式吗?<表达式,展开点,阶数>,在上面的例子中,我们的阶数填的是5,如果填充为n的话,就建立了滑动条和求导阶数的关联了。

这里写图片描述

这个时候,你再滑动一下滑动条试试看吧:

这里写图片描述

一个动画到此就做成了,当然这个动画要是想动起来,需要人为地去拖动滑动条,能不能让它自己跑起来呢?很容易,空白处点击右键,选中“启动动画”即可。如果你想保存成一张gif图片的格式,那么“文件-导出-动画 gif”即可,非常简单。
  不像其它的Howto或者手册类的文档,关于Geogebra的用法的一点介绍就到此为止,事实上,这根本算不上什么关于用法的介绍,毕竟我只是用Geogebra演示了一个及其简单的例子。
  然而可以看到的是,对比gnuplot而言,做同样的事情,Geogebra是多么的简单方便,对于几何画板,matlab,wolfram而言,Geogebra又是多么的容易获得。我几乎没有在网上搜索Geogebra的使用手册,甚至没有怎么看它的在线帮助,几乎就是完全的盲使用,然后一个泰勒展开就完成了,这反映了Geogebra是多么的友好易于上手。而且最终我将结果做成了动画:

这里写图片描述

对比之前用gnuplot做的那个,可见这个更为优雅,整个过程完全是可视化的环境,这简直太棒了。
  我的这篇文章仅仅只是抛一块砖而已,Geogebra的功能异常强大,它包含了太多的东西根本没有通过文章的形式完全展开,幸运的是,Geogebra拥有强大的社区支撑和论坛,如果你实在是不想自己摸索了,你可以在这些地方找到关于Geogebra任何你需要的。

关于Geogebra

它是一个真的好用的东西,能让我觉得好用的软件确实不多,相反,我认为绝大多数软件都是很难使用的,做很多事情,相比使用软件,除非到万不得已,我更倾向于用更传统的方式。但Geogebra让我在一开始决定要画图的时候,就想到使用它。
  Geogebra是很容易下载的,它有多个操作系统版本,还包括iOS和Android,装在手机上,在任何地方都可以作图(当然这种需求并不多)…如果你实在是不想安装,它还有网页版:
https://www.geogebra.org/graphing

这里写图片描述

是不是很不错呢?!赶紧拿起电话订购吧!其实并不要钱…
  我强烈建议程序员掌握这个工具,对于不是那么重量级的数据分析而言,GeoGebra可以给你直观的展示。当然,它可能并不满足你高大上的需求,我要说的是,朴素是真,复杂都是装,具体详情我会详述。