Mandelbrot set generator using DISCO-F746NG.

Dependencies:   BSP_DISCO_F746NG LCD_DISCO_F746NG TS_DISCO_F746NG mbed BUTTON_GROUP

Committer:
MikamiUitOpen
Date:
Thu Nov 05 04:38:28 2015 +0000
Revision:
1:27bfb11afcff
Parent:
0:9a78f27b84a4
Child:
2:6c1471e4a4b1
2

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MikamiUitOpen 0:9a78f27b84a4 1 //---------------------------------------------------------------
MikamiUitOpen 0:9a78f27b84a4 2 // Mandelbrot set generator
MikamiUitOpen 0:9a78f27b84a4 3 //
MikamiUitOpen 0:9a78f27b84a4 4 // Mandelbrot set is displayed using 3 kinds of color pattern.
MikamiUitOpen 0:9a78f27b84a4 5 // Tap the Mandelbrot set on the screen, expanded figure by a
MikamiUitOpen 0:9a78f27b84a4 6 // factor of two around the tapped position is displayed.
MikamiUitOpen 0:9a78f27b84a4 7 //
MikamiUitOpen 1:27bfb11afcff 8 // 2015/11/05, Copyright (c) 2015 MIKAMI, Naoki
MikamiUitOpen 0:9a78f27b84a4 9 //---------------------------------------------------------------
MikamiUitOpen 0:9a78f27b84a4 10
MikamiUitOpen 0:9a78f27b84a4 11 #include "button.hpp"
MikamiUitOpen 0:9a78f27b84a4 12 #include "mandelbrot.hpp"
MikamiUitOpen 0:9a78f27b84a4 13
MikamiUitOpen 0:9a78f27b84a4 14 using namespace Mikami;
MikamiUitOpen 0:9a78f27b84a4 15
MikamiUitOpen 0:9a78f27b84a4 16 struct PointF
MikamiUitOpen 0:9a78f27b84a4 17 {
MikamiUitOpen 0:9a78f27b84a4 18 PointF() {}
MikamiUitOpen 0:9a78f27b84a4 19 PointF(float x0, float y0) : x(x0), y(y0) {}
MikamiUitOpen 0:9a78f27b84a4 20 float x, y;
MikamiUitOpen 0:9a78f27b84a4 21 };
MikamiUitOpen 0:9a78f27b84a4 22
MikamiUitOpen 0:9a78f27b84a4 23 TS_DISCO_F746NG ts_;
MikamiUitOpen 0:9a78f27b84a4 24 LCD_DISCO_F746NG lcd_;
MikamiUitOpen 0:9a78f27b84a4 25
MikamiUitOpen 0:9a78f27b84a4 26 const int X0_ = 5; // origin of x axis
MikamiUitOpen 0:9a78f27b84a4 27 const int Y0_ = 5; // origin of y axis
MikamiUitOpen 0:9a78f27b84a4 28 const int NX_ = 321; // number of pixels for horizon
MikamiUitOpen 0:9a78f27b84a4 29 const int NY_ = 261; // number of pixels for vertical
MikamiUitOpen 0:9a78f27b84a4 30
MikamiUitOpen 0:9a78f27b84a4 31 void ReDraw(MandelbrotBase *mandel,
MikamiUitOpen 0:9a78f27b84a4 32 float wH, float hH, PointF xy, int level,
MikamiUitOpen 0:9a78f27b84a4 33 float &x1, float &x2, float &y1, float &y2)
MikamiUitOpen 0:9a78f27b84a4 34 {
MikamiUitOpen 0:9a78f27b84a4 35 x1 = xy.x - wH;
MikamiUitOpen 0:9a78f27b84a4 36 x2 = xy.x + wH;
MikamiUitOpen 0:9a78f27b84a4 37 y1 = xy.y - hH;
MikamiUitOpen 0:9a78f27b84a4 38 y2 = xy.y + hH;
MikamiUitOpen 0:9a78f27b84a4 39
MikamiUitOpen 0:9a78f27b84a4 40 char str[16];
MikamiUitOpen 0:9a78f27b84a4 41 sprintf(str, "factor:%6d", 1 << level);
MikamiUitOpen 0:9a78f27b84a4 42 lcd_.DisplayStringAt(360, 224, (uint8_t *)str, LEFT_MODE);
MikamiUitOpen 0:9a78f27b84a4 43 sprintf(str, "x:%8.4f", xy.x);
MikamiUitOpen 0:9a78f27b84a4 44 lcd_.DisplayStringAt(360, 240, (uint8_t *)str, LEFT_MODE);
MikamiUitOpen 0:9a78f27b84a4 45 sprintf(str, "y:%8.4f", -xy.y);
MikamiUitOpen 0:9a78f27b84a4 46 lcd_.DisplayStringAt(360, 256, (uint8_t *)str, LEFT_MODE);
MikamiUitOpen 0:9a78f27b84a4 47
MikamiUitOpen 0:9a78f27b84a4 48 mandel->Display(x1, x2, y1, y2);
MikamiUitOpen 0:9a78f27b84a4 49 }
MikamiUitOpen 0:9a78f27b84a4 50
MikamiUitOpen 0:9a78f27b84a4 51 int main()
MikamiUitOpen 0:9a78f27b84a4 52 {
MikamiUitOpen 0:9a78f27b84a4 53 const int LEVEL = 18;
MikamiUitOpen 0:9a78f27b84a4 54 PointF xy[LEVEL]; // corresponding to touched position
MikamiUitOpen 0:9a78f27b84a4 55
MikamiUitOpen 0:9a78f27b84a4 56 uint32_t backColor = 0xFF006A6C; // teal green
MikamiUitOpen 0:9a78f27b84a4 57
MikamiUitOpen 0:9a78f27b84a4 58 // region to be displayed
MikamiUitOpen 0:9a78f27b84a4 59 float x1 = -2.3f;
MikamiUitOpen 0:9a78f27b84a4 60 float x2 = 0.9f;
MikamiUitOpen 0:9a78f27b84a4 61 float y1 = -1.3f;
MikamiUitOpen 0:9a78f27b84a4 62 float y2 = 1.3f;
MikamiUitOpen 0:9a78f27b84a4 63
MikamiUitOpen 0:9a78f27b84a4 64 float wH = (x2 - x1)/2.0f; // half width of region
MikamiUitOpen 0:9a78f27b84a4 65 float hH = (y2 - y1)/2.0f; // half height of region
MikamiUitOpen 0:9a78f27b84a4 66
MikamiUitOpen 0:9a78f27b84a4 67 xy[0] = PointF(x1 + wH, y1 + hH);
MikamiUitOpen 0:9a78f27b84a4 68
MikamiUitOpen 0:9a78f27b84a4 69 lcd_.Clear(backColor);
MikamiUitOpen 0:9a78f27b84a4 70
MikamiUitOpen 0:9a78f27b84a4 71 MandelbrotBase *mandel[3];
MikamiUitOpen 0:9a78f27b84a4 72 mandel[0] = new MandelbrotBW(lcd_, X0_, Y0_, NX_, NY_);
MikamiUitOpen 0:9a78f27b84a4 73 mandel[1] = new MandelbrotColor1(lcd_, X0_, Y0_, NX_, NY_);
MikamiUitOpen 0:9a78f27b84a4 74 mandel[2] = new MandelbrotColor2(lcd_, X0_, Y0_, NX_, NY_);
MikamiUitOpen 0:9a78f27b84a4 75
MikamiUitOpen 0:9a78f27b84a4 76 Button *buttons[3];
MikamiUitOpen 0:9a78f27b84a4 77 char strButton[3][8] = {"B & W", "Color1", "Color2"};
MikamiUitOpen 0:9a78f27b84a4 78 for (int n=0; n<3; n++)
MikamiUitOpen 0:9a78f27b84a4 79 buttons[n] = new Button(lcd_, ts_, 340, Y0_+45*n, 60, 40,
MikamiUitOpen 0:9a78f27b84a4 80 LCD_COLOR_BLUE, strButton[n], Font12);
MikamiUitOpen 0:9a78f27b84a4 81 Button back(lcd_, ts_, 410, Y0_, 60, 40, LCD_COLOR_BLUE, "Back", Font12);
MikamiUitOpen 1:27bfb11afcff 82 back.Erase(backColor); //back.Draw(0xFFE0E0FF);
MikamiUitOpen 0:9a78f27b84a4 83 // area of Mandelbrot set
MikamiUitOpen 0:9a78f27b84a4 84 Button area(lcd_, ts_, X0_, Y0_, NX_, NY_, backColor);
MikamiUitOpen 0:9a78f27b84a4 85
MikamiUitOpen 0:9a78f27b84a4 86 lcd_.SetBackColor(backColor);
MikamiUitOpen 0:9a78f27b84a4 87
MikamiUitOpen 0:9a78f27b84a4 88 lcd_.SetFont(&Font20);
MikamiUitOpen 0:9a78f27b84a4 89 lcd_.DisplayStringAt(60, 130, (uint8_t *)"Mandelbrot set", LEFT_MODE);
MikamiUitOpen 0:9a78f27b84a4 90
MikamiUitOpen 0:9a78f27b84a4 91 int pattern = -1;
MikamiUitOpen 0:9a78f27b84a4 92 int level = 0;
MikamiUitOpen 0:9a78f27b84a4 93 while (true)
MikamiUitOpen 0:9a78f27b84a4 94 {
MikamiUitOpen 0:9a78f27b84a4 95 // select color pattern
MikamiUitOpen 0:9a78f27b84a4 96 for (int k=0; k<3; k++)
MikamiUitOpen 0:9a78f27b84a4 97 {
MikamiUitOpen 0:9a78f27b84a4 98 buttons[k]->ReDraw();
MikamiUitOpen 1:27bfb11afcff 99 if (buttons[k]->Touched() && (pattern != k))
MikamiUitOpen 0:9a78f27b84a4 100 {
MikamiUitOpen 1:27bfb11afcff 101 buttons[k]->Draw(LCD_COLOR_DARKBLUE);
MikamiUitOpen 0:9a78f27b84a4 102 mandel[k]->Display(x1, x2, y1, y2);
MikamiUitOpen 0:9a78f27b84a4 103 pattern = k;
MikamiUitOpen 0:9a78f27b84a4 104
MikamiUitOpen 0:9a78f27b84a4 105 lcd_.SetBackColor(backColor);
MikamiUitOpen 0:9a78f27b84a4 106 lcd_.SetFont(&Font12);
MikamiUitOpen 0:9a78f27b84a4 107 lcd_.DisplayStringAt(360, LINE(15), (uint8_t *)"Tap to zoom.",
MikamiUitOpen 0:9a78f27b84a4 108 LEFT_MODE);
MikamiUitOpen 0:9a78f27b84a4 109 }
MikamiUitOpen 0:9a78f27b84a4 110 }
MikamiUitOpen 0:9a78f27b84a4 111
MikamiUitOpen 0:9a78f27b84a4 112 // expand twice around tapped point
MikamiUitOpen 0:9a78f27b84a4 113 if (area.Touched() && (pattern != -1))
MikamiUitOpen 0:9a78f27b84a4 114 {
MikamiUitOpen 0:9a78f27b84a4 115 TS_StateTypeDef state;
MikamiUitOpen 0:9a78f27b84a4 116 ts_.GetState(&state);
MikamiUitOpen 0:9a78f27b84a4 117
MikamiUitOpen 0:9a78f27b84a4 118 uint16_t x = state.touchX[0] - X0_;
MikamiUitOpen 0:9a78f27b84a4 119 uint16_t y = state.touchY[0] - Y0_;
MikamiUitOpen 0:9a78f27b84a4 120
MikamiUitOpen 0:9a78f27b84a4 121 lcd_.SetBackColor(backColor);
MikamiUitOpen 0:9a78f27b84a4 122 if (++level < LEVEL)
MikamiUitOpen 0:9a78f27b84a4 123 {
MikamiUitOpen 0:9a78f27b84a4 124 xy[level] = PointF(mandel[pattern]->Fx(x), mandel[pattern]->Fy(y));
MikamiUitOpen 0:9a78f27b84a4 125 wH = wH/2.0f;
MikamiUitOpen 0:9a78f27b84a4 126 hH = hH/2.0f;
MikamiUitOpen 0:9a78f27b84a4 127
MikamiUitOpen 0:9a78f27b84a4 128 ReDraw(mandel[pattern], wH, hH, xy[level], level, x1, x2, y1, y2);
MikamiUitOpen 0:9a78f27b84a4 129 }
MikamiUitOpen 0:9a78f27b84a4 130 else
MikamiUitOpen 0:9a78f27b84a4 131 {
MikamiUitOpen 0:9a78f27b84a4 132 lcd_.SetFont(&Font20);
MikamiUitOpen 0:9a78f27b84a4 133 lcd_.DisplayStringAt(X0_+38, 130, (uint8_t *)" No more expand! ",
MikamiUitOpen 0:9a78f27b84a4 134 LEFT_MODE);
MikamiUitOpen 0:9a78f27b84a4 135 level = LEVEL - 1 ;
MikamiUitOpen 0:9a78f27b84a4 136 }
MikamiUitOpen 0:9a78f27b84a4 137 back.ReDraw();
MikamiUitOpen 0:9a78f27b84a4 138 }
MikamiUitOpen 0:9a78f27b84a4 139
MikamiUitOpen 0:9a78f27b84a4 140 // "back" button tapped
MikamiUitOpen 0:9a78f27b84a4 141 if (back.Touched() && level > 0)
MikamiUitOpen 0:9a78f27b84a4 142 {
MikamiUitOpen 0:9a78f27b84a4 143 back.Draw(LCD_COLOR_DARKBLUE);
MikamiUitOpen 0:9a78f27b84a4 144 lcd_.SetBackColor(backColor);
MikamiUitOpen 0:9a78f27b84a4 145 if (level > 0)
MikamiUitOpen 0:9a78f27b84a4 146 {
MikamiUitOpen 0:9a78f27b84a4 147 level--;
MikamiUitOpen 0:9a78f27b84a4 148 wH = wH*2.0f;
MikamiUitOpen 0:9a78f27b84a4 149 hH = hH*2.0f;
MikamiUitOpen 0:9a78f27b84a4 150
MikamiUitOpen 0:9a78f27b84a4 151 ReDraw(mandel[pattern], wH, hH, xy[level], level, x1, x2, y1, y2);
MikamiUitOpen 0:9a78f27b84a4 152
MikamiUitOpen 0:9a78f27b84a4 153 if (level > 0) back.ReDraw();
MikamiUitOpen 1:27bfb11afcff 154 else back.Erase(backColor); //back.Draw(0xFFE0E0FF);
MikamiUitOpen 0:9a78f27b84a4 155 }
MikamiUitOpen 0:9a78f27b84a4 156 }
MikamiUitOpen 0:9a78f27b84a4 157 wait(0.1f);
MikamiUitOpen 0:9a78f27b84a4 158 }
MikamiUitOpen 0:9a78f27b84a4 159 }
MikamiUitOpen 1:27bfb11afcff 160