dcexpert 发表于 2020-2-19 16:38

“玩板”+在STM32F7DISC上重玩micropython(5)

<div class='showpostmsg'><p>有了LCD和TS驱动,就可以做一点复杂的演示了。下面是一个分形(mandelbrot)演示程序,首先绘制初始的图案,然后读取触摸屏输入,根据输入的手势进行缩放、移动等操作。</p>

<p><br />
因为触摸屏驱动没有直接提供手势功能,因此做了一个简单的识别,通过检测单点和双点触摸以及触摸时间和移动距离,判断手势。先实现了单点触摸检测,并完成了图形的移动功能,下一步将缩放检测功能(争取尽快完成)。<br />
&nbsp;</p>

<p>为了加快显示速度和减少计算量,使用了guess方法计算分形。即先计算一个矩形块(这里设置为4x4大小)的4个顶点,如果它们是相同的,那么认为这个矩形区内部也是相同的,可以直接填充矩形。此外在移动时,也只计算变化的区域。</p>

<p>&nbsp;</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) &gt;= 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 &lt; MX-4 and iy &lt; 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 &lt; 128:
      return

    dx = max(min(dx &gt;&gt; 3 &lt;&lt; 3, 128), -128)
    dy = max(min(dy &gt;&gt; 3 &lt;&lt; 3, 80), -80)
    wx = WIN*dx/MAX_X
    wy = WIN*dy/MAX_Y

    lcd.scroll(dx, dy)

    if dx &gt;= 0:
      if dy &gt;= 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 &gt;= 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 &gt; 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 &lt;= 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 &gt; 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>&nbsp;</p>

<p><strong>运行效果</strong></p>

<p>&nbsp;</p>

<p></p>

<p>&nbsp;</p>

<p><br />
<b><font color="#5E7384">此内容由EEWORLD论坛网友<font size="3">dcexpert</font>原创,如需转载或用于商业用途需征得作者同意并注明出处</font></b><br />
&nbsp;</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]
查看完整版本: “玩板”+在STM32F7DISC上重玩micropython(5)