Mandelbrot set generator using DISCO-F746NG.

Dependencies:   BSP_DISCO_F746NG LCD_DISCO_F746NG TS_DISCO_F746NG mbed BUTTON_GROUP

Committer:
MikamiUitOpen
Date:
Wed Feb 17 06:37:08 2016 +0000
Revision:
5:d8baac12f595
Parent:
4:45feeb548dfa
Child:
6:cafbcdf0d166
6

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 5:d8baac12f595 8 // 2016/02/17, Copyright (c) 2016 MIKAMI, Naoki
MikamiUitOpen 0:9a78f27b84a4 9 //---------------------------------------------------------------
MikamiUitOpen 0:9a78f27b84a4 10
MikamiUitOpen 2:6c1471e4a4b1 11 #include "button_group.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 2:6c1471e4a4b1 31 // Redrawing Mandelbrot set with different scale
MikamiUitOpen 2:6c1471e4a4b1 32 void Redraw(MandelbrotBase *mandel,
MikamiUitOpen 0:9a78f27b84a4 33 float wH, float hH, PointF xy, int level,
MikamiUitOpen 0:9a78f27b84a4 34 float &x1, float &x2, float &y1, float &y2)
MikamiUitOpen 0:9a78f27b84a4 35 {
MikamiUitOpen 0:9a78f27b84a4 36 x1 = xy.x - wH;
MikamiUitOpen 0:9a78f27b84a4 37 x2 = xy.x + wH;
MikamiUitOpen 0:9a78f27b84a4 38 y1 = xy.y - hH;
MikamiUitOpen 0:9a78f27b84a4 39 y2 = xy.y + hH;
MikamiUitOpen 0:9a78f27b84a4 40
MikamiUitOpen 0:9a78f27b84a4 41 char str[16];
MikamiUitOpen 2:6c1471e4a4b1 42 lcd_.SetTextColor(LCD_COLOR_WHITE);
MikamiUitOpen 0:9a78f27b84a4 43 sprintf(str, "factor:%6d", 1 << level);
MikamiUitOpen 0:9a78f27b84a4 44 lcd_.DisplayStringAt(360, 224, (uint8_t *)str, LEFT_MODE);
MikamiUitOpen 0:9a78f27b84a4 45 sprintf(str, "x:%8.4f", xy.x);
MikamiUitOpen 0:9a78f27b84a4 46 lcd_.DisplayStringAt(360, 240, (uint8_t *)str, LEFT_MODE);
MikamiUitOpen 0:9a78f27b84a4 47 sprintf(str, "y:%8.4f", -xy.y);
MikamiUitOpen 0:9a78f27b84a4 48 lcd_.DisplayStringAt(360, 256, (uint8_t *)str, LEFT_MODE);
MikamiUitOpen 0:9a78f27b84a4 49
MikamiUitOpen 0:9a78f27b84a4 50 mandel->Display(x1, x2, y1, y2);
MikamiUitOpen 0:9a78f27b84a4 51 }
MikamiUitOpen 0:9a78f27b84a4 52
MikamiUitOpen 0:9a78f27b84a4 53 int main()
MikamiUitOpen 0:9a78f27b84a4 54 {
MikamiUitOpen 0:9a78f27b84a4 55 const int LEVEL = 18;
MikamiUitOpen 0:9a78f27b84a4 56 PointF xy[LEVEL]; // corresponding to touched position
MikamiUitOpen 0:9a78f27b84a4 57
MikamiUitOpen 2:6c1471e4a4b1 58 uint32_t backColor = 0xFF006A6C; // teal green
MikamiUitOpen 2:6c1471e4a4b1 59 uint32_t inActive = backColor & 0xE0FFFFFF; // color for inactive button
MikamiUitOpen 0:9a78f27b84a4 60
MikamiUitOpen 0:9a78f27b84a4 61 // region to be displayed
MikamiUitOpen 0:9a78f27b84a4 62 float x1 = -2.3f;
MikamiUitOpen 0:9a78f27b84a4 63 float x2 = 0.9f;
MikamiUitOpen 0:9a78f27b84a4 64 float y1 = -1.3f;
MikamiUitOpen 0:9a78f27b84a4 65 float y2 = 1.3f;
MikamiUitOpen 0:9a78f27b84a4 66
MikamiUitOpen 0:9a78f27b84a4 67 float wH = (x2 - x1)/2.0f; // half width of region
MikamiUitOpen 0:9a78f27b84a4 68 float hH = (y2 - y1)/2.0f; // half height of region
MikamiUitOpen 0:9a78f27b84a4 69
MikamiUitOpen 0:9a78f27b84a4 70 xy[0] = PointF(x1 + wH, y1 + hH);
MikamiUitOpen 0:9a78f27b84a4 71
MikamiUitOpen 0:9a78f27b84a4 72 lcd_.Clear(backColor);
MikamiUitOpen 0:9a78f27b84a4 73
MikamiUitOpen 0:9a78f27b84a4 74 MandelbrotBase *mandel[3];
MikamiUitOpen 0:9a78f27b84a4 75 mandel[0] = new MandelbrotBW(lcd_, X0_, Y0_, NX_, NY_);
MikamiUitOpen 0:9a78f27b84a4 76 mandel[1] = new MandelbrotColor1(lcd_, X0_, Y0_, NX_, NY_);
MikamiUitOpen 0:9a78f27b84a4 77 mandel[2] = new MandelbrotColor2(lcd_, X0_, Y0_, NX_, NY_);
MikamiUitOpen 0:9a78f27b84a4 78
MikamiUitOpen 3:0be49559a8dc 79 const string strButton[3] = {"B & W", "Color1", "Color2"};
MikamiUitOpen 2:6c1471e4a4b1 80 ButtonGroup bGroup(lcd_, ts_, 340, Y0_, 60, 40,
MikamiUitOpen 2:6c1471e4a4b1 81 LCD_COLOR_BLUE, backColor,
MikamiUitOpen 2:6c1471e4a4b1 82 3, strButton, 0, 5, 1, Font12);
MikamiUitOpen 2:6c1471e4a4b1 83 Button back(lcd_, ts_, 410, Y0_, 60, 40, LCD_COLOR_BLUE, backColor, "Back", Font12);
MikamiUitOpen 2:6c1471e4a4b1 84 back.Draw(inActive, LCD_COLOR_GRAY);
MikamiUitOpen 2:6c1471e4a4b1 85
MikamiUitOpen 2:6c1471e4a4b1 86
MikamiUitOpen 0:9a78f27b84a4 87 // area of Mandelbrot set
MikamiUitOpen 2:6c1471e4a4b1 88 Button area(lcd_, ts_, X0_, Y0_, NX_, NY_, backColor, backColor);
MikamiUitOpen 0:9a78f27b84a4 89
MikamiUitOpen 2:6c1471e4a4b1 90 lcd_.SetTextColor(LCD_COLOR_WHITE);
MikamiUitOpen 0:9a78f27b84a4 91 lcd_.SetFont(&Font20);
MikamiUitOpen 0:9a78f27b84a4 92 lcd_.DisplayStringAt(60, 130, (uint8_t *)"Mandelbrot set", LEFT_MODE);
MikamiUitOpen 0:9a78f27b84a4 93
MikamiUitOpen 0:9a78f27b84a4 94 int pattern = -1;
MikamiUitOpen 0:9a78f27b84a4 95 int level = 0;
MikamiUitOpen 2:6c1471e4a4b1 96 bool first = true;
MikamiUitOpen 0:9a78f27b84a4 97 while (true)
MikamiUitOpen 0:9a78f27b84a4 98 {
MikamiUitOpen 2:6c1471e4a4b1 99 int num = -1;
MikamiUitOpen 2:6c1471e4a4b1 100 // select color pattern and display
MikamiUitOpen 2:6c1471e4a4b1 101 if (bGroup.GetTouchedNumber(num) && (pattern != num))
MikamiUitOpen 0:9a78f27b84a4 102 {
MikamiUitOpen 2:6c1471e4a4b1 103 bGroup.Draw(num, LCD_COLOR_DARKBLUE);
MikamiUitOpen 2:6c1471e4a4b1 104 mandel[num]->Display(x1, x2, y1, y2);
MikamiUitOpen 2:6c1471e4a4b1 105 pattern = num;
MikamiUitOpen 2:6c1471e4a4b1 106 bGroup.Redraw(num);
MikamiUitOpen 2:6c1471e4a4b1 107
MikamiUitOpen 2:6c1471e4a4b1 108 if (first)
MikamiUitOpen 0:9a78f27b84a4 109 {
MikamiUitOpen 0:9a78f27b84a4 110 lcd_.SetBackColor(backColor);
MikamiUitOpen 0:9a78f27b84a4 111 lcd_.SetFont(&Font12);
MikamiUitOpen 2:6c1471e4a4b1 112 lcd_.DisplayStringAt(350, LINE(15), (uint8_t *)"Tap to zoom in.",
MikamiUitOpen 0:9a78f27b84a4 113 LEFT_MODE);
MikamiUitOpen 2:6c1471e4a4b1 114 first = false;
MikamiUitOpen 2:6c1471e4a4b1 115 }
MikamiUitOpen 0:9a78f27b84a4 116 }
MikamiUitOpen 0:9a78f27b84a4 117
MikamiUitOpen 0:9a78f27b84a4 118 // expand twice around tapped point
MikamiUitOpen 0:9a78f27b84a4 119 if (area.Touched() && (pattern != -1))
MikamiUitOpen 0:9a78f27b84a4 120 {
MikamiUitOpen 0:9a78f27b84a4 121 TS_StateTypeDef state;
MikamiUitOpen 0:9a78f27b84a4 122 ts_.GetState(&state);
MikamiUitOpen 0:9a78f27b84a4 123
MikamiUitOpen 0:9a78f27b84a4 124 uint16_t x = state.touchX[0] - X0_;
MikamiUitOpen 0:9a78f27b84a4 125 uint16_t y = state.touchY[0] - Y0_;
MikamiUitOpen 0:9a78f27b84a4 126
MikamiUitOpen 0:9a78f27b84a4 127 lcd_.SetBackColor(backColor);
MikamiUitOpen 0:9a78f27b84a4 128 if (++level < LEVEL)
MikamiUitOpen 0:9a78f27b84a4 129 {
MikamiUitOpen 0:9a78f27b84a4 130 xy[level] = PointF(mandel[pattern]->Fx(x), mandel[pattern]->Fy(y));
MikamiUitOpen 0:9a78f27b84a4 131 wH = wH/2.0f;
MikamiUitOpen 0:9a78f27b84a4 132 hH = hH/2.0f;
MikamiUitOpen 0:9a78f27b84a4 133
MikamiUitOpen 2:6c1471e4a4b1 134 Redraw(mandel[pattern], wH, hH, xy[level], level, x1, x2, y1, y2);
MikamiUitOpen 0:9a78f27b84a4 135 }
MikamiUitOpen 0:9a78f27b84a4 136 else
MikamiUitOpen 0:9a78f27b84a4 137 {
MikamiUitOpen 0:9a78f27b84a4 138 lcd_.SetFont(&Font20);
MikamiUitOpen 0:9a78f27b84a4 139 lcd_.DisplayStringAt(X0_+38, 130, (uint8_t *)" No more expand! ",
MikamiUitOpen 0:9a78f27b84a4 140 LEFT_MODE);
MikamiUitOpen 0:9a78f27b84a4 141 level = LEVEL - 1 ;
MikamiUitOpen 0:9a78f27b84a4 142 }
MikamiUitOpen 2:6c1471e4a4b1 143 back.Redraw();
MikamiUitOpen 0:9a78f27b84a4 144 }
MikamiUitOpen 0:9a78f27b84a4 145
MikamiUitOpen 4:45feeb548dfa 146 // "Back" button tapped
MikamiUitOpen 0:9a78f27b84a4 147 if (back.Touched() && level > 0)
MikamiUitOpen 0:9a78f27b84a4 148 {
MikamiUitOpen 0:9a78f27b84a4 149 back.Draw(LCD_COLOR_DARKBLUE);
MikamiUitOpen 0:9a78f27b84a4 150 lcd_.SetBackColor(backColor);
MikamiUitOpen 0:9a78f27b84a4 151 if (level > 0)
MikamiUitOpen 0:9a78f27b84a4 152 {
MikamiUitOpen 0:9a78f27b84a4 153 level--;
MikamiUitOpen 0:9a78f27b84a4 154 wH = wH*2.0f;
MikamiUitOpen 0:9a78f27b84a4 155 hH = hH*2.0f;
MikamiUitOpen 0:9a78f27b84a4 156
MikamiUitOpen 2:6c1471e4a4b1 157 Redraw(mandel[pattern], wH, hH, xy[level], level, x1, x2, y1, y2);
MikamiUitOpen 2:6c1471e4a4b1 158 if (level > 0) back.Redraw();
MikamiUitOpen 2:6c1471e4a4b1 159 else
MikamiUitOpen 2:6c1471e4a4b1 160 back.Draw(inActive, LCD_COLOR_GRAY);
MikamiUitOpen 0:9a78f27b84a4 161 }
MikamiUitOpen 0:9a78f27b84a4 162 }
MikamiUitOpen 0:9a78f27b84a4 163 wait(0.1f);
MikamiUitOpen 0:9a78f27b84a4 164 }
MikamiUitOpen 0:9a78f27b84a4 165 }