有了LCD和TS驱动,就可以做一点复杂的演示了。下面是一个分形(mandelbrot)演示程序,首先绘制初始的图案,然后读取触摸屏输入,根据输入的手势进行缩放、移动等操作。
因为触摸屏驱动没有直接提供手势功能,因此做了一个简单的识别,通过检测单点和双点触摸以及触摸时间和移动距离,判断手势。先实现了单点触摸检测,并完成了图形的移动功能,下一步将缩放检测功能(争取尽快完成)。
为了加快显示速度和减少计算量,使用了guess方法计算分形。即先计算一个矩形块(这里设置为4x4大小)的4个顶点,如果它们是相同的,那么认为这个矩形区内部也是相同的,可以直接填充矩形。此外在移动时,也只计算变化的区域。
import lcdF7D as lcd
import tchF7D as ts
from time import sleep_ms, ticks_ms, ticks_diff
from random import randrange as rand
import gc
MAX_X = 480
MAX_Y = 272
MAX_ITER = 80
MAX_PAL = 256
pal = [i*16 for i in range(MAX_PAL)]
c = [0] * (MAX_X*MAX_Y//16)
ZoomFactor = 4
magnification = 1
WIN = [-0.5, 0, 6, 4]
def init():
lcd.init()
lcd.set_text_color(0x00FF00)
ts.init(MAX_X, MAX_Y)
lcd.set_layer_visible(0, 1)
lcd.set_layer_visible(1, 0)
lcd.select_layer(1)
lcd.clear(0x40, 0)
lcd.set_text_color(0x60, 0x888888)
lcd.fill_rect(240 - 90, 136 - 20, 180, 40)
lcd.set_text_color(0xA0, 0x00AA00)
lcd.set_back_color(0x30, 0x888888)
lcd.set_font(20)
s = 'calculating'
lcd.display_string_at(240 - len(s)*14//2, 136-20//2, 'calculating', 0)
lcd.select_layer(0)
lcd.clear(0)
init()
def randPAL():
global pal
pal = [rand(0xFFFFFF) for i in range(MAX_PAL)]
@micropython.native
def calc(c, ITER=MAX_ITER):
z = c
for i in range(ITER):
z = z * z + c
if abs(z) >= 4:
return i
return 0
# wr: cx(center x), cy(center y), width, height
# sr: sx(left), sy(top), width, height
def draw_fast_mandelbrot(wr = [-0.5, 0, 6, 4], sr = [0, 0, MAX_X, MAX_Y], ITER = MAX_ITER):
print(wr, sr)
lcd.set_layer_visible(1, 1)
lcd.select_layer(0)
lcd.set_text_color(0)
lcd.fill_rect(sr[0], sr[1], sr[2], sr[3])
t0 = ticks_ms()
MX, MY = sr[2], sr[3]
if MX == 0 or MY == 0:
return 0
x0, y0 = wr[0] - wr[2]/2, wr[1] - wr[3]/2
dx, dy = wr[2]/MX, wr[3]/MY
n = 0
LXN, LYN = MX//4, MY//4
for ix in range(0, MX, 4):
for iy in range(0, MY, 4):
z = x0 + dx * ix + (y0 + dy * iy) * 1j
c[n] = calc(z, ITER)
lcd.draw_pixel(sr[0]+ix, sr[1]+iy, pal[c[n]%MAX_PAL])
n += 1
for ix in range(0, MX, 4):
for iy in range(0, MY, 4):
n = ix * LYN //4 + iy//4
if ix < MX-4 and iy < MY-4 and c[n] == c[n+1] and c[n] == c[n+LYN] and c[n] == c[n+LYN+1]:
lcd.set_text_color(pal[c[n]%MAX_PAL])
lcd.fill_rect(sr[0]+ix, sr[1]+iy, 5, 5)
else:
for i in range(1, 16):
z = x0 + dx * (ix + i//4)+ (y0 + dy * (iy + i%4)) * 1j
d = calc(z, ITER)
lcd.draw_pixel(sr[0]+ix+i//4, sr[1]+iy+i%4, pal[d%MAX_PAL])
lcd.set_layer_visible(1, 0)
return ticks_diff(ticks_ms(), t0)
def dealwith_drag(p1, p2):
global WIN
dx, dy = p2[0] - p1[0], p2[1] - p1[1]
if dx*dx + dy*dy < 128:
return
dx = max(min(dx >> 3 << 3, 128), -128)
dy = max(min(dy >> 3 << 3, 80), -80)
wx = WIN[2]*dx/MAX_X
wy = WIN[3]*dy/MAX_Y
lcd.scroll(dx, dy)
if dx >= 0:
if dy >= 0:
draw_fast_mandelbrot(wr = (WIN[0]-WIN[2]/2-wx/2, WIN[1]-wy, wx, WIN[3]), sr = (0, 0, dx, MAX_Y))
draw_fast_mandelbrot(wr = (WIN[0]-wx/2, WIN[1]-WIN[3]/2-wy/2, WIN[2]-wx, wy), sr = (dx, 0, MAX_X-dx, dy))
else:
draw_fast_mandelbrot(wr = (WIN[0]-WIN[2]/2-wx/2, WIN[1]-wy, wx, WIN[3]), sr = (0, 0, dx, MAX_Y))
draw_fast_mandelbrot(wr = (WIN[0]-wx/2, WIN[1]+WIN[3]/2-wy/2, WIN[2]-wx, -wy), sr = (dx, MAX_Y + dy, MAX_X-dx, -dy))
else:
if dy >= 0:
draw_fast_mandelbrot(wr = (WIN[0]+WIN[2]/2-wx/2, WIN[1]-wy, -wx, WIN[3]), sr = (MAX_X+dx, 0, -dx, MAX_Y))
draw_fast_mandelbrot(wr = (WIN[0]-wx/2, WIN[1]-WIN[3]/2-wy/2, WIN[2]-wx, wy), sr = (0, 0, MAX_X+dx, dy))
else:
draw_fast_mandelbrot(wr = (WIN[0]+WIN[2]/2-wx/2, WIN[1]-wy, -wx, WIN[3]), sr = (MAX_X+dx, 0, -dx, MAX_Y))
draw_fast_mandelbrot(wr = (WIN[0]-wx/2, WIN[1]+WIN[3]/2-wy/2, WIN[2]-wx, -wy), sr = (0, MAX_Y + dy, MAX_X+dx, -dy))
WIN[0] -= wx
WIN[1] -= wy
def main():
ts_g_drag = False
ts_g_zoom = False
ts_n = 0
ts_t = 0
ts_gd0 = [0, 0, 0, 0, 0]
draw_fast_mandelbrot(wr = WIN)
while 1:
ts.get_state()
ts_n = ts.touches()
if ts_n > 0:
if ts_n == 1: # drag
if not ts_g_drag:
ts_g_drag = True
ts_t = 0
ts_gd0 = ts.point_info(1)
print('Drag detect begin')
else:
if ts_t <= 30:
ts_t += 1
if ts_t == 30:
print('Drag detect ok.')
ts_gd1 = ts.point_info(1)
elif ts_n == 2: # zoom
pass
else:
pass
else:
if ts_g_drag:
#ts_g_drag = False
if ts_t > 30:
print('Drag end.')
print(ts_gd0, ts_gd1)
dealwith_drag(ts_gd0, ts_gd1)
if ts_n != 1:
ts_g_drag = False
if ts_n != 2:
ts_g_zoom = False
sleep_ms(20)
main()
运行效果
此内容由EEWORLD论坛网友dcexpert原创,如需转载或用于商业用途需征得作者同意并注明出处