Example drawing mandelbrot on the RA8875 with touch to zoom in or out. Touch and hold > 4s to zoom out, touch to zoom in.
Saw the nice mandelbrot demo from Bob Stone and leverage it to use this library.
Diff: main.cpp
- Revision:
- 0:702ce703348d
- Child:
- 1:14319ec53540
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Jan 13 12:36:30 2015 +0000 @@ -0,0 +1,232 @@ +#include "mbed.h" + +#include "RA8875.h" + + +Serial pc(USBTX, USBRX); +RA8875 lcd(p5, p6, p7, p12, NC, "tft"); // MOSI, MISO, SCK, /ChipSelect, /reset, name +uint16_t width, height; + +#if 1 +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); + 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; //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); +} + +int main() +{ + Timer timer; + pc.baud(460800); // I like a snappy terminal, so crank it up! + pc.printf("\r\nRA8875 Portrait Mode Dev. - Build " __DATE__ " " __TIME__ "\r\n"); + lcd.frequency(10000000); + lcd.init(); + width = lcd.width(); // Could have set the dim, 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 + //lcd.set_font((unsigned char*) Arial12x12); // select the font + //lcd.set_orientation(1); + lcd.TouchPanelCalibrate("Touch to Calibrate"); // calibrate the touch + point_t p; + + lcd.locate(0,0); + + //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); + + //Wait for a touch + //p=lcd.get_touch(); + //while(!lcd.is_touched(p)) { + // p=lcd.get_touch(); + //} + pc.printf("ready for touch\r\n"); + while (!lcd.TouchPanelGet(&p)) + ; + timer.start(); + timer.reset(); + while (lcd.TouchPanelReadable()) + ; + if (timer.read_ms() > 4000) { // 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 + //p = lcd.to_pixel(p); + 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); + } + } +} + +#else + +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; + + 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 + 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)); + lcd.pixel(i,j, RGB(cr,cg,cb)); + } + x += dx; + } + y += dy; + } +} + +int main() +{ + pc.baud(460800); // I like a snappy terminal, so crank it up! + pc.printf("\r\nRA8875 Portrait Mode Dev. - Build " __DATE__ " " __TIME__ "\r\n"); + + lcd.init(); + + wait_ms(250); + + lcd.cls(); + lcd.SetOrientation(RA8875::rotate_0); + lcd.puts(30,30, "Normal Landscape"); + lcd.line(0,0, lcd.width()/2, lcd.height()/2); + wait_ms(2500); + + lcd.cls(); + lcd.SetOrientation(RA8875::rotate_90); + lcd.puts(30,30, "Rotated 90 Text\r\n"); + lcd.line(0,0, lcd.width()/2, lcd.height()/2); + wait_ms(2500); + + lcd.cls(); + lcd.SetOrientation(RA8875::rotate_180); + lcd.puts(30,30, "Rotated 180 Text\r\n"); + lcd.line(0,0, lcd.width()/2, lcd.height()/2); + wait_ms(2500); + + lcd.cls(); + lcd.SetOrientation(RA8875::rotate_270); + lcd.puts(30,30, "Rotated 270 Text\r\n"); + lcd.line(0,0, lcd.width()/2, lcd.height()/2); + wait_ms(2500); + + + while(1) { + while(!lcd.readable()) + ; + if (lcd.readable()) { + int k = lcd.getc(); + pc.printf("key: %02X \r\n", k); + } + wait_ms(50); + } +} +#endif