3469|4

53

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

ESP32学习笔记3 -- WS2812 16*16点阵的点线面绘画 [复制链接]

 

大家晚上好,上次强占的发帖位这次给大家补上了

上次初步介绍了WS2812的16*16点阵  传送门在这里   ----->   https://bbs.eeworld.com.cn/thread-1141816-1-1.html

有兴趣的可以看一下啊

一个图形是由线条组成的,而线条是由点构成的,那么画点则是重中之重

首先我想建立一个坐标系,就是所有的点都在坐标系上,坐标为横向1-16,纵向1-16

在画点的时候我做种考虑了一下16*16点阵的重要要素

第一要有图形的感念  图形是你要在点阵上面表示的东西  它是一个列表 ,列表里面是数字WS2812的编号 即要点亮和改变的灯 

第二要有颜色的感念 每个灯都可以有不同的颜色,颜色是一个列表,里面是一个一个的元组红绿蓝的组合

第三要有页的感念  每一页都是有图形 颜色和非图形以外灯的结合体,我想页是由灯与颜色的对应关系组成

第四要有动态图的感念 ,就是很多个页组成的集合体(我现在还没有写到这里,所以这些是我的猜想)

好吧废话不多说,上干货   画点走起

  • from machine import Pin
  • from neopixel import NeoPixel
  • import time
  • p5 = Pin(5,Pin.OUT)
  • np = NeoPixel(p5,256)
  • r = g = b = 0
  • ### 一个变换的点阵图像必须要有以下几个要素
  • ## 图形 : 每个点阵必须有整个图形存储的空间
  • ## 当前页 : 当前刷新的页的参数 包括 当前亮的灯 背景颜色 灯颜色
  • ## 颜色 : 所有包含的颜色列表
  • ## 过渡 : 是一个过渡列表
  • yanse = []
  • tuxing = []
  • ye = []
  • def dian(x,y) : #画点函数 任何图形必定是由点组成的
  • if x == 1 :
  • return 16 - y
  • if x == 2 :
  • return 15 + y
  • if x == 3 :
  • return 48 - y
  • if x == 4 :
  • return 47 + y
  • if x == 5 :
  • return 80 - y
  • if x == 6 :
  • return 79 + y
  • if x == 7 :
  • return 112 - y
  • if x == 8 :
  • return 111 + y
  • if x == 9 :
  • return 144 - y
  • if x == 10 :
  • return 143 + y
  • if x == 11 :
  • return 176 - y
  • if x == 12 :
  • return 175 + y
  • if x == 13 :
  • return 208 - y
  • if x == 14 :
  • return 207 + y
  • if x == 15 :
  • return 240 - y
  • if x == 16 :
  • return 239 + y
  • def hua (x,y) : #画一个点
  • zi = dian(x,y)
  • np[zi] = (11,22,33)
  • np.write()

通过输入 X和Y的值来计算出灯的编号   比如说点亮10 * 10 的这个灯

 

会画点了我们就进一步画线

线是由很多个点组成的,因为分辨率实在太低 所以我这里就做了简单的直线和45度斜线

源码如下

  • from machine import Pin
  • from neopixel import NeoPixel
  • import time
  • p5 = Pin(5,Pin.OUT)
  • np = NeoPixel(p5,256)
  • r = g = b = 0
  • ### 一个变换的点阵图像必须要有以下几个要素
  • ## 图形 : 每个点阵必须有整个图形存储的空间
  • ## 当前页 : 当前刷新的页的参数 包括 当前亮的灯 背景颜色 灯颜色
  • ## 颜色 : 所有包含的颜色列表
  • ## 过渡 : 是一个过渡列表
  • # yanse = []
  • # tuxing = []
  • # ye = []
  • def dian(x,y) : #画点函数 任何图形必定是由点组成的
  • if x == 1 :
  • return 16 - y
  • if x == 2 :
  • return 15 + y
  • if x == 3 :
  • return 48 - y
  • if x == 4 :
  • return 47 + y
  • if x == 5 :
  • return 80 - y
  • if x == 6 :
  • return 79 + y
  • if x == 7 :
  • return 112 - y
  • if x == 8 :
  • return 111 + y
  • if x == 9 :
  • return 144 - y
  • if x == 10 :
  • return 143 + y
  • if x == 11 :
  • return 176 - y
  • if x == 12 :
  • return 175 + y
  • if x == 13 :
  • return 208 - y
  • if x == 14 :
  • return 207 + y
  • if x == 15 :
  • return 240 - y
  • if x == 16 :
  • return 239 + y
  • def huaxian(x1,y1,x2,y2) :
  • xian = []
  • x3 = y3 = 0
  • if x1 == x2 :
  • if y1 == y2 :
  • xian.append(dian(x1,y1))
  • if y1 > y2 :
  • for i in range (y1-y2+1) :
  • xian.append(dian(x1,y2+i))
  • if y1 < y2 :
  • for i in range (y2-y1+1) :
  • xian.append(dian(x1,y1+i))
  • if x1 > x2 :
  • x3 = x1
  • x1 = x2
  • x2 = x3
  • y3 = y1
  • y1 = y2
  • y2 = y3
  • if x1 != x2 :
  • if y1 == y2 :
  • for i in range (x2-x1+1) :
  • xian.append(dian(x1+i,y1))
  • if y1 > y2 :
  • if y1 - y2 == x2 - x1 :
  • for i in range(x2-x1+1):
  • xian.append(dian(x1+i,y1-i))
  • if y1 < y2 :
  • if y2 - y1 == x2 - x1 :
  • for i in range(x2-x1+1):
  • xian.append(dian(x1+i,y1+i))
  • for i in range(len(xian)) :
  • np[xian[i]] = (11,22,33)
  • np.write()

