Example drawing mandelbrot on the RA8875 with touch to zoom in or out. Touch and hold > 4s to zoom out, touch to zoom in.

Dependencies:   mbed RA8875

Saw the nice mandelbrot demo from Bob Stone and leverage it to use this library.

main.cpp

Committer:
WiredHome
Date:
2019-07-28
Revision:
6:3979c5ff6d32
Parent:
5:3efba02a1cb2

File content as of revision 6:3979c5ff6d32:

#include "mbed.h"       // v112
#include "RA8875.h"     // v102

// These two defines can be enabled, or commented out
#define BIG_SCREEN
#define CAP_TOUCH
#define LCD_C 16         // color - bits per pixel

#ifdef CAP_TOUCH
RA8875 lcd(p5,p6,p7,p12,NC, p9,p10,p13, "tft"); // MOSI,MISO,SCK,/ChipSelect,/reset, SDA,SCL,/IRQ, name
#else
RA8875 lcd(p5,p6,p7,p12,NC, "tft");             //MOSI, MISO, SCK, /ChipSelect, /reset, name
LocalFileSystem local("local");                     // access to calibration file for resistive touch.
#endif

#ifdef BIG_SCREEN
    #define LCD_W 800
    #define LCD_H 480
#else
    #define LCD_W 480
    #define LCD_H 272
#endif

Serial pc(USBTX, USBRX);

uint16_t width, height;

int GetScreenCapture(void)
{
    char fqfn[50];
    int i = 0;
    
    pc.printf("Screen Capture... ");
    for (i=1; i< 100; i++) {
        snprintf(fqfn, sizeof(fqfn), "/local/Screen%02d.bmp", i);
        FILE * fh = fopen(fqfn, "rb");
        if (!fh) {
            lcd.PrintScreen(0,0,480,272,fqfn);
            pc.printf(" as /local/Screen%02d.bmp\r\n", i);
            return i;
        } else {
            fclose(fh);     // close this and try the next
        }
    }
    return 0;
}


void drawMandelbrot(float centrex, float centrey, float zoom, int maxIter) {
    float xmin = centrex - 1.0/zoom;
    float xmax = centrex + 1.0/zoom;
    float ymin = centrey - height / (width * zoom);
    float ymax = centrey + height / (width * zoom);
    float dx = (xmax - xmin) / width;
    float dy = (ymax - ymin) / height;
    float y = ymin;
    float c;
    unsigned int cr, cg, cb;
    
    lcd.SetGraphicsCursor(0, 0);
    // shows use of a pixel (one line scan) buffer.
    color_t * pixelBuffer = (color_t *)malloc(width * sizeof(color_t));
    
    for (int j = 0; j < height; j++) {
        float x = xmin;
 
        for (int i = 0;  i < width; i++) {
            float a = x;
            float b = y;
            int n = 0;
 
            while (n < maxIter) {
                float aa = a * a;
                float bb = b * b;
                float twoab = 2.0 * a * b;
 
                a = aa - bb + x;
                b = twoab + y;
                if(aa + bb > 16.0) {
                    break;
                }
                n++;
            }
 
            if (n == maxIter) {
                //It's in the set - Black
                pixelBuffer[i] = Black;             // if not using the pixel buffer, then lcd.pixel(i,j,Black);
            } else {
                //Not in the set - pick a colour
                c = 3.0 * (maxIter-n)/maxIter;
                cr = ((c < 1.0) ? 255 * ( 1.0 - c) : (c > 2.0) ? 255 * (c - 2.0) : 0);
                cg = ((c < 1.0) ? 255 * c : (c > 2.0) ? 0 : 255 * (2.0 - c));
                cb = ((c < 1.0) ? 0 : (c > 2.0) ? 255 * (3.0 - c) : 255 * (c - 1.0));
                pixelBuffer[i] = RGB(cr,cg,cb);     //lcd.pixel(i,j, RGB(cr,cg,cb));
            }
            x += dx;
        }
        lcd.pixelStream(pixelBuffer, width, 0, j);  // send this scanline
        y += dy;
    }
    free(pixelBuffer);  // don't leak memory.
}



int main()
{
    Timer timer;
    point_t p;

    pc.baud(460800);    // I like a snappy terminal, so crank it up!
    pc.printf("\r\nRA8875 Portrait Mode Dev. - Build " __DATE__ " " __TIME__ "\r\n");
    pc.printf("Press 'P' to PrintScreen as bmp on local file system\r\n");
    
    lcd.init(LCD_W, LCD_H, LCD_C);
    lcd.Backlight(0.5f);
    
    #ifndef CAP_TOUCH
    InitTS();
    #endif

    width = lcd.width();        // Could have set the dimensions, let's just adapt.
    height = lcd.height();

    lcd.claim(stdout);        // send stdout to the TFT display
    lcd.background(Black);    // set background to black
    lcd.foreground(White);    // set chars to white
    lcd.cls();                // clear the screen
  
    //Setup base Mandelbrot
    float centrex = -0.5;
    float centrey = 0.0;
    float zoom=0.5;
    int maxiterations = 150;
 
    while(true) {
        //Draw it    
        drawMandelbrot(centrex, centrey, zoom, maxiterations);
    
        pc.printf("ready for touch\r\n");
        bool waitingOnUser = true;
        while (waitingOnUser) {
            TouchCode_t t;
            
            if (pc.readable()) {
                int c = pc.getc();
                if (c == 'P')
                    GetScreenCapture();
            }
            t = lcd.TouchPanelReadable();
            if (t != no_touch) {
                bool zoomOut = false;
                
                pc.printf("touch: %d\r\n", t);
                timer.start();
                timer.reset();
                t = lcd.TouchPanelReadable(&p);
                pc.printf(" t: %d\r\n", t);
                while (t == touch || t == held) {
                    if (timer.read_ms() > 2000) {
                        zoomOut = true;
                        break;
                    }
                    t = lcd.TouchPanelReadable(&p);
                    pc.printf(" u: %d\r\n", t);
                }
                if (zoomOut) {   // long held is zoom out.
                    // zoom out
                    lcd.puts(50, 250, "Zooming out...");
                    pc.printf("zoom out\r\n");
                    centrex = -0.5;
                    centrey = 0.0;
                    zoom=0.5;
                } else {
                    //Set new centre and zoom
                    lcd.puts(50, 250, "Zooming in...");
                    pc.printf("zoom in\r\n");
                    centrex += (2.0 * p.x - width) / (zoom * height);
                    centrey += (2.0 * p.y - height) / (zoom * width);
                    zoom *= 4.0;
                    lcd.rect(p.x - width / 8.0, p.y - height / 8.0, 
                             p.x + width / 8.0, p.y + height / 8.0, Yellow);
                    wait_ms(100);
                }
                waitingOnUser = false;
            }
        }
    }
}