“玩板”+在STM32F7DISC上重玩micropython(5)
<div class='showpostmsg'><p>有了LCD和TS驱动,就可以做一点复杂的演示了。下面是一个分形(mandelbrot)演示程序,首先绘制初始的图案,然后读取触摸屏输入,根据输入的手势进行缩放、移动等操作。</p><p><br />
因为触摸屏驱动没有直接提供手势功能,因此做了一个简单的识别,通过检测单点和双点触摸以及触摸时间和移动距离,判断手势。先实现了单点触摸检测,并完成了图形的移动功能,下一步将缩放检测功能(争取尽快完成)。<br />
</p>
<p>为了加快显示速度和减少计算量,使用了guess方法计算分形。即先计算一个矩形块(这里设置为4x4大小)的4个顶点,如果它们是相同的,那么认为这个矩形区内部也是相同的,可以直接填充矩形。此外在移动时,也只计算变化的区域。</p>
<p> </p>
<pre>
<code class="language-python">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 =
c = * (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 =
@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 = , 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, sr, sr, sr)
t0 = ticks_ms()
MX, MY = sr, sr
if MX == 0 or MY == 0:
return 0
x0, y0 = wr - wr/2, wr - wr/2
dx, dy = wr/MX, wr/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 = calc(z, ITER)
lcd.draw_pixel(sr+ix, sr+iy, pal%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 == c and c == c and c == c:
lcd.set_text_color(pal%MAX_PAL])
lcd.fill_rect(sr+ix, sr+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+ix+i//4, sr+iy+i%4, pal)
lcd.set_layer_visible(1, 0)
return ticks_diff(ticks_ms(), t0)
def dealwith_drag(p1, p2):
global WIN
dx, dy = p2 - p1, p2 - p1
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*dx/MAX_X
wy = WIN*dy/MAX_Y
lcd.scroll(dx, dy)
if dx >= 0:
if dy >= 0:
draw_fast_mandelbrot(wr = (WIN-WIN/2-wx/2, WIN-wy, wx, WIN), sr = (0, 0, dx, MAX_Y))
draw_fast_mandelbrot(wr = (WIN-wx/2, WIN-WIN/2-wy/2, WIN-wx, wy), sr = (dx, 0, MAX_X-dx, dy))
else:
draw_fast_mandelbrot(wr = (WIN-WIN/2-wx/2, WIN-wy, wx, WIN), sr = (0, 0, dx, MAX_Y))
draw_fast_mandelbrot(wr = (WIN-wx/2, WIN+WIN/2-wy/2, WIN-wx, -wy), sr = (dx, MAX_Y + dy, MAX_X-dx, -dy))
else:
if dy >= 0:
draw_fast_mandelbrot(wr = (WIN+WIN/2-wx/2, WIN-wy, -wx, WIN), sr = (MAX_X+dx, 0, -dx, MAX_Y))
draw_fast_mandelbrot(wr = (WIN-wx/2, WIN-WIN/2-wy/2, WIN-wx, wy), sr = (0, 0, MAX_X+dx, dy))
else:
draw_fast_mandelbrot(wr = (WIN+WIN/2-wx/2, WIN-wy, -wx, WIN), sr = (MAX_X+dx, 0, -dx, MAX_Y))
draw_fast_mandelbrot(wr = (WIN-wx/2, WIN+WIN/2-wy/2, WIN-wx, -wy), sr = (0, MAX_Y + dy, MAX_X+dx, -dy))
WIN -= wx
WIN -= wy
def main():
ts_g_drag = False
ts_g_zoom = False
ts_n = 0
ts_t = 0
ts_gd0 =
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()
</code></pre>
<p> </p>
<p><strong>运行效果</strong></p>
<p> </p>
<p></p>
<p> </p>
<p><br />
<b><font color="#5E7384">此内容由EEWORLD论坛网友<font size="3">dcexpert</font>原创,如需转载或用于商业用途需征得作者同意并注明出处</font></b><br />
</p>
</div><script> var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;" style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
if(parseInt(discuz_uid)==0){
(function($){
var postHeight = getTextHeight(400);
$(".showpostmsg").html($(".showpostmsg").html());
$(".showpostmsg").after(loginstr);
$(".showpostmsg").css({height:postHeight,overflow:"hidden"});
})(jQuery);
} </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>
页:
[1]