在这里我画了两条线,分别是(1,1)到 (10,10)的和(1,16)到(16,16)的

 

画完线之后就要画图形了   我在这里先拿了一个硬骨头来啃,就是画三角形。

为啥说三角形是硬骨头呢,看我的思路慢慢道来吧

在低像素中只能画这样8种三角形

那么每种三角形都有一个不同的算法

在画三角形的时候我在函数里面添加了填充或不填充两种选择

具体看函数吧  有问题再帖子下面留言

  • from machine import Pin
  • from neopixel import NeoPixel
  • import time
  • p5 = Pin(5,Pin.OUT)
  • np = NeoPixel(p5,256)
  • r = g = b = 0
  • tuxing = []
  • ### 一个变换的点阵图像必须要有以下几个要素
  • ## 图形 : 每个点阵必须有整个图形存储的空间
  • ## 当前页 : 当前刷新的页的参数 包括 当前亮的灯 背景颜色 灯颜色
  • ## 颜色 : 所有包含的颜色列表
  • ## 过渡 : 是一个过渡列表
  • # yanse = []
  • # tuxing = []
  • # ye = []
  • def dian(x,y) : #画点函数 任何图形必定是由点组成的
  • if x == 1 :
  • return 16 - y
  • if x == 2 :
  • return 15 + y
  • if x == 3 :
  • return 48 - y
  • if x == 4 :
  • return 47 + y
  • if x == 5 :
  • return 80 - y
  • if x == 6 :
  • return 79 + y
  • if x == 7 :
  • return 112 - y
  • if x == 8 :
  • return 111 + y
  • if x == 9 :
  • return 144 - y
  • if x == 10 :
  • return 143 + y
  • if x == 11 :
  • return 176 - y
  • if x == 12 :
  • return 175 + y
  • if x == 13 :
  • return 208 - y
  • if x == 14 :
  • return 207 + y
  • if x == 15 :
  • return 240 - y
  • if x == 16 :
  • return 239 + y
  • def huaxian(x1,y1,x2,y2) :
  • xian = []
  • x3 = y3 = 0
  • if x1 == x2 :
  • if y1 == y2 :
  • xian.append(dian(x1,y1))
  • if y1 > y2 :
  • for i in range(y1-y2+1) :
  • xian.append(dian(x1,y2+i))
  • if y1 < y2 :
  • for i in range(y2-y1+1) :
  • xian.append(dian(x1,y1+i))
  • if x1 > x2 :
  • x3 = x1
  • x1 = x2
  • x2 = x3
  • y3 = y1
  • y1 = y2
  • y2 = y3
  • if x1 != x2 :
  • if y1 == y2 :
  • for i in range(x2-x1+1) :
  • xian.append(dian(x1+i,y1))
  • if y1 > y2 :
  • if y1 - y2 == x2 - x1 :
  • for i in range(x2-x1+1):
  • xian.append(dian(x1+i,y1-i))
  • if y1 < y2 :
  • if y2 - y1 == x2 - x1 :
  • for i in range(x2-x1+1):
  • xian.append(dian(x1+i,y1+i))
  • return xian
  • #三角图形,只能画等腰直角三角形,第一个坐标值为三角形直角,最后的t=0为不填充,t=1为填充,默认为0
  • def sanjiao (x1,y1,x2,y2,x3,y3,t=0):
  • global tuxing
  • x4 = y4 = 0
  • bian = []
  • if t == 0 :
  • bian = huaxian(x1,y1,x2,y2)
  • for i in range(len(bian)) :
  • tuxing.append(bian[i])
  • bian = huaxian(x1,y1,x3,y3)
  • for i in range(len(bian)) :
  • tuxing.append(bian[i])
  • bian = huaxian(x2,y2,x3,y3)
  • for i in range(len(bian)) :
  • tuxing.append(bian[i])
  • tuxing = list(set(tuxing))
  • if t == 1 :
  • if x2 == x3 :
  • if y3 == y2 :
  • tuxing = huaxian(x3,y3,x2,y2)
  • if y2 < y3 :
  • y4 = y2
  • x4 = x2
  • y2 = y3
  • x2 = x3
  • y3 = y4
  • x3 = x4
  • if y3 != y2 :
  • if x1 > x2 : #测试无误
  • for i in range(x1-x2+1):
  • bian = huaxian(x2+i,y2-i,x3+i,y3+i)
  • for j in range(len(bian)) :
  • tuxing.append(bian[j])
  • tuxing = list(set(tuxing))
  • if x2 > x1 : #测试无误
  • for i in range(x2-x1+1):
  • bian = huaxian(x2-i,y2-i,x3-i,y3+i)
  • for j in range(len(bian)) :
  • tuxing.append(bian[j])
  • tuxing = list(set(tuxing))
  • if x2 > x3 :
  • x4 = x2
  • y4 = y2
  • x2 = x3
  • y2 = y3
  • x3 = x4
  • y3 = y4
  • if x2 != x3 :
  • if y3 == y2 :
  • if y1 > y2 : #测试无误
  • for i in range(y1-y2+1):
  • bian = huaxian(x2+i,y2+i,x3-i,y3+i)
  • for j in range(len(bian)) :
  • tuxing.append(bian[j])
  • tuxing = list(set(tuxing))
  • if y2 > y1 : #测试无误
  • for i in range(y2-y1+1):
  • bian = huaxian(x2+i,y2-i,x3-i,y3-i)
  • for j in range(len(bian)) :
  • tuxing.append(bian[j])
  • tuxing = list(set(tuxing))
  • if x1 == x2 :
  • if y2 > y1 : #测试无误
  • for i in range(y2-y1+1):
  • bian = huaxian(x1,y1+i,x3-i,y3+i)
  • for j in range(len(bian)) :
  • tuxing.append(bian[j])
  • tuxing = list(set(tuxing))
  • if y1 > y2 : #测试无误
  • for i in range(y1-y2+1):
  • print(tuxing)
  • bian = huaxian(x1,y1-i,x3-i,y3-i)
  • for j in range(len(bian)) :
  • tuxing.append(bian[j])
  • tuxing = list(set(tuxing))
  • if x1 == x3 :
  • if y3 > y1 : #测试无误
  • for i in range(y3-y1+1):
  • bian = huaxian(x2+i,y2+i,x1,y1+i)
  • print(x2-i,y2+i,x1,y1+i)
  • for j in range(len(bian)) :
  • tuxing.append(bian[j])
  • tuxing = list(set(tuxing))
  • if y1 > y3 : #测试无误
  • for i in range(y1-y3+1):
  • bian = huaxian(x2+i,y2-i,x1,y1-i)
  • for j in range(len(bian)) :
  • tuxing.append(bian[j])
  • tuxing = list(set(tuxing))
  • tuxing.sort()
  • for i in range(len(tuxing)) :
  • np[tuxing[i]] = (1,2,3)
  • np.write()

