TP fractalTP fractal..
[GPU.git] / WCudaMSE / Student_Cuda_Image / src / cpp / core / 02_Mandelbrot_Julia / moo / device / math / FractalMath.h
index 2bd56ae..aff0b79 100755 (executable)
@@ -6,32 +6,20 @@
 #include "CalibreurF.h"\r
 #include "ColorTools.h"\r
 \r
-/*----------------------------------------------------------------------*\\r
- |*                    Declaration                                     *|\r
- \*---------------------------------------------------------------------*/\r
-\r
-/*--------------------------------------*\\r
- |*            Public                  *|\r
- \*-------------------------------------*/\r
-\r
 class FractalMath\r
     {\r
-\r
-       /*--------------------------------------*\\r
-       |*              Constructor             *|\r
-        \*-------------------------------------*/\r
-\r
     public:\r
-\r
+       /**\r
+        * n: le nombre maximum d'iterations afin de savoir si Zi diverge ou non.\r
+        */\r
        __device__\r
        FractalMath(int n)\r
-           : n(n), calibreur(IntervalF(-1, 1), IntervalF(0, 1))\r
+           : n(n), calibreur(IntervalF(1, n), IntervalF(0, 1))\r
            {\r
            }\r
 \r
-       /*--------------------------------------*\\r
-       |*              Methodes                *|\r
-        \*-------------------------------------*/\r
+       __device__\r
+       virtual ~FractalMath() {}\r
 \r
     public:\r
        /**\r
@@ -39,40 +27,115 @@ class FractalMath
         * y=pixelJ\r
         */\r
        __device__\r
-       void colorXY(uchar4* ptrColor, float x, float y, float t)\r
+       void colorXY(uchar4* ptrColor, float x, float y) const\r
            {\r
-           float z = f(x, y, t);\r
-\r
-           calibreur.calibrer(z);\r
-           float hue01 = z;\r
-\r
-           ColorTools::HSB_TO_RVB(hue01, ptrColor); // update color\r
-\r
-           ptrColor->w = 255; // opaque\r
+           // Z courant.\r
+           float z_r, z_i;\r
+           this->initZ(z_r, z_i, x, y);\r
+\r
+           int i = 0;\r
+           while (i < this->n)\r
+                {\r
+                i++;\r
+\r
+                nextZ(z_r, z_i, x, y);\r
+\r
+                if (isDivergent(z_r, z_i))\r
+                    break;\r
+                }\r
+\r
+            if (i == this->n)\r
+                {\r
+                ptrColor->x = 0;\r
+                ptrColor->y = 0;\r
+                ptrColor->z = 0;\r
+                }\r
+            else\r
+                {\r
+                float s = static_cast<float>(i);\r
+                this->calibreur.calibrer(s);\r
+                ColorTools::HSB_TO_RVB(s, ptrColor);\r
+                }\r
            }\r
 \r
     private:\r
        __device__\r
-       float f(float x, float y,float t)\r
+       static bool isDivergent(float a, float b)\r
            {\r
-           return sin(x * n + t) * cos(y * n + t);\r
+           return pow(a, 2) + pow(b, 2) > 4;\r
            }\r
 \r
+       __device__\r
+       virtual void initZ(float& z_r, float& z_i, float x, float y) const = 0;\r
 \r
-       /*--------------------------------------*\\r
-       |*              Attributs               *|\r
-        \*-------------------------------------*/\r
+       __device__\r
+       virtual void nextZ(float& z_r, float& z_i, float x, float y) const = 0;\r
 \r
     private:\r
-       // Input\r
        int n;\r
-\r
-       // Tools\r
        CalibreurF calibreur;\r
     };\r
 \r
-#endif\r
+class FractalMandelbrotMath : public FractalMath\r
+    {\r
+    public:\r
+        /**\r
+         * n: le nombre maximum d'iterations afin de savoir si Zi diverge ou non.\r
+         */\r
+        __device__\r
+        FractalMandelbrotMath(int n)\r
+            : FractalMath(n)\r
+            {\r
+            }\r
 \r
-/*----------------------------------------------------------------------*\\r
- |*                    End                                             *|\r
- \*---------------------------------------------------------------------*/\r
+    private:\r
+        __device__\r
+        void initZ(float& z_r, float& z_i, float, float) const\r
+            {\r
+            z_r = 0.0;\r
+            z_i = 0.0;\r
+            }\r
+\r
+        __device__\r
+        void nextZ(float& z_r, float& z_i, float x, float y) const\r
+            {\r
+            // Z^2 + (x, iy) :\r
+            float z_r_tmp = pow(z_r, 2) - pow(z_i, 2);\r
+            z_i = 2 * z_r * z_i + y;\r
+            z_r = z_r_tmp + x;\r
+            }\r
+    };\r
+\r
+class FractalJuliaMath : public FractalMath\r
+    {\r
+    public:\r
+        /**\r
+         * n: le nombre maximum d'iterations afin de savoir si Zi diverge ou non.\r
+         */\r
+        __device__\r
+        FractalJuliaMath(int n, float c_r, float c_i)\r
+            : FractalMath(n), c_r(c_r), c_i(c_i)\r
+            {\r
+            }\r
+\r
+    private:\r
+        __device__\r
+        void initZ(float& z_r, float& z_i, float x, float y) const\r
+            {\r
+            z_r = x;\r
+            z_i = y;\r
+            }\r
+\r
+        __device__\r
+        void nextZ(float& z_r, float& z_i, float, float) const\r
+            {\r
+            // Z^2 + C :\r
+            float z_r_tmp = pow(z_r, 2) - pow(z_i, 2);\r
+            z_i = 2 * z_r * z_i + this->c_i;\r
+            z_r = z_r_tmp + this->c_r;\r
+            }\r
+\r
+        float c_r, c_i;\r
+    };\r
+\r
+#endif\r