10154| 7
|
[入门教程] 【向金老师原创】掌控板数学算法系列(一):玫瑰曲线 |
本帖最后由 rzyzzxw 于 2018-10-3 17:56 编辑 掌控板数学算法系列(一):玫瑰曲线 向 金 【前 言】昨天突然对掌控板着迷了,一口气做了好几个项目。不知不觉发现已经到了凌晨3点了,幸好是国庆节,要不就悲催了。今天分享的是一系列的数学算法之一:玫瑰曲线。 ![]() 【知识储备】玫瑰曲线,大家可以自行百度,基本的意思是:平面内,围绕某一中心点平均分布整数个正弦花瓣的曲线。数学公式是:ρ=a*sin(nθ),a为定长,n为整数(不一定是花瓣数)。如果用参数方程式来表示,玫瑰曲线可以表述为下面的公式: ![]() 其中:a是常量,用来控制图形的大小,参数t为角度,参数n是控制花瓣数量。 【编程思路】: 由于这个图形不是由直线组成,所以,掌控板上的所有绘图函数均无法使用,只能使用其中的像素点显示功能。命令如下: display.pixel(50,0,1) 这个命令中:display.pixel(x, y [,c ]) x , y 为点坐标(x,y)。当如果未给出c,则获取指定像素的颜色值。 如果给出c,则将指定的像素设置为给定的颜色,由于掌控板用的是黑白屏幕,所以用1代表点亮就可以了。 理解了这一点,我们就可以用上面的公式计算出需要显示的像素点,这样就可以画出玫瑰曲线了。如下视频: 【编程一】:实现固定的尺寸和花瓣数量。 这里有一个很重要的学习内容,就是要引入数学计算的库文件:import math 程序如下: [mw_shl_code=python,true]#玫瑰曲线 from mpython import * import math,time#引入库文件 #这是一个自定义的可以画出玫瑰曲线的函数。 #为了方便,角度采用的360度。 #参数a用来控制图像的大小,参数n代表的是花瓣数量。 def DrawRoseCurve(a,n): for t in range(0,360):#循环次数,由于是画一圈,所以是360;可以自行设定 x = math.floor(math.cos(t)*a*math.sin(n*t))#计算x坐标的值,注意:这里需要取整 y = math.floor(math.sin(t)*a*math.sin(n*t))#计算y坐标的值,并且取整 display.pixel(x+64,y+32,1) #显示坐标像素点,为什么要+64、+32,哪是因为要把中心坐标(64,32)作为起点 display.show() #执行 display.fill(0)#清屏 DrawRoseCurve(30,3)[/mw_shl_code] 【提别注意事项】: 1、 一定要采用mpython自动生成的缩进格式,否则你会发现莫名的无法运行,但是还没错误提示。昨晚搞到凌晨3点钟,那是因为开始程序代码运行没有任何问题,但是我后来改成自定义函数后,怎么都无法显示,查询代码没有任何问题,后来才发现在缩进上出现了错误(严格意义上来讲不是错误,而是略有所不规范,但是mpython就无法识别了)。 2、 坐标值x、y必须要进行取整运算,因为掌控板的像素点是无法用小数表示的。昨晚也是因为没有取整,搞得一直黑屏,思考了好久才发现有可能是这个原因,加上取整函数math.floor()后立刻就成功了,当时那个幸福呀。哈哈! 3、 在进行数学函数计算的时候,一定要有前缀名math.(官方的介绍里面目前没有,已经反馈官方修改文档),如果没有加前缀名是无法运行的。 【编程二】:用A、B键进行参数的修改,目前修改的是花瓣数量。程序如下: [mw_shl_code=python,true]#玫瑰曲线,按A加1,按B开始, #目前发现的bug:无法画6个、10个、14个花瓣(除以2后是奇数的花瓣)。 from mpython import * import math,time#引入库文件 def DrawRoseCurve(a,n):#定义函数,函数名称可以自己命名 for t in range(0,360):#循环次数,由于是画一圈,所以是360;可以自行设定 x = math.floor(math.cos(t)*a*math.sin(n*t))#计算x坐标的值,注意:这里需要取整 y = math.floor(math.sin(t)*a*math.sin(n*t))#计算y坐标的值,并且取整 display.pixel(x+64,y+32,1) #显示坐标像素点,为什么要+64、+32,哪是因为要把中心坐标(64,32)作为起点 display.show() #执行 # 按键引脚初始化 display.fill(0)#清屏 display.show()#清屏执行 BTNA = Pin(0, mode=Pin.OPEN_DRAIN,pull=Pin.PULL_UP,value=1) BTNB = Pin(2, mode=Pin.OPEN_DRAIN,pull=Pin.PULL_UP,value=1) display.DispChar('玫瑰曲线', 38, 0) display.DispChar('输入花瓣数量,按A加', 0, 17) display.DispChar('按B开始', 0, 34) display.show() #执行 n1 = 0 jishu = True Start = False while True: if jishu: if BTNA.value() == 0 and BTNB.value() == 1 : display.fill(0)#清屏 display.show()#清屏执行 n1 = n1+1 display.DispChar('数量:%d' % n1, 0, 0) display.show()#执行 time.sleep_ms(400) if BTNA.value() == 1 and BTNB.value() == 0 : jishu = False Start = True if Start: if n1%2 == 0: n1=n1/2 display.fill(0)#清屏 display.show()#清屏执行 DrawRoseCurve(30,n1)#调用函数 Break[/mw_shl_code] 【特别提醒事项】: 1、 按键识别后一定要加延时,否在会连续识别、累加; 2、 目前发现的bug:无法画6个、10个、14个花瓣(除以2后是奇数的花瓣)。这是因为:当n为奇数时,玫瑰花瓣时n个,但是当n为偶数时,玫瑰花瓣时2n个,根据这个原理当n是偶数时,我把n进行了除以2的处理,但是,由于6、10、14等除以2后成了奇数,结果就画成了3个、5个、7个花瓣。当然这个是可以用程序算法进行修正的,期待大家能做出来。 【写在后面的话】: 其实这个程序我主要是用来锻炼自己的自定义函数的能力,所以在写法上比较侧重这种方式,大家可以根据自己的方式进行修改。 另外,我还做了一个蝴蝶的曲线函数,但是由于掌控板的屏幕太小,显示效果一班,我也放出来供大家参考。 ![]() 程序如下: [mw_shl_code=python,true]from mpython import * import math,time#引入库文件 #这是一个自定义的可以画蝴蝶的函数 #参数n代表的是蝴蝶的层数,层数越多,蝴蝶的翅膀效果越好 def DrawButterfly(n): n = n*360 for t in range(0,n): p = math.sin(t/12)**5 p = math.e**math.cos(t)-2*math.cos(4*t)+p x = math.floor(a*math.sin(t)*p)#计算x坐标的值,注意:这里需要取整 y = math.floor(b*math.cos(t)*p-10)#计算y坐标的值,并且取整 display.pixel(x+64,y+32,1) #显示坐标像素点,为什么要+64、+32,哪是因为要把中心坐标(64,32)作为起点 display.show() #执行 display.fill(0)#清屏 display.show()#清屏执行 a = 15 #蝴蝶的宽度 b = 10 #蝴蝶的高度 DrawButterfly(1)[/mw_shl_code] |
© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed