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.
main.cpp@0:702ce703348d, 2015-01-13 (annotated)
- Committer:
- WiredHome
- Date:
- Tue Jan 13 12:36:30 2015 +0000
- Revision:
- 0:702ce703348d
- Child:
- 1:14319ec53540
Applied Mandelbrot drawing program from Bob Stone to this RA8875 library.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
WiredHome | 0:702ce703348d | 1 | #include "mbed.h" |
WiredHome | 0:702ce703348d | 2 | |
WiredHome | 0:702ce703348d | 3 | #include "RA8875.h" |
WiredHome | 0:702ce703348d | 4 | |
WiredHome | 0:702ce703348d | 5 | |
WiredHome | 0:702ce703348d | 6 | Serial pc(USBTX, USBRX); |
WiredHome | 0:702ce703348d | 7 | RA8875 lcd(p5, p6, p7, p12, NC, "tft"); // MOSI, MISO, SCK, /ChipSelect, /reset, name |
WiredHome | 0:702ce703348d | 8 | uint16_t width, height; |
WiredHome | 0:702ce703348d | 9 | |
WiredHome | 0:702ce703348d | 10 | #if 1 |
WiredHome | 0:702ce703348d | 11 | void drawMandelbrot(float centrex, float centrey, float zoom, int maxIter) { |
WiredHome | 0:702ce703348d | 12 | float xmin = centrex - 1.0/zoom; |
WiredHome | 0:702ce703348d | 13 | float xmax = centrex + 1.0/zoom; |
WiredHome | 0:702ce703348d | 14 | float ymin = centrey - height / (width * zoom); |
WiredHome | 0:702ce703348d | 15 | float ymax = centrey + height / (width *zoom); |
WiredHome | 0:702ce703348d | 16 | |
WiredHome | 0:702ce703348d | 17 | float dx = (xmax - xmin) / width; |
WiredHome | 0:702ce703348d | 18 | float dy = (ymax - ymin) / height; |
WiredHome | 0:702ce703348d | 19 | |
WiredHome | 0:702ce703348d | 20 | float y = ymin; |
WiredHome | 0:702ce703348d | 21 | |
WiredHome | 0:702ce703348d | 22 | float c; |
WiredHome | 0:702ce703348d | 23 | unsigned int cr, cg, cb; |
WiredHome | 0:702ce703348d | 24 | |
WiredHome | 0:702ce703348d | 25 | lcd.SetGraphicsCursor(0, 0); |
WiredHome | 0:702ce703348d | 26 | color_t * pixelBuffer = (color_t *)malloc(width * sizeof(color_t)); |
WiredHome | 0:702ce703348d | 27 | |
WiredHome | 0:702ce703348d | 28 | for (int j = 0; j < height; j++) { |
WiredHome | 0:702ce703348d | 29 | float x = xmin; |
WiredHome | 0:702ce703348d | 30 | |
WiredHome | 0:702ce703348d | 31 | for (int i = 0; i < width; i++) { |
WiredHome | 0:702ce703348d | 32 | float a = x; |
WiredHome | 0:702ce703348d | 33 | float b = y; |
WiredHome | 0:702ce703348d | 34 | int n = 0; |
WiredHome | 0:702ce703348d | 35 | |
WiredHome | 0:702ce703348d | 36 | while (n < maxIter) { |
WiredHome | 0:702ce703348d | 37 | float aa = a * a; |
WiredHome | 0:702ce703348d | 38 | float bb = b * b; |
WiredHome | 0:702ce703348d | 39 | float twoab = 2.0 * a * b; |
WiredHome | 0:702ce703348d | 40 | |
WiredHome | 0:702ce703348d | 41 | a = aa - bb + x; |
WiredHome | 0:702ce703348d | 42 | b = twoab + y; |
WiredHome | 0:702ce703348d | 43 | |
WiredHome | 0:702ce703348d | 44 | if(aa + bb > 16.0) { |
WiredHome | 0:702ce703348d | 45 | break; |
WiredHome | 0:702ce703348d | 46 | } |
WiredHome | 0:702ce703348d | 47 | n++; |
WiredHome | 0:702ce703348d | 48 | } |
WiredHome | 0:702ce703348d | 49 | |
WiredHome | 0:702ce703348d | 50 | if (n == maxIter) { |
WiredHome | 0:702ce703348d | 51 | //It's in the set - Black |
WiredHome | 0:702ce703348d | 52 | pixelBuffer[i] = Black; //lcd.pixel(i,j,Black); |
WiredHome | 0:702ce703348d | 53 | } else { |
WiredHome | 0:702ce703348d | 54 | //Not in the set - pick a colour |
WiredHome | 0:702ce703348d | 55 | c = 3.0 * (maxIter-n)/maxIter; |
WiredHome | 0:702ce703348d | 56 | cr = ((c < 1.0) ? 255 * ( 1.0 - c) : (c > 2.0) ? 255 * (c - 2.0) : 0); |
WiredHome | 0:702ce703348d | 57 | cg = ((c < 1.0) ? 255 * c : (c > 2.0) ? 0 : 255 * (2.0 - c)); |
WiredHome | 0:702ce703348d | 58 | cb = ((c < 1.0) ? 0 : (c > 2.0) ? 255 * (3.0 - c) : 255 * (c - 1.0)); |
WiredHome | 0:702ce703348d | 59 | pixelBuffer[i] = RGB(cr,cg,cb); //lcd.pixel(i,j, RGB(cr,cg,cb)); |
WiredHome | 0:702ce703348d | 60 | } |
WiredHome | 0:702ce703348d | 61 | x += dx; |
WiredHome | 0:702ce703348d | 62 | } |
WiredHome | 0:702ce703348d | 63 | lcd.pixelStream(pixelBuffer, width, 0, j); // send this scanline |
WiredHome | 0:702ce703348d | 64 | y += dy; |
WiredHome | 0:702ce703348d | 65 | } |
WiredHome | 0:702ce703348d | 66 | free(pixelBuffer); |
WiredHome | 0:702ce703348d | 67 | } |
WiredHome | 0:702ce703348d | 68 | |
WiredHome | 0:702ce703348d | 69 | int main() |
WiredHome | 0:702ce703348d | 70 | { |
WiredHome | 0:702ce703348d | 71 | Timer timer; |
WiredHome | 0:702ce703348d | 72 | pc.baud(460800); // I like a snappy terminal, so crank it up! |
WiredHome | 0:702ce703348d | 73 | pc.printf("\r\nRA8875 Portrait Mode Dev. - Build " __DATE__ " " __TIME__ "\r\n"); |
WiredHome | 0:702ce703348d | 74 | lcd.frequency(10000000); |
WiredHome | 0:702ce703348d | 75 | lcd.init(); |
WiredHome | 0:702ce703348d | 76 | width = lcd.width(); // Could have set the dim, let's just adapt. |
WiredHome | 0:702ce703348d | 77 | height = lcd.height(); |
WiredHome | 0:702ce703348d | 78 | |
WiredHome | 0:702ce703348d | 79 | lcd.claim(stdout); // send stdout to the TFT display |
WiredHome | 0:702ce703348d | 80 | lcd.background(Black); // set background to black |
WiredHome | 0:702ce703348d | 81 | lcd.foreground(White); // set chars to white |
WiredHome | 0:702ce703348d | 82 | lcd.cls(); // clear the screen |
WiredHome | 0:702ce703348d | 83 | //lcd.set_font((unsigned char*) Arial12x12); // select the font |
WiredHome | 0:702ce703348d | 84 | //lcd.set_orientation(1); |
WiredHome | 0:702ce703348d | 85 | lcd.TouchPanelCalibrate("Touch to Calibrate"); // calibrate the touch |
WiredHome | 0:702ce703348d | 86 | point_t p; |
WiredHome | 0:702ce703348d | 87 | |
WiredHome | 0:702ce703348d | 88 | lcd.locate(0,0); |
WiredHome | 0:702ce703348d | 89 | |
WiredHome | 0:702ce703348d | 90 | //Setup base Mandelbrot |
WiredHome | 0:702ce703348d | 91 | float centrex = -0.5; |
WiredHome | 0:702ce703348d | 92 | float centrey = 0.0; |
WiredHome | 0:702ce703348d | 93 | float zoom=0.5; |
WiredHome | 0:702ce703348d | 94 | int maxiterations = 150; |
WiredHome | 0:702ce703348d | 95 | |
WiredHome | 0:702ce703348d | 96 | while(true) { |
WiredHome | 0:702ce703348d | 97 | //Draw it |
WiredHome | 0:702ce703348d | 98 | drawMandelbrot(centrex, centrey, zoom, maxiterations); |
WiredHome | 0:702ce703348d | 99 | |
WiredHome | 0:702ce703348d | 100 | //Wait for a touch |
WiredHome | 0:702ce703348d | 101 | //p=lcd.get_touch(); |
WiredHome | 0:702ce703348d | 102 | //while(!lcd.is_touched(p)) { |
WiredHome | 0:702ce703348d | 103 | // p=lcd.get_touch(); |
WiredHome | 0:702ce703348d | 104 | //} |
WiredHome | 0:702ce703348d | 105 | pc.printf("ready for touch\r\n"); |
WiredHome | 0:702ce703348d | 106 | while (!lcd.TouchPanelGet(&p)) |
WiredHome | 0:702ce703348d | 107 | ; |
WiredHome | 0:702ce703348d | 108 | timer.start(); |
WiredHome | 0:702ce703348d | 109 | timer.reset(); |
WiredHome | 0:702ce703348d | 110 | while (lcd.TouchPanelReadable()) |
WiredHome | 0:702ce703348d | 111 | ; |
WiredHome | 0:702ce703348d | 112 | if (timer.read_ms() > 4000) { // long held is zoom out. |
WiredHome | 0:702ce703348d | 113 | // zoom out |
WiredHome | 0:702ce703348d | 114 | lcd.puts(50, 250, "Zooming out..."); |
WiredHome | 0:702ce703348d | 115 | pc.printf("zoom out\r\n"); |
WiredHome | 0:702ce703348d | 116 | centrex = -0.5; |
WiredHome | 0:702ce703348d | 117 | centrey = 0.0; |
WiredHome | 0:702ce703348d | 118 | zoom=0.5; |
WiredHome | 0:702ce703348d | 119 | } else { |
WiredHome | 0:702ce703348d | 120 | //Set new centre and zoom |
WiredHome | 0:702ce703348d | 121 | //p = lcd.to_pixel(p); |
WiredHome | 0:702ce703348d | 122 | lcd.puts(50, 250, "Zooming in..."); |
WiredHome | 0:702ce703348d | 123 | pc.printf("zoom in\r\n"); |
WiredHome | 0:702ce703348d | 124 | centrex += (2.0 * p.x - width) / (zoom * height); |
WiredHome | 0:702ce703348d | 125 | centrey += (2.0 * p.y - height) / (zoom * width); |
WiredHome | 0:702ce703348d | 126 | zoom *= 4.0; |
WiredHome | 0:702ce703348d | 127 | lcd.rect(p.x - width / 8.0, p.y - height / 8.0, |
WiredHome | 0:702ce703348d | 128 | p.x + width / 8.0, p.y + height / 8.0, Yellow); |
WiredHome | 0:702ce703348d | 129 | } |
WiredHome | 0:702ce703348d | 130 | } |
WiredHome | 0:702ce703348d | 131 | } |
WiredHome | 0:702ce703348d | 132 | |
WiredHome | 0:702ce703348d | 133 | #else |
WiredHome | 0:702ce703348d | 134 | |
WiredHome | 0:702ce703348d | 135 | void drawMandelbrot(float centrex, float centrey, float zoom, int maxIter) { |
WiredHome | 0:702ce703348d | 136 | float xmin = centrex - 1.0/zoom; |
WiredHome | 0:702ce703348d | 137 | float xmax = centrex + 1.0/zoom; |
WiredHome | 0:702ce703348d | 138 | float ymin = centrey - height / (width * zoom); |
WiredHome | 0:702ce703348d | 139 | float ymax = centrey + height / (width *zoom); |
WiredHome | 0:702ce703348d | 140 | |
WiredHome | 0:702ce703348d | 141 | float dx = (xmax - xmin) / width; |
WiredHome | 0:702ce703348d | 142 | float dy = (ymax - ymin) / height; |
WiredHome | 0:702ce703348d | 143 | |
WiredHome | 0:702ce703348d | 144 | float y = ymin; |
WiredHome | 0:702ce703348d | 145 | |
WiredHome | 0:702ce703348d | 146 | float c; |
WiredHome | 0:702ce703348d | 147 | unsigned int cr, cg, cb; |
WiredHome | 0:702ce703348d | 148 | |
WiredHome | 0:702ce703348d | 149 | for (int j = 0; j < height; j++) { |
WiredHome | 0:702ce703348d | 150 | float x = xmin; |
WiredHome | 0:702ce703348d | 151 | |
WiredHome | 0:702ce703348d | 152 | for (int i = 0; i < width; i++) { |
WiredHome | 0:702ce703348d | 153 | float a = x; |
WiredHome | 0:702ce703348d | 154 | float b = y; |
WiredHome | 0:702ce703348d | 155 | int n = 0; |
WiredHome | 0:702ce703348d | 156 | |
WiredHome | 0:702ce703348d | 157 | while (n < maxIter) { |
WiredHome | 0:702ce703348d | 158 | float aa = a * a; |
WiredHome | 0:702ce703348d | 159 | float bb = b * b; |
WiredHome | 0:702ce703348d | 160 | float twoab = 2.0 * a * b; |
WiredHome | 0:702ce703348d | 161 | |
WiredHome | 0:702ce703348d | 162 | a = aa - bb + x; |
WiredHome | 0:702ce703348d | 163 | b = twoab + y; |
WiredHome | 0:702ce703348d | 164 | |
WiredHome | 0:702ce703348d | 165 | if(aa + bb > 16.0) { |
WiredHome | 0:702ce703348d | 166 | break; |
WiredHome | 0:702ce703348d | 167 | } |
WiredHome | 0:702ce703348d | 168 | n++; |
WiredHome | 0:702ce703348d | 169 | } |
WiredHome | 0:702ce703348d | 170 | |
WiredHome | 0:702ce703348d | 171 | if (n == maxIter) { |
WiredHome | 0:702ce703348d | 172 | //It's in the set - Black |
WiredHome | 0:702ce703348d | 173 | lcd.pixel(i,j,Black); |
WiredHome | 0:702ce703348d | 174 | } else { |
WiredHome | 0:702ce703348d | 175 | //Not in the set - pick a colour |
WiredHome | 0:702ce703348d | 176 | c = 3.0 * (maxIter-n)/maxIter; |
WiredHome | 0:702ce703348d | 177 | cr = ((c < 1.0) ? 255 * ( 1.0 - c) : (c > 2.0) ? 255 * (c - 2.0) : 0); |
WiredHome | 0:702ce703348d | 178 | cg = ((c < 1.0) ? 255 * c : (c > 2.0) ? 0 : 255 * (2.0 - c)); |
WiredHome | 0:702ce703348d | 179 | cb = ((c < 1.0) ? 0 : (c > 2.0) ? 255 * (3.0 - c) : 255 * (c - 1.0)); |
WiredHome | 0:702ce703348d | 180 | lcd.pixel(i,j, RGB(cr,cg,cb)); |
WiredHome | 0:702ce703348d | 181 | } |
WiredHome | 0:702ce703348d | 182 | x += dx; |
WiredHome | 0:702ce703348d | 183 | } |
WiredHome | 0:702ce703348d | 184 | y += dy; |
WiredHome | 0:702ce703348d | 185 | } |
WiredHome | 0:702ce703348d | 186 | } |
WiredHome | 0:702ce703348d | 187 | |
WiredHome | 0:702ce703348d | 188 | int main() |
WiredHome | 0:702ce703348d | 189 | { |
WiredHome | 0:702ce703348d | 190 | pc.baud(460800); // I like a snappy terminal, so crank it up! |
WiredHome | 0:702ce703348d | 191 | pc.printf("\r\nRA8875 Portrait Mode Dev. - Build " __DATE__ " " __TIME__ "\r\n"); |
WiredHome | 0:702ce703348d | 192 | |
WiredHome | 0:702ce703348d | 193 | lcd.init(); |
WiredHome | 0:702ce703348d | 194 | |
WiredHome | 0:702ce703348d | 195 | wait_ms(250); |
WiredHome | 0:702ce703348d | 196 | |
WiredHome | 0:702ce703348d | 197 | lcd.cls(); |
WiredHome | 0:702ce703348d | 198 | lcd.SetOrientation(RA8875::rotate_0); |
WiredHome | 0:702ce703348d | 199 | lcd.puts(30,30, "Normal Landscape"); |
WiredHome | 0:702ce703348d | 200 | lcd.line(0,0, lcd.width()/2, lcd.height()/2); |
WiredHome | 0:702ce703348d | 201 | wait_ms(2500); |
WiredHome | 0:702ce703348d | 202 | |
WiredHome | 0:702ce703348d | 203 | lcd.cls(); |
WiredHome | 0:702ce703348d | 204 | lcd.SetOrientation(RA8875::rotate_90); |
WiredHome | 0:702ce703348d | 205 | lcd.puts(30,30, "Rotated 90 Text\r\n"); |
WiredHome | 0:702ce703348d | 206 | lcd.line(0,0, lcd.width()/2, lcd.height()/2); |
WiredHome | 0:702ce703348d | 207 | wait_ms(2500); |
WiredHome | 0:702ce703348d | 208 | |
WiredHome | 0:702ce703348d | 209 | lcd.cls(); |
WiredHome | 0:702ce703348d | 210 | lcd.SetOrientation(RA8875::rotate_180); |
WiredHome | 0:702ce703348d | 211 | lcd.puts(30,30, "Rotated 180 Text\r\n"); |
WiredHome | 0:702ce703348d | 212 | lcd.line(0,0, lcd.width()/2, lcd.height()/2); |
WiredHome | 0:702ce703348d | 213 | wait_ms(2500); |
WiredHome | 0:702ce703348d | 214 | |
WiredHome | 0:702ce703348d | 215 | lcd.cls(); |
WiredHome | 0:702ce703348d | 216 | lcd.SetOrientation(RA8875::rotate_270); |
WiredHome | 0:702ce703348d | 217 | lcd.puts(30,30, "Rotated 270 Text\r\n"); |
WiredHome | 0:702ce703348d | 218 | lcd.line(0,0, lcd.width()/2, lcd.height()/2); |
WiredHome | 0:702ce703348d | 219 | wait_ms(2500); |
WiredHome | 0:702ce703348d | 220 | |
WiredHome | 0:702ce703348d | 221 | |
WiredHome | 0:702ce703348d | 222 | while(1) { |
WiredHome | 0:702ce703348d | 223 | while(!lcd.readable()) |
WiredHome | 0:702ce703348d | 224 | ; |
WiredHome | 0:702ce703348d | 225 | if (lcd.readable()) { |
WiredHome | 0:702ce703348d | 226 | int k = lcd.getc(); |
WiredHome | 0:702ce703348d | 227 | pc.printf("key: %02X \r\n", k); |
WiredHome | 0:702ce703348d | 228 | } |
WiredHome | 0:702ce703348d | 229 | wait_ms(50); |
WiredHome | 0:702ce703348d | 230 | } |
WiredHome | 0:702ce703348d | 231 | } |
WiredHome | 0:702ce703348d | 232 | #endif |