ASPiK SDK
mandelbrot.h
1 // This file is part of VSTGUI. It is subject to the license terms
2 // in the LICENSE file found in the top-level directory of this
3 // distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
4 
5 #include "vstgui/lib/cpoint.h"
6 #include "vstgui/lib/dispatchlist.h"
7 #include <complex>
8 #include <iostream>
9 #include <memory>
10 
11 //------------------------------------------------------------------------
12 namespace Mandelbrot {
13 
14 using Point = VSTGUI::CPoint;
15 using Complex = std::complex<double>;
16 struct Model;
17 
18 //------------------------------------------------------------------------
20 {
21  virtual void modelChanged (const Model& model) = 0;
22 };
23 
24 //------------------------------------------------------------------------
25 struct Model
26 {
27  using Ptr = std::shared_ptr<Model>;
28 
29  void registerListener (IModelChangeListener* listener) { listeners.add (listener); }
30  void unregisterListener (IModelChangeListener* listener) { listeners.remove (listener); }
31 
32  const Point& getMax () const { return max; }
33  const Point& getMin () const { return min; }
34  uint32_t getIterations () const { return iterations; }
35 
36  void setIterations (uint32_t newIterations)
37  {
38  if (newIterations != iterations)
39  {
40  iterations = newIterations;
41  changed ();
42  }
43  }
44 
45  void setMinMax (Point newMin, Point newMax)
46  {
47  if (max == newMax && min == newMin)
48  return;
49  max = newMax;
50  min = newMin;
51  changed ();
52  }
53 
54 private:
55  void changed ()
56  {
57  listeners.forEach ([this] (auto& l) { l->modelChanged (*this); });
58  }
60 
61  Point max {1.2, 1.7};
62  Point min {-2.2, -1.7};
63  uint32_t iterations {50};
64 };
65 
66 //------------------------------------------------------------------------
67 inline Point pixelToPoint (Point max, Point min, Point size, Point pixel)
68 {
69  Point p;
70  p.x = min.x + pixel.x / (size.x - 1.0) * (max.x - min.x);
71  p.y = min.y + pixel.y / (size.y - 1.0) * (max.y - min.y);
72  return p;
73 }
74 
75 //------------------------------------------------------------------------
76 inline double hypot (double x, double y)
77 {
78  return std::sqrt (x * x + y * y);
79 }
80 
81 //------------------------------------------------------------------------
82 inline Complex mulAdd (Complex z, Complex w, Complex v)
83 {
84  auto a = z.real ();
85  auto b = z.imag ();
86  auto c = w.real ();
87  auto d = w.imag ();
88  auto ac = a * c;
89  auto bd = b * d;
90  auto ad = a * d;
91  auto bc = b * c;
92  auto x = ac - bd;
93  auto y = ad + bc;
94  return Complex (x + v.real (), y + v.imag ());
95 }
96 
97 //------------------------------------------------------------------------
98 template <typename SetPixelProc>
99 inline void calculateLine (uint32_t line, Point size, const Model& model, SetPixelProc setPixel)
100 {
101  Point sizeInv (size);
102  sizeInv -= {1, 1};
103  sizeInv.x = 1. / sizeInv.x;
104  sizeInv.y = 1. / sizeInv.y;
105  Point diff;
106  diff.x = model.getMax ().x - model.getMin ().x;
107  diff.y = model.getMax ().y - model.getMin ().y;
108  Point pos;
109  pos.y = model.getMin ().y + line * sizeInv.y * diff.y;
110  std::vector<uint32_t> iterationResult (size.x);
111  for (auto x = 0u; x < size.x; ++x)
112  {
113  pos.x = model.getMin ().x + x * sizeInv.x * diff.x;
114  Complex c {pos.x, pos.y};
115  Complex z {0};
116  uint32_t iterations {};
117 
118  for (; iterations < model.getIterations () && hypot (z.real (), z.imag ()) < 2.0;
119  ++iterations)
120  z = mulAdd (z, z, c);
121  iterationResult[x] = iterations;
122  }
123  for (auto x = 0u; x < size.x; ++x)
124  setPixel (x, iterationResult[x]);
125 }
126 
127 //------------------------------------------------------------------------
128 template <typename SetPixelProc>
129 inline void calculate (Point size, const Model& model, SetPixelProc setPixel)
130 {
131  for (auto y = 0u; y < size.y; ++y)
132  {
133  calculateLine (y, size, model, setPixel);
134  }
135 }
136 
137 //------------------------------------------------------------------------
138 } // Mandelbrot
Definition: mandelbrot.h:19
Definition: dispatchlist.h:14
Definition: mandelbrot.h:25
Point structure.
Definition: cpoint.h:17
Definition: mandelbrot.h:12