在这里我画了3个

三角形分别是填充和不填充的

接下来就是画方形了

  • from machine import Pin
  • from neopixel import NeoPixel
  • import time
  • p5 = Pin(5,Pin.OUT)
  • np = NeoPixel(p5,256)
  • r = g = b = 0
  • tuxing = []
  • ### 一个变换的点阵图像必须要有以下几个要素
  • ## 图形 : 每个点阵必须有整个图形存储的空间
  • ## 当前页 : 当前刷新的页的参数 包括 当前亮的灯 背景颜色 灯颜色
  • ## 颜色 : 所有包含的颜色列表
  • ## 过渡 : 是一个过渡列表
  • # yanse = []
  • # tuxing = []
  • # ye = []
  • def dian(x,y) : #画点函数 任何图形必定是由点组成的
  • if x == 1 :
  • return 16 - y
  • if x == 2 :
  • return 15 + y
  • if x == 3 :
  • return 48 - y
  • if x == 4 :
  • return 47 + y
  • if x == 5 :
  • return 80 - y
  • if x == 6 :
  • return 79 + y
  • if x == 7 :
  • return 112 - y
  • if x == 8 :
  • return 111 + y
  • if x == 9 :
  • return 144 - y
  • if x == 10 :
  • return 143 + y
  • if x == 11 :
  • return 176 - y
  • if x == 12 :
  • return 175 + y
  • if x == 13 :
  • return 208 - y
  • if x == 14 :
  • return 207 + y
  • if x == 15 :
  • return 240 - y
  • if x == 16 :
  • return 239 + y
  • def huaxian(x1,y1,x2,y2) :
  • xian = []
  • x3 = y3 = 0
  • if x1 == x2 :
  • if y1 == y2 :
  • xian.append(dian(x1,y1))
  • if y1 > y2 :
  • for i in range(y1-y2+1) :
  • xian.append(dian(x1,y2+i))
  • if y1 < y2 :
  • for i in range(y2-y1+1) :
  • xian.append(dian(x1,y1+i))
  • if x1 > x2 :
  • x3 = x1
  • x1 = x2
  • x2 = x3
  • y3 = y1
  • y1 = y2
  • y2 = y3
  • if x1 != x2 :
  • if y1 == y2 :
  • for i in range(x2-x1+1) :
  • xian.append(dian(x1+i,y1))
  • if y1 > y2 :
  • if y1 - y2 == x2 - x1 :
  • for i in range(x2-x1+1):
  • xian.append(dian(x1+i,y1-i))
  • if y1 < y2 :
  • if y2 - y1 == x2 - x1 :
  • for i in range(x2-x1+1):
  • xian.append(dian(x1+i,y1+i))
  • return xian
  • #方形的两个对角点确定一个方形 t = 0 时画框 t = 1 时填充
  • def fangxing (x1,y1,x2,y2,t=0) :
  • global tuxing
  • bian = []
  • x3 = y3 = 0
  • if x1 == x2 :
  • tuxing = huaxian(x1,y,x2,y2)
  • if x1 > x2 :
  • x3 = x1
  • y3 = y1
  • x1 = x2
  • y1 = y2
  • x2 = x3
  • y2 = y3
  • if x1 != x2 :
  • if y1 == y2 :
  • tuxing = huaxian(x1,y,x2,y2)
  • if y1 > y2 :
  • for i in range(y1-y2+1):
  • bian = huaxian(x1,y1-i,x2,y1-i)
  • for j in range(len(bian)) :
  • tuxing.append(bian[j])
  • if y2 > y1 :
  • for i in range(y2-y1+1):
  • bian = huaxian(x1,y1+i,x2,y1+i)
  • for j in range(len(bian)) :
  • tuxing.append(bian[j])
  • tuxing = list(set(tuxing))
  • tuxing.sort()
  • for i in range(len(tuxing)) :
  • np[tuxing[i]] = (1,2,3)
  • np.write()

