mandel_view.hpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. //
  2. // Copyright 2013 Christian Henning
  3. //
  4. // Distributed under the Boost Software License, Version 1.0
  5. // See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt
  7. //
  8. #ifndef BOOST_GIL_IO_TEST_MANDEL_HPP
  9. #define BOOST_GIL_IO_TEST_MANDEL_HPP
  10. #include <boost/gil.hpp>
  11. using namespace std;
  12. using namespace boost;
  13. using namespace gil;
  14. // Models a Unary Function
  15. template <typename P> // Models PixelValueConcept
  16. struct mandelbrot_fn
  17. {
  18. using point_t = boost::gil::point_t;
  19. using const_t = mandelbrot_fn;
  20. using value_type = P;
  21. using reference = value_type;
  22. using const_reference = value_type;
  23. using argument_type = point_t;
  24. using result_type = reference;
  25. static constexpr bool is_mutable = false;
  26. value_type _in_color,_out_color;
  27. point_t _img_size;
  28. static const int MAX_ITER=100; // max number of iterations
  29. mandelbrot_fn() {}
  30. mandelbrot_fn(const point_t& sz, const value_type& in_color, const value_type& out_color) : _in_color(in_color), _out_color(out_color), _img_size(sz) {}
  31. std::ptrdiff_t width() { return _img_size.x; }
  32. std::ptrdiff_t height() { return _img_size.y; }
  33. result_type operator()(const point_t& p) const {
  34. // normalize the coords to (-2..1, -1.5..1.5)
  35. // (actually make y -1.0..2 so it is asymmetric, so we can verify some view factory methods)
  36. double t=get_num_iter(point<double>(p.x/(double)_img_size.x*3-2, p.y/(double)_img_size.y*3-1.0f));//1.5f));
  37. t=pow(t,0.2);
  38. value_type ret;
  39. for (int k=0; k<num_channels<P>::value; ++k)
  40. ret[k]=(typename channel_type<P>::type)(_in_color[k]*t + _out_color[k]*(1-t));
  41. return ret;
  42. }
  43. private:
  44. double get_num_iter(const point<double>& p) const {
  45. point<double> Z(0,0);
  46. for (int i=0; i<MAX_ITER; ++i) {
  47. Z = point<double>(Z.x*Z.x - Z.y*Z.y + p.x, 2*Z.x*Z.y + p.y);
  48. if (Z.x*Z.x + Z.y*Z.y > 4)
  49. return i/(double)MAX_ITER;
  50. }
  51. return 0;
  52. }
  53. };
  54. template< typename Pixel >
  55. struct mandel_view
  56. {
  57. using deref_t = mandelbrot_fn<Pixel>;
  58. using locator_t= virtual_2d_locator<deref_t, false>;
  59. using my_virt_view_t = image_view<locator_t>;
  60. using type = my_virt_view_t;
  61. };
  62. template< typename Pixel >
  63. typename mandel_view< Pixel >::type create_mandel_view( unsigned int width
  64. , unsigned int height
  65. , const Pixel& in
  66. , const Pixel& out
  67. )
  68. {
  69. using view_t = typename mandel_view<Pixel>::type;
  70. using deref_t = typename mandel_view<Pixel>::deref_t;
  71. using locator_t = typename mandel_view<Pixel>::locator_t;
  72. point_t dims( width, height );
  73. return view_t( dims
  74. , locator_t( point_t( 0, 0 )
  75. , point_t( 1, 1 )
  76. , deref_t( dims
  77. , in
  78. , out
  79. )
  80. )
  81. );
  82. }
  83. #endif // BOOST_GIL_IO_TEST_MANDEL_HPP