From 2d95edd9a2d09421e5eae56755bdf3105e12edf7 Mon Sep 17 00:00:00 2001 From: gburri Date: Sat, 6 Dec 2014 18:36:42 +0100 Subject: [PATCH] Newton, work in progress. --- .../provider/FractalProvider.cpp | 49 +------ .../provider/FractalProvider.h | 26 ++-- .../core/03_Newton/moo/device/NewtonDevice.cu | 11 +- .../03_Newton/moo/device/math/NewtonMath.h | 138 +++++++++++++++--- .../src/cpp/core/03_Newton/moo/host/Newton.cu | 8 +- .../src/cpp/core/mainGL.cpp | 56 +++---- 6 files changed, 163 insertions(+), 125 deletions(-) diff --git a/WCudaMSE/Student_Cuda_Image/src/cpp/core/02_Mandelbrot_Julia/provider/FractalProvider.cpp b/WCudaMSE/Student_Cuda_Image/src/cpp/core/02_Mandelbrot_Julia/provider/FractalProvider.cpp index 47df25e..5282d85 100755 --- a/WCudaMSE/Student_Cuda_Image/src/cpp/core/02_Mandelbrot_Julia/provider/FractalProvider.cpp +++ b/WCudaMSE/Student_Cuda_Image/src/cpp/core/02_Mandelbrot_Julia/provider/FractalProvider.cpp @@ -1,35 +1,6 @@ #include "FractalProvider.h" - -/*----------------------------------------------------------------------*\ - |* Declaration *| - \*---------------------------------------------------------------------*/ - -/*--------------------------------------*\ - |* Imported *| - \*-------------------------------------*/ - -/*--------------------------------------*\ - |* Public *| - \*-------------------------------------*/ - -/*--------------------------------------*\ - |* Private *| - \*-------------------------------------*/ - -/*----------------------------------------------------------------------*\ - |* Implementation *| - \*---------------------------------------------------------------------*/ - -/*--------------------------------------*\ - |* Public *| - \*-------------------------------------*/ - -/*-----------------*\ - |* static *| - \*----------------*/ - -Fractal* FractalProvider::createMandelbrot() +Fractal* MandelbrotProvider::create() { int dw = 16 * 50; int dh = 16 * 30; @@ -37,7 +8,7 @@ Fractal* FractalProvider::createMandelbrot() return new FractalMandelbrot(dw, dh, 0.2); } -Fractal* FractalProvider::createJulia() +Fractal* JuliaProvider::create() { int dw = 16 * 50; int dh = 16 * 30; @@ -45,23 +16,15 @@ Fractal* FractalProvider::createJulia() return new FractalJulia(dw, dh, 0.01, -0.745, -0.32, -0.09, 0.1); } -ImageFonctionel* FractalProvider::createMandelbrotGL() +ImageFonctionel* MandelbrotProvider::createGL() { ColorRGB_01* ptrColorTitre = new ColorRGB_01(0, 0, 0); - return new ImageFonctionel(createMandelbrot(), ptrColorTitre); // both ptr destroy by destructor of ImageFonctionel + return new ImageFonctionel(create(), ptrColorTitre); // both ptr destroy by destructor of ImageFonctionel } -ImageFonctionel* FractalProvider::createJuliaGL() +ImageFonctionel* JuliaProvider::createGL() { ColorRGB_01* ptrColorTitre = new ColorRGB_01(0, 0, 0); - return new ImageFonctionel(createJulia(), ptrColorTitre); // both ptr destroy by destructor of ImageFonctionel + return new ImageFonctionel(create(), ptrColorTitre); // both ptr destroy by destructor of ImageFonctionel } - -/*--------------------------------------*\ - |* Private *| - \*-------------------------------------*/ - -/*----------------------------------------------------------------------*\ - |* End *| - \*---------------------------------------------------------------------*/ diff --git a/WCudaMSE/Student_Cuda_Image/src/cpp/core/02_Mandelbrot_Julia/provider/FractalProvider.h b/WCudaMSE/Student_Cuda_Image/src/cpp/core/02_Mandelbrot_Julia/provider/FractalProvider.h index 27bd73e..eca7b3c 100755 --- a/WCudaMSE/Student_Cuda_Image/src/cpp/core/02_Mandelbrot_Julia/provider/FractalProvider.h +++ b/WCudaMSE/Student_Cuda_Image/src/cpp/core/02_Mandelbrot_Julia/provider/FractalProvider.h @@ -4,27 +4,19 @@ #include "Fractal.h" #include "ImageFonctionel.h" -/*----------------------------------------------------------------------*\ - |* Declaration *| - \*---------------------------------------------------------------------*/ +class MandelbrotProvider + { + public: + static Fractal* create(); + static ImageFonctionel* createGL(); + }; -/*--------------------------------------*\ - |* Public *| - \*-------------------------------------*/ -class FractalProvider +class JuliaProvider { public: - static Fractal* createMandelbrot(); - static Fractal* createJulia(); - - static ImageFonctionel* createMandelbrotGL(); - static ImageFonctionel* createJuliaGL(); + static Fractal* create(); + static ImageFonctionel* createGL(); }; #endif - -/*----------------------------------------------------------------------*\ - |* End *| - \*---------------------------------------------------------------------*/ - diff --git a/WCudaMSE/Student_Cuda_Image/src/cpp/core/03_Newton/moo/device/NewtonDevice.cu b/WCudaMSE/Student_Cuda_Image/src/cpp/core/03_Newton/moo/device/NewtonDevice.cu index 536b75b..3399d92 100755 --- a/WCudaMSE/Student_Cuda_Image/src/cpp/core/03_Newton/moo/device/NewtonDevice.cu +++ b/WCudaMSE/Student_Cuda_Image/src/cpp/core/03_Newton/moo/device/NewtonDevice.cu @@ -1,4 +1,6 @@ #include +#include +using namespace std; #include "Indice2D.h" #include "IndiceTools.h" @@ -8,9 +10,6 @@ #include "NewtonMath.h" -using std::cout; -using std::endl; - __global__ void newton(uchar4* ptrDevPixels, int w, int h, DomaineMath domaineMath) { const int TID = Indice2D::tid(); @@ -20,7 +19,7 @@ __global__ void newton(uchar4* ptrDevPixels, int w, int h, DomaineMath domaineMa NewtonMath newtonMath; uchar4 color; - color.z = 255; // Par défaut, l'image est opaque. + color.w = 255; // Par défaut, l'image est opaque. double x, y; int pixelI, pixelJ; @@ -30,8 +29,8 @@ __global__ void newton(uchar4* ptrDevPixels, int w, int h, DomaineMath domaineMa { IndiceTools::toIJ(s, w, &pixelI, &pixelJ); // update (pixelI, pixelJ) - // (i,j) domaine ecran - // (x,y) domaine math + // (i,j) domaine écran. + // (x,y) domaine math. domaineMath.toXY(pixelI, pixelJ, &x, &y); // (i,j) -> (x,y) newtonMath.colorXY(&color, x, y); diff --git a/WCudaMSE/Student_Cuda_Image/src/cpp/core/03_Newton/moo/device/math/NewtonMath.h b/WCudaMSE/Student_Cuda_Image/src/cpp/core/03_Newton/moo/device/math/NewtonMath.h index 5edf6ee..3c76170 100755 --- a/WCudaMSE/Student_Cuda_Image/src/cpp/core/03_Newton/moo/device/math/NewtonMath.h +++ b/WCudaMSE/Student_Cuda_Image/src/cpp/core/03_Newton/moo/device/math/NewtonMath.h @@ -2,44 +2,142 @@ #define NEWTON_MATH_H_ #include +#include +#include -#include "CalibreurF.h" #include "ColorTools.h" class NewtonMath { + enum Solution { + A, // (1 0) + B, // (-1/2 sqrt(3)/2) + C // (-1/2 -sqrt(3)/2) + }; + + /* + * Renvoie la valeur (x1, x2) de l'itération suivante (i+1). + */ + __device__ + static void nextX(float x1, float x2, float& x1_next, float& x2_next) + { + float f_x1 = powf(x1, 3.0) - 3.0 * x1 * powf(x2, 2.0) - 1.0; + float f_x2 = powf(x2, 3.0) - 3.0 * powf(x1, 2.0) * x2; + + // La matrice est représentée comme cela : + // a b + // c d + float jacobienne_f_x_a = 3.0 * powf(x1, 2.0) - 3.0 * powf(x2, 2.0); + float jacobienne_f_x_b = -6.0 * x1 * x2; + float jacobienne_f_x_c = -6.0 * x1 * x2; + float jacobienne_f_x_d = -3.0 * powf(x1, 2.0) + 3.0 * powf(x2, 2.0); + + float det_inverse_jacobienne = 1.0 / (jacobienne_f_x_a * jacobienne_f_x_d - jacobienne_f_x_b * jacobienne_f_x_c); + float jacobienne_f_x_a_inverse = jacobienne_f_x_d * det_inverse_jacobienne; + float jacobienne_f_x_b_inverse = -jacobienne_f_x_b * det_inverse_jacobienne; + float jacobienne_f_x_c_inverse = -jacobienne_f_x_c * det_inverse_jacobienne; + float jacobienne_f_x_d_inverse = jacobienne_f_x_a * det_inverse_jacobienne; + + x1_next = x1 - (jacobienne_f_x_a_inverse * f_x1 + jacobienne_f_x_b_inverse * f_x2); + x2_next = x2 - (jacobienne_f_x_c_inverse * f_x1 + jacobienne_f_x_d_inverse * f_x2); + } + + /* + * Renvoie la distance entre deux vecteurs a et b. + */ + __device__ + static float distance_carre(float a1, float a2, float b1, float b2) + { + return powf(a1 - b1, 2.0) + powf(a2 - b2, 2.0); + } + + __device__ + static float distance(float a1, float a2, float b1, float b2) + { + return (powf(a1 - b1, 2.0) + powf(a2 - b2, 2.0)) / (powf(b1, 2.0) + powf(b2, 2.0)); + } + public: + /* + * n est le nombre d'iteration. + */ __device__ - NewtonMath() - : calibreur(IntervalF(1, 100), IntervalF(0, 1)) + NewtonMath(int n = 1000) + : n(n) { } __device__ virtual ~NewtonMath() {} - public: - /** - * x=pixelI - * y=pixelJ - */ __device__ - void colorXY(uchar4* ptrColor, float x, float y) const + void colorXY(uchar4* ptrColor, float x1, float x2) const { - ptrColor->x = 0; - ptrColor->y = 0; - ptrColor->z = 0; - - int i = 0; - float s = static_cast(i); - this->calibreur.calibrer(s); - ColorTools::HSB_TO_RVB(s, ptrColor); - } + const float A1 = 1.0; + const float A2 = 0.0; + const float B1 = -1.0 / 2.0; + const float B2 = sqrt(3.0) / 2.0; + const float C1 = -1.0 / 2.0; + const float C2 = -sqrt(3.0) / 2.0; - private: + const float epsilon = 0.001; + + float nearest_current_solution_distance = FLT_MAX; + Solution nearest_current_solution = A; + + for (int i = 0; i < this->n; i++) + { + float distance_to_A = distance(x1, x2, A1, A2); + float distance_to_B = distance(x1, x2, B1, B2); + float distance_to_C = distance(x1, x2, C1, C2); + + if (distance_to_A < nearest_current_solution_distance && distance_to_A < distance_to_B && distance_to_A < distance_to_C) + { + nearest_current_solution = A; + nearest_current_solution_distance = distance_to_A; + } + else if (distance_to_B < nearest_current_solution_distance && distance_to_B < distance_to_A && distance_to_B < distance_to_C) + { + nearest_current_solution = B; + nearest_current_solution_distance = distance_to_B; + } + else if (distance_to_C < nearest_current_solution_distance && distance_to_C < distance_to_A && distance_to_C < distance_to_B) + { + nearest_current_solution = C; + nearest_current_solution_distance = distance_to_C; + } + + if (nearest_current_solution_distance < epsilon) + break; + + nextX(x1, x2, x1, x2); + } + + switch (nearest_current_solution) + { + // Noir. + case A : + ptrColor->x = 0; + ptrColor->y = 0; + ptrColor->z = 0; + break; + // Gris. + case B : + ptrColor->x = 128; + ptrColor->y = 128; + ptrColor->z = 128; + break; + // Blanc. + case C : + ptrColor->x = 255; + ptrColor->y = 255; + ptrColor->z = 255; + break; + } + } private: - CalibreurF calibreur; + int n; }; #endif diff --git a/WCudaMSE/Student_Cuda_Image/src/cpp/core/03_Newton/moo/host/Newton.cu b/WCudaMSE/Student_Cuda_Image/src/cpp/core/03_Newton/moo/host/Newton.cu index 028f924..685fb5e 100755 --- a/WCudaMSE/Student_Cuda_Image/src/cpp/core/03_Newton/moo/host/Newton.cu +++ b/WCudaMSE/Student_Cuda_Image/src/cpp/core/03_Newton/moo/host/Newton.cu @@ -1,12 +1,11 @@ #include #include +#include +using namespace std; #include "Newton.h" #include "Device.h" -using std::cout; -using std::endl; - extern __global__ void newton(uchar4* ptrDevPixels, int w, int h, DomaineMath domaineMath); Newton::Newton(int w, int h) @@ -14,9 +13,10 @@ Newton::Newton(int w, int h) w(w), h(h), dg(8, 8, 1), db(16, 16, 1), + ptrDomaineMathInit(new DomaineMath(-2, -2, 2, 2)), title("Fractal Newton") { - //print(dg, db); + // print(dg, db); Device::assertDim(dg, db); } diff --git a/WCudaMSE/Student_Cuda_Image/src/cpp/core/mainGL.cpp b/WCudaMSE/Student_Cuda_Image/src/cpp/core/mainGL.cpp index 3d4d02f..d2b6adf 100755 --- a/WCudaMSE/Student_Cuda_Image/src/cpp/core/mainGL.cpp +++ b/WCudaMSE/Student_Cuda_Image/src/cpp/core/mainGL.cpp @@ -1,6 +1,7 @@ #include #include #include +using namespace std; #include "GLUTImageViewers.h" @@ -9,55 +10,40 @@ #include "Rippling0Provider.h" #include "RipplingProvider.h" - #include "FractalProvider.h" +#include "NewtonProvider.h" -using std::cout; -using std::endl; -using std::string; -class RipplingViewer +template +class Viewer { + private: + TOutput* ptrProvider; + GLUTImageViewers viewer; + public: - RipplingViewer() - : ptrRippling0(Rippling0Provider::createGL()), ptrRippling(RipplingProvider::createGL()), - rippling0Viewer(this->ptrRippling0, true, true, 0, 0), - ripplingViewer(this->ptrRippling, true, true, 20, 20) - {} - ~RipplingViewer() + Viewer(bool isAnimation, bool isSelection, int pxFrame, int pyFrame): + ptrProvider(TProvider::createGL()), + viewer(ptrProvider, isAnimation, isSelection, pxFrame, pyFrame) { - delete this->ptrRippling0; - delete this->ptrRippling; } - private: - Rippling0Image* ptrRippling0; - Image* ptrRippling; - GLUTImageViewers rippling0Viewer, ripplingViewer; - }; -class FractalViewer - { - public: - FractalViewer() - : ptrMandelbrot(FractalProvider::createMandelbrotGL()), ptrJulia(FractalProvider::createJuliaGL()), - mandelbrotViewer(this->ptrMandelbrot, true, true, 0, 0), - juliaViewer(this->ptrJulia, true, true, 20, 20) - {} - ~FractalViewer() + ~Viewer() { - delete this->ptrMandelbrot; - delete this->ptrJulia; + delete this->ptrProvider; } - private: - ImageFonctionel* ptrMandelbrot; - ImageFonctionel* ptrJulia; - GLUTImageViewers mandelbrotViewer, juliaViewer; }; int mainGL(void) { - // RipplingViewer rippling; - // FractalViewer fractals; + //Viewer rippling0(true, true, 10, 10); + //Viewer rippling0(true, true, 10, 10); + //Viewer fractalMandelbrot(true, true, 20, 20); + //Viewer fractalJulia(true, true, 30, 30); + + + Viewer newtown(true, true, 20, 20); + GLUTImageViewers::runALL(); // Bloquant, Tant qu'une fenetre est ouverte -- 2.45.2