画方形

这里画了一个(5,7)(7,13)

今天太累了  有什么提问就在下面留言吧   

爱你们呦   回家睡觉了 

最新回复

可以用fb模块作前处理,自己做一个show函数把rgb565的点阵数据转换成2812的格式发送显示即可   详情 回复 发表于 2023-2-11 21:27

赞赏

1

查看全部赞赏

点赞(1) 关注(1)
 
 

回复
举报

1万

帖子

25

TA的资源

版主

沙发
 

帖子太长了,可以分几个部分或者分楼层发

 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

板凳
 

楼主,期待您再次发帖!您这两帖对于学习WS2812来说受益匪浅。有了画点,画矩形,三角形等函数以后,您可以推出字符、汉字系列,这样就完美了!dcexpert这位大佬做的图片显示结合您的图形显示,再加上字符以后简直无敌!

 
 
 

回复

8

帖子

0

TA的资源

一粒金砂(中级)

4
 

Micropython要是有字库就好了,直接输出

 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(中级)

5
 

可以用fb模块作前处理,自己做一个show函数把rgb565的点阵数据转换成2812的格式发送显示即可

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
【干货上新】电源解决方案和技术第二趴 | DigiKey 应用探索站
当月好物、电源技术资源、特色活动、DigiKey在线实用工具,干货多多~

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网 4

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表