这个程序演示了在STM32F746DISC开发板上显示分形(MandelBrot set),实现了缩放、移动、参数显示等功能。一个手指可以拖动图形,两个手指靠近或分开可以缩放。
#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[j] = calcMandelBrot(x1 + 4*dx*i, y1 + 4*dy*j);
lcd.DrawPixel(4*i, 4*j, 0xFF000000 | (c[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[j] == c[i+1][j]) && (c[j] == c[i+1][j+1]) && (c[j] == c[j+1]))
{
lcd.SetTextColor(0xFF000000 | (c[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;
}
}
}
}
}
用户468979 2016-5-10 14:40
用户1053025 2008-6-10 15:12