打印
[STM32F7]

【STM32F746DISC】显示分形2

[复制链接]
791|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dentsgot|  楼主 | 2016-5-7 22:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这是昨天程序的升级版,增加了缩放、移动、参数显示等功能。一个手指可以拖到图形,两个手指靠近或分开可以缩放。

此外使用了Guess算法减少计算次数,加快显示速度。

目前已知问题,手势识别还不够灵敏,等待进一步改进。


#include "mbed.h"
#include "LCD_DISCO_F746NG.h"
#include "TS_DISCO_F746NG.h"
#include <math.h>

#define ITERATION  150
#define BAILOUT 4

LCD_DISCO_F746NG lcd;
TS_DISCO_F746NG ts;
TS_StateTypeDef TS_State;
uint8_t ts_nb = 0;

uint16_t tsx0[2], tsy0[2];
uint16_t tsx[2], tsy[2];
uint8_t tscnt = 0;
double zoom = 1;

Timer tmr;

uint8_t msg[20];
uint16_t screen_width, screen_height;

double mx1, my1, mx2, my2;

uint16_t calcMandelBrot(double x, double y)
{
    uint16_t i;
    double xx, yy, tx, ty;
   
    xx = yy = 0;
    i = 0;
    while((i < ITERATION) && ((xx*xx + yy*yy) < BAILOUT))
    {
        tx = xx*xx - yy*yy + x;
        ty = 2*xx*yy + y;
        xx = tx;
        yy = ty;
        i++;
    }
    return i;
}

uint8_t c[150][100];
void rectMandelBrot(double x1, double y1, double x2, double y2)
{
    double dx, dy;
    uint16_t i, j, n;
    uint32_t color;
  
    lcd.SetTextColor(LCD_COLOR_BLACK);
    lcd.FillRect(0, 0, screen_width, screen_height);
    lcd.SetTextColor(LCD_COLOR_WHITE);
    sprintf((char *)msg, "%10f", x1);
    lcd.DisplayStringAt(screen_width+5, 224, msg, LEFT_MODE);
    sprintf((char *)msg, "%10f", y1);
    lcd.DisplayStringAt(screen_width+5, 236, msg, LEFT_MODE);
    sprintf((char *)msg, "%10f", x2);
    lcd.DisplayStringAt(screen_width+5, 248, msg, LEFT_MODE);
    sprintf((char *)msg, "%10f", y2);
    lcd.DisplayStringAt(screen_width+5, 260, msg, LEFT_MODE);
    sprintf((char *)msg, "  %10f", zoom);
    lcd.DisplayStringAt(screen_width+5, 212, msg, LEFT_MODE);
   
    tmr.reset();
    tmr.start();
   
    dx = (x2 - x1)/screen_width;
    dy = (y2 - y1)/screen_height;
/*
    for(i = 0; i < screen_width; i++)
    {
        for(j = 0; j < screen_height; j++)
        {
            color = calcMandelBrot(x1 + dx*i, y1 + dy*j);
            lcd.DrawPixel(i, j, 0xFF000000 | (color<<14) | (color <<4));
        }
    }*/
    for(i = 0; i < screen_width/4; i++)
    {
        ts.GetState(&TS_State);
        if (TS_State.touchDetected)
            return;
        for(j = 0; j < screen_height/4; j++)
        {
            c[i][j] = calcMandelBrot(x1 + 4*dx*i, y1 + 4*dy*j);
            lcd.DrawPixel(4*i, 4*j, 0xFF000000 | (c[i][j]<<4));
        }
    }
   
    for(i = 0; i < screen_width/4; i++)
    {
        ts.GetState(&TS_State);
        if (TS_State.touchDetected)
            return;
        for(j = 0; j < screen_height/4; j++)
        {
            if((c[i][j] == c[i+1][j]) && (c[i][j] == c[i+1][j+1]) && (c[i][j] == c[i][j+1]))
            {
                lcd.SetTextColor(0xFF000000 | (c[i][j]<<4));
                lcd.FillRect(i*4, j*4, 4, 4);               
            }
            else
            {
                for(n = 1; n < 16; n++)
                {
                    color = calcMandelBrot(x1 + dx*(4*i+(n/4)), y1 + dy*(4*j+(n%4)));
                    lcd.DrawPixel(4*i+(n/4), 4*j+(n%4), 0xFF000000 | (color<<4));
                }
            }
        }
    }

    tmr.stop();
   
    sprintf((char *)msg, "  %6d ms", tmr.read_ms());
    lcd.SetTextColor(LCD_COLOR_WHITE);
    lcd.SetBackColor(LCD_COLOR_BLACK);
    lcd.DisplayStringAt(screen_width+5, 20, msg, LEFT_MODE);
}

int main()
{
    uint8_t status;
    uint8_t prev_nb_touches = 0;
    double cx, cy, lx, ly;

    status = ts.Init(lcd.GetXSize(), lcd.GetYSize());
    if (status != TS_OK) {
        lcd.Clear(LCD_COLOR_RED);
        lcd.SetBackColor(LCD_COLOR_RED);
        lcd.SetTextColor(LCD_COLOR_WHITE);
        lcd.DisplayStringAt(0, LINE(5), (uint8_t *)"TOUCHSCREEN INIT FAIL", CENTER_MODE);
        
        while(1);
    }   
   
    lcd.Clear(LCD_COLOR_BLACK);
    lcd.SetFont(&Font12);
    lcd.SetTextColor(LCD_COLOR_WHITE);
    lcd.SetBackColor(LCD_COLOR_BLACK);

    screen_width = lcd.GetXSize() - 120;
    screen_height = lcd.GetYSize();

    lcd.DisplayStringAt(screen_width+5, 0, (uint8_t *)"Elapsed:", LEFT_MODE);
    lcd.DisplayStringAt(screen_width+5, 200, (uint8_t *)"Zoom:", LEFT_MODE);

   
    mx1 = -2.5;
    my1 = -2.5;
    mx2 = 2.5;
    my2 = 2.5;
    rectMandelBrot(mx1, my1, mx2, my2);
   
    status = 0;
    while(1)
    {
        wait(0.01);
        ts.GetState(&TS_State);
        if (TS_State.touchDetected)
        {
            if(TS_State.touchDetected != prev_nb_touches)
            {
                status = 0;
                tscnt = 0;
                prev_nb_touches = TS_State.touchDetected;               
            }
            
            if(tscnt < 10)
            {
                tscnt++;
                if(tscnt == 9)
                {
                    ts_nb = TS_State.touchDetected;
                    lcd.SetTextColor(LCD_COLOR_BLACK);
                    lcd.FillRect(screen_width+5, 60, 120, 48);
                }
                continue;
            }
            
            switch(ts_nb)
            {
                case 1:
                    if(status == 0)
                    {
                        status = 1;
                        tsx0[0] = TS_State.touchX[0];
                        tsy0[0] = TS_State.touchY[0];
                    }
                    tsx[0] = TS_State.touchX[0];
                    tsy[0] = TS_State.touchY[0];
                    lcd.SetTextColor(LCD_COLOR_LIGHTBLUE);
                    sprintf((char *)msg, "%3d", TS_State.touchX[0]);
                    lcd.DisplayStringAt(screen_width+5, 60, msg, LEFT_MODE);
                    sprintf((char *)msg, "%3d", TS_State.touchY[0]);
                    lcd.DisplayStringAt(screen_width+5, 72, msg, LEFT_MODE);
                    break;
                case 2:
                    if(status == 0)
                    {
                        status = 1;
                        tsx0[0] = TS_State.touchX[0];
                        tsy0[0] = TS_State.touchY[0];
                        tsx0[1] = TS_State.touchX[1];
                        tsy0[1] = TS_State.touchY[1];
                    }
                    tsx[0] = TS_State.touchX[0];
                    tsy[0] = TS_State.touchY[0];
                    tsx[1] = TS_State.touchX[1];
                    tsy[1] = TS_State.touchY[1];
                    lcd.SetTextColor(LCD_COLOR_LIGHTBLUE);
                    sprintf((char *)msg, "%3d", TS_State.touchX[0]);
                    lcd.DisplayStringAt(screen_width+5, 60, msg, LEFT_MODE);
                    sprintf((char *)msg, "%3d", TS_State.touchY[0]);
                    lcd.DisplayStringAt(screen_width+5, 72, msg, LEFT_MODE);
                    sprintf((char *)msg, "%3d", TS_State.touchX[1]);
                    lcd.DisplayStringAt(screen_width+5, 84, msg, LEFT_MODE);
                    sprintf((char *)msg, "%3d", TS_State.touchY[1]);
                    lcd.DisplayStringAt(screen_width+5, 96, msg, LEFT_MODE);
                    break;
            }
        }
        else
        {
            if(status)
            {
                lcd.SetTextColor(LCD_COLOR_YELLOW);
                status = 0;
                tscnt = 0;
                switch(ts_nb)
                {
                    case 1:
                        if((abs(tsx[0] - tsx0[0]) > 20) || (abs(tsy[0] - tsy0[0]) > 20))
                        {
                            lcd.DisplayStringAt(screen_width+41, 200, (uint8_t *)" - ", LEFT_MODE);
                            cx = (tsx[0] - tsx0[0])*(mx2 - mx1)/screen_width;
                            cy = (tsy[0] - tsy0[0])*(my2 - my1)/screen_height;
                            mx1 -= cx;
                            mx2 -= cx;
                            my1 -= cy;
                            my2 -= cy;
                            rectMandelBrot(mx1, my1, mx2, my2);
                        }
                        break;
                    case 2:
                        if(((tsx[0]-tsx[1])*(tsx[0]-tsx[1]) + 20) < ((tsx0[0]-tsx0[1])*(tsx0[0]-tsx0[1])))
                        {
                            lcd.DisplayStringAt(screen_width+41, 200, (uint8_t *)"out", LEFT_MODE);
                            zoom = zoom /2;
                            cx = (tsx0[0] + tsx0[1])/2;
                            cy = (tsy0[0] + tsy0[1])/2;
                            lx = (mx2 - mx1);
                            ly = (my2 - my1);
                            cx = cx * (mx2 - mx1) / screen_width + mx1;
                            cy = cy * (my2 - my1) / screen_height + my1;
                            mx1 = cx - lx;
                            mx2 = cx + lx;
                            my1 = cy - ly;
                            my2 = cy + ly;
                            rectMandelBrot(mx1, my1, mx2, my2);                           
                        }
                        else if(((tsx[0]-tsx[1])*(tsx[0]-tsx[1])) > ((tsx0[0]-tsx0[1])*(tsx0[0]-tsx0[1]) + 20))
                        {
                            lcd.DisplayStringAt(screen_width+41, 200, (uint8_t *)"in ", LEFT_MODE);
                            zoom = zoom*2;
                            cx = (tsx0[0] + tsx0[1])/2;
                            cy = (tsy0[0] + tsy0[1])/2;
                            lx = (mx2 - mx1)/4;
                            ly = (my2 - my1)/4;
                            cx = cx * (mx2 - mx1) / screen_width + mx1;
                            cy = cy * (my2 - my1) / screen_height + my1;
                            mx1 = cx - lx;
                            mx2 = cx + lx;
                            my1 = cy - ly;
                            my2 = cy + ly;
                            rectMandelBrot(mx1, my1, mx2, my2);  
                           
                        }

                        break;
                }
            }
        }


    }
}


DISCO-F746NG_fract.bin.zip

31.95 KB

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

29

主题

164

帖子

2

粉丝