TP fractalTP fractal..
[GPU.git] / WCudaMSE / Student_Cuda_Image / src / cpp / core / 02_Mandelbrot_Julia / moo / device / math / FractalMath.h
1 #ifndef FRACTAL_MATH_H_
2 #define FRACTAL_MATH_H_
3
4 #include <cmath>
5
6 #include "CalibreurF.h"
7 #include "ColorTools.h"
8
9 class FractalMath
10 {
11 public:
12 /**
13 * n: le nombre maximum d'iterations afin de savoir si Zi diverge ou non.
14 */
15 __device__
16 FractalMath(int n)
17 : n(n), calibreur(IntervalF(1, n), IntervalF(0, 1))
18 {
19 }
20
21 __device__
22 virtual ~FractalMath() {}
23
24 public:
25 /**
26 * x=pixelI
27 * y=pixelJ
28 */
29 __device__
30 void colorXY(uchar4* ptrColor, float x, float y) const
31 {
32 // Z courant.
33 float z_r, z_i;
34 this->initZ(z_r, z_i, x, y);
35
36 int i = 0;
37 while (i < this->n)
38 {
39 i++;
40
41 nextZ(z_r, z_i, x, y);
42
43 if (isDivergent(z_r, z_i))
44 break;
45 }
46
47 if (i == this->n)
48 {
49 ptrColor->x = 0;
50 ptrColor->y = 0;
51 ptrColor->z = 0;
52 }
53 else
54 {
55 float s = static_cast<float>(i);
56 this->calibreur.calibrer(s);
57 ColorTools::HSB_TO_RVB(s, ptrColor);
58 }
59 }
60
61 private:
62 __device__
63 static bool isDivergent(float a, float b)
64 {
65 return pow(a, 2) + pow(b, 2) > 4;
66 }
67
68 __device__
69 virtual void initZ(float& z_r, float& z_i, float x, float y) const = 0;
70
71 __device__
72 virtual void nextZ(float& z_r, float& z_i, float x, float y) const = 0;
73
74 private:
75 int n;
76 CalibreurF calibreur;
77 };
78
79 class FractalMandelbrotMath : public FractalMath
80 {
81 public:
82 /**
83 * n: le nombre maximum d'iterations afin de savoir si Zi diverge ou non.
84 */
85 __device__
86 FractalMandelbrotMath(int n)
87 : FractalMath(n)
88 {
89 }
90
91 private:
92 __device__
93 void initZ(float& z_r, float& z_i, float, float) const
94 {
95 z_r = 0.0;
96 z_i = 0.0;
97 }
98
99 __device__
100 void nextZ(float& z_r, float& z_i, float x, float y) const
101 {
102 // Z^2 + (x, iy) :
103 float z_r_tmp = pow(z_r, 2) - pow(z_i, 2);
104 z_i = 2 * z_r * z_i + y;
105 z_r = z_r_tmp + x;
106 }
107 };
108
109 class FractalJuliaMath : public FractalMath
110 {
111 public:
112 /**
113 * n: le nombre maximum d'iterations afin de savoir si Zi diverge ou non.
114 */
115 __device__
116 FractalJuliaMath(int n, float c_r, float c_i)
117 : FractalMath(n), c_r(c_r), c_i(c_i)
118 {
119 }
120
121 private:
122 __device__
123 void initZ(float& z_r, float& z_i, float x, float y) const
124 {
125 z_r = x;
126 z_i = y;
127 }
128
129 __device__
130 void nextZ(float& z_r, float& z_i, float, float) const
131 {
132 // Z^2 + C :
133 float z_r_tmp = pow(z_r, 2) - pow(z_i, 2);
134 z_i = 2 * z_r * z_i + this->c_i;
135 z_r = z_r_tmp + this->c_r;
136 }
137
138 float c_r, c_i;
139 };
140
141 #endif