OGLplus (0.52.0) a C++ wrapper for OpenGL

newton.hpp
Go to the documentation of this file.
1 
12 #pragma once
13 #ifndef OGLPLUS_IMAGES_NEWTON_1107121519_HPP
14 #define OGLPLUS_IMAGES_NEWTON_1107121519_HPP
15 
16 #include <oglplus/images/image.hpp>
17 #include <oglplus/math/vector.hpp>
18 
19 #include <cassert>
20 
21 namespace oglplus {
22 namespace images {
23 
25 
46  : public Image
47 {
48 private:
49  // complex number division
50  static Vec2f _cdiv(Vec2f a, Vec2f b)
51  {
52  float d = Dot(b, b);
53  if(d == 0.0f) return a;
54  else return Vec2f(
55  (a.x()*b.x() + a.y()*b.y()) / d,
56  (a.y()*b.x() - a.x()*b.y()) / d
57  );
58  }
59 
60  template <typename T>
61  static T _mix(T a, T b, float coef)
62  {
63  return a*(1.0f - coef) + b*coef;
64  }
65 
66  template <typename Function, typename Mixer, std::size_t N>
67  void _make(
68  GLsizei width,
69  GLsizei height,
70  Function,
71  Mixer mixer,
72  Vec2f lb,
73  Vec2f rt,
76  )
77  {
78  auto p = this->_begin<GLfloat>();
79 
80  for(GLsizei i=0; i!=width; ++i)
81  for(GLsizei j=0; j!=height; ++j)
82  {
83  Vec2f z(
84  _mix(lb.x(), rt.x(), float(i)/float(width-1)),
85  _mix(lb.y(), rt.y(), float(j)/float(height-1))
86  );
87  std::size_t n, max = 256;
88  for(n = 0; n != max; ++n)
89  {
90  Vec2f zn = z - _cdiv(
91  Function::f(z),
92  Function::df(z)
93  );
94  if(Distance(zn, z) < 0.00001f) break;
95  z = zn;
96  }
97  Vector<float, N> c = _mix(
98  c1,
99  c2,
100  mixer(float(n) / float(max-1))
101  );
102  for(n=0; n!=N; ++n)
103  {
104  assert(p != this->_end<GLfloat>());
105  *p = c.At(n);
106  ++p;
107  }
108  }
109  assert(p == this->_end<GLfloat>());
110  }
111 public:
113  struct X3Minus1
114  {
115  static Vec2f f(Vec2f n)
116  {
117  return Vec2f(
118  n.x()*n.x()*n.x() - 3.f*n.x()*n.y()*n.y() - 1.f,
119  -n.y()*n.y()*n.y() + 3.f*n.x()*n.x()*n.y()
120  );
121  }
122 
123  static Vec2f df(Vec2f n)
124  {
125  return 3.0f * Vec2f(
126  n.x()*n.x() - n.y()*n.y(),
127  2.0 * n.x() * n.y()
128  );
129  }
130  };
131 
133  struct X4Minus1
134  {
135  static Vec2f f(Vec2f n)
136  {
137  return Vec2f(
138  n.x()*n.x()*n.x()*n.x() +
139  n.y()*n.y()*n.y()*n.y() -
140  6.f*n.x()*n.x()*n.y()*n.y() - 1.f,
141  4.f*n.x()*n.x()*n.x()*n.y() -
142  4.f*n.x()*n.y()*n.y()*n.y()
143  );
144  }
145 
146  static Vec2f df(Vec2f n)
147  {
148  return 4.0f * Vec2f(
149  n.x()*n.x()*n.x() - 3.f*n.x()*n.y()*n.y(),
150  -n.y()*n.y()*n.y() + 3.f*n.x()*n.x()*n.y()
151  );
152  }
153  };
154 
155  typedef X3Minus1 DefaultFunction;
156 
157  struct NoopMixer
158  {
159  template <typename T>
160  T operator()(T value) const
161  {
162  return value;
163  }
164  };
165 
166  struct PowMixer
167  {
168  float _exponent;
169 
170  PowMixer(float exponent)
171  : _exponent(exponent)
172  { }
173 
174  template <typename T>
175  T operator()(T value) const
176  {
177  return std::pow(value, T(_exponent));
178  }
179  };
180 
181  typedef NoopMixer DefaultMixer;
182 
183 #if OGLPLUS_DOCUMENTATION_ONLY || !OGLPLUS_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS
184 
201  template <
202  typename Function = DefaultFunction,
203  typename Mixer = DefaultMixer
204  >
206  GLsizei width,
207  GLsizei height,
208  Vec3f c1,
209  Vec3f c2,
210  Vec2f lb = Vec2f(-1.0f, -1.0f),
211  Vec2f rt = Vec2f( 1.0f, 1.0f),
212  Function func = Function(),
213  Mixer mixer = Mixer()
214  ): Image(width, height, 1, 3, (GLfloat*)0)
215  {
216  _make(width, height, func, mixer, lb, rt, c1, c2);
217  }
218 
220 
228  template <
229  typename Function = DefaultFunction,
230  typename Mixer = DefaultMixer
231  >
233  GLsizei width,
234  GLsizei height,
235  Function func = Function(),
236  Mixer mixer = Mixer()
237  ): Image(width, height, 1, 1, (GLfloat*)0)
238  {
239  _make(
240  width, height,
241  func,
242  mixer,
243  Vec2f(-1.0f, -1.0f), Vec2f(1.0f, 1.0f),
244  Vec1f(0.0f), Vec1f(1.0f)
245  );
246  }
247 #else
248  template <typename Function, typename Mixer>
250  GLsizei width,
251  GLsizei height,
252  Vec3f c1,
253  Vec3f c2,
254  Vec2f lb,
255  Vec2f rt,
256  Function func,
257  Mixer mixer
258  ): Image(width, height, 1, 3, (GLfloat*)0)
259  {
260  _make(width, height, func, mixer, lb, rt, c1, c2);
261  }
262 
263  template <typename Function, typename Mixer>
265  GLsizei width,
266  GLsizei height,
267  Function func,
268  Mixer mixer
269  ): Image(width, height, 1, 1, (GLfloat*)0)
270  {
271  _make(
272  width, height,
273  func,
274  mixer,
275  Vec2f(-1.0f, -1.0f), Vec2f(1.0f, 1.0f),
276  Vec1f(0.0f), Vec1f(1.0f)
277  );
278  }
279 #endif
280 };
281 
282 } // images
283 } // oglplus
284 
285 #endif // include guard
The X^4-1 function and its derivation.
Definition: newton.hpp:133
NewtonFractal(GLsizei width, GLsizei height, Vec3f c1, Vec3f c2, Vec2f lb=Vec2f(-1.0f,-1.0f), Vec2f rt=Vec2f(1.0f, 1.0f), Function func=Function(), Mixer mixer=Mixer())
Creates a RGB texture using c1 and c2 for colorizing of the fractal.
Definition: newton.hpp:205
Vector< GLfloat, 2 > Vec2f
2D float vector
Definition: vector.hpp:73
T At(const Vector &vector, std::size_t i) const T x(void) const
Returns the value of the i-th coordinate of the vector.
Definition: vector.hpp:221
NewtonFractal(GLsizei width, GLsizei height, Function func=Function(), Mixer mixer=Mixer())
Creates a Red texture colorized from black to red.
Definition: newton.hpp:232
T y(void) const
Returns the 1-st component.
Definition: vector.hpp:231
A generator of Newton fractal 2D images.
Definition: newton.hpp:45
Wrapper for (texture) image data.
Definition: image.hpp:45
Basic template for vector types.
Definition: fwd.hpp:43
The X^3-1 function and its derivation.
Definition: newton.hpp:113
A vector class.
Vector< GLfloat, 1 > Vec1f
1D float (degenerate) vector
Definition: vector.hpp:67
Image data wrapper.

Copyright © 2010-2014 Matúš Chochlík, University of Žilina, Žilina, Slovakia.
<matus.chochlik -at- fri.uniza.sk>
<chochlik -at -gmail.com>
Documentation generated on Mon Sep 22 2014 by Doxygen (version 1.8.6).