Mandelbrot set generator using DISCO-F746NG.

Dependencies:   BSP_DISCO_F746NG LCD_DISCO_F746NG TS_DISCO_F746NG mbed BUTTON_GROUP

Committer:
MikamiUitOpen
Date:
Mon Feb 22 13:51:42 2016 +0000
Revision:
6:cafbcdf0d166
Parent:
5:d8baac12f595
7

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