Mandelbrot set generator using DISCO-F746NG.
Dependencies: BSP_DISCO_F746NG LCD_DISCO_F746NG TS_DISCO_F746NG mbed BUTTON_GROUP
Diff: main.cpp
- Revision:
- 0:9a78f27b84a4
- Child:
- 1:27bfb11afcff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Nov 03 05:44:41 2015 +0000 @@ -0,0 +1,158 @@ +//--------------------------------------------------------------- +// Mandelbrot set generator +// +// Mandelbrot set is displayed using 3 kinds of color pattern. +// Tap the Mandelbrot set on the screen, expanded figure by a +// factor of two around the tapped position is displayed. +// +// 2015/11/03, Copyright (c) 2015 MIKAMI, Naoki +//--------------------------------------------------------------- + +#include "button.hpp" +#include "mandelbrot.hpp" + +using namespace Mikami; + +struct PointF +{ + PointF() {} + PointF(float x0, float y0) : x(x0), y(y0) {} + float x, y; +}; + +TS_DISCO_F746NG ts_; +LCD_DISCO_F746NG lcd_; + +const int X0_ = 5; // origin of x axis +const int Y0_ = 5; // origin of y axis +const int NX_ = 321; // number of pixels for horizon +const int NY_ = 261; // number of pixels for vertical + +void ReDraw(MandelbrotBase *mandel, + float wH, float hH, PointF xy, int level, + float &x1, float &x2, float &y1, float &y2) +{ + x1 = xy.x - wH; + x2 = xy.x + wH; + y1 = xy.y - hH; + y2 = xy.y + hH; + + char str[16]; + sprintf(str, "factor:%6d", 1 << level); + lcd_.DisplayStringAt(360, 224, (uint8_t *)str, LEFT_MODE); + sprintf(str, "x:%8.4f", xy.x); + lcd_.DisplayStringAt(360, 240, (uint8_t *)str, LEFT_MODE); + sprintf(str, "y:%8.4f", -xy.y); + lcd_.DisplayStringAt(360, 256, (uint8_t *)str, LEFT_MODE); + + mandel->Display(x1, x2, y1, y2); +} + +int main() +{ + const int LEVEL = 18; + PointF xy[LEVEL]; // corresponding to touched position + + uint32_t backColor = 0xFF006A6C; // teal green + + // region to be displayed + float x1 = -2.3f; + float x2 = 0.9f; + float y1 = -1.3f; + float y2 = 1.3f; + + float wH = (x2 - x1)/2.0f; // half width of region + float hH = (y2 - y1)/2.0f; // half height of region + + xy[0] = PointF(x1 + wH, y1 + hH); + + lcd_.Clear(backColor); + + MandelbrotBase *mandel[3]; + mandel[0] = new MandelbrotBW(lcd_, X0_, Y0_, NX_, NY_); + mandel[1] = new MandelbrotColor1(lcd_, X0_, Y0_, NX_, NY_); + mandel[2] = new MandelbrotColor2(lcd_, X0_, Y0_, NX_, NY_); + + Button *buttons[3]; + char strButton[3][8] = {"B & W", "Color1", "Color2"}; + for (int n=0; n<3; n++) + buttons[n] = new Button(lcd_, ts_, 340, Y0_+45*n, 60, 40, + LCD_COLOR_BLUE, strButton[n], Font12); + Button back(lcd_, ts_, 410, Y0_, 60, 40, LCD_COLOR_BLUE, "Back", Font12); + back.Draw(0xFFE0E0FF); + // area of Mandelbrot set + Button area(lcd_, ts_, X0_, Y0_, NX_, NY_, backColor); + + lcd_.SetBackColor(backColor); + + lcd_.SetFont(&Font20); + lcd_.DisplayStringAt(60, 130, (uint8_t *)"Mandelbrot set", LEFT_MODE); + + int pattern = -1; + int level = 0; + while (true) + { + // select color pattern + for (int k=0; k<3; k++) + { + buttons[k]->ReDraw(); + if (buttons[k]->Touched(LCD_COLOR_DARKBLUE)) + { + mandel[k]->Display(x1, x2, y1, y2); + pattern = k; + + lcd_.SetBackColor(backColor); + lcd_.SetFont(&Font12); + lcd_.DisplayStringAt(360, LINE(15), (uint8_t *)"Tap to zoom.", + LEFT_MODE); + } + } + + // expand twice around tapped point + if (area.Touched() && (pattern != -1)) + { + TS_StateTypeDef state; + ts_.GetState(&state); + + uint16_t x = state.touchX[0] - X0_; + uint16_t y = state.touchY[0] - Y0_; + + lcd_.SetBackColor(backColor); + if (++level < LEVEL) + { + xy[level] = PointF(mandel[pattern]->Fx(x), mandel[pattern]->Fy(y)); + wH = wH/2.0f; + hH = hH/2.0f; + + ReDraw(mandel[pattern], wH, hH, xy[level], level, x1, x2, y1, y2); + } + else + { + lcd_.SetFont(&Font20); + lcd_.DisplayStringAt(X0_+38, 130, (uint8_t *)" No more expand! ", + LEFT_MODE); + level = LEVEL - 1 ; + } + back.ReDraw(); + } + + // "back" button tapped + if (back.Touched() && level > 0) + { + back.Draw(LCD_COLOR_DARKBLUE); + lcd_.SetBackColor(backColor); + if (level > 0) + { + level--; + wH = wH*2.0f; + hH = hH*2.0f; + + ReDraw(mandel[pattern], wH, hH, xy[level], level, x1, x2, y1, y2); + + if (level > 0) back.ReDraw(); + else back.Draw(0xFFE0E0FF); + } + } + wait(0.1f); + } +}