00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <math.h>
00035 #include <time.h>
00036 #include <stdexcept>
00037 #include <iostream>
00038 #include "Image.h"
00039 #include "LIC.h"
00040 #include "cimg_dependent.h"
00041
00042 using namespace lsseg;
00043 using namespace std;
00044
00045
00046 inline void uniformNoise(double* res, double lval, double uval, int num_samples)
00047 {
00048 if (uval <= lval) {
00049 throw runtime_error("uniformNoise(...) : erroneous range.");
00050 }
00051 double range = uval - lval;
00052 double scale_factor = range / double(RAND_MAX);
00053 for (int i = 0; i < num_samples; ++i) {
00054 res[i] = double(rand()) * scale_factor + lval;
00055 }
00056 }
00057
00058 void monopole_field(double xpos, double ypos, double zpos, double q, Image<double>& I);
00059
00060 double gauss(double t)
00061 {
00062
00063 return exp(-(t*t) / 10);
00064 }
00065
00066 int main()
00067 {
00068 const int X = 200;
00069 const int Y = 200;
00070 const int Z = 200;
00071 const double FIELD_STRENGTH = 1;
00072
00073 cout << "Now allocating memory for field..." << endl;
00074 Image<double> field(X, Y, Z, 3);
00075 cout << "Finished!" << endl;
00076
00077
00078 const double p1x = double(X-1)/2;
00079 const double p1y = double(Y-1)/2;
00080 const double p1z = double(Z-1)/3;
00081 const double p2x = double(X-1)/2;
00082 const double p2y = double(Y-1)/2;
00083 const double p2z = double(2*(Z-1))/3;
00084
00085 cout << "Now generating field..." << endl;
00086 monopole_field(p1x, p1y, p1z, FIELD_STRENGTH, field);
00087 cout << "halfway..." << endl;
00088 monopole_field(p2x, p2y, p2z, -FIELD_STRENGTH, field);
00089 cout << "Finished!" << endl;
00090
00091 cout << "Now allocating memory for noise image..." << endl;
00092 Image<double> noise(X, Y, Z);
00093 cout << "Finished!" << endl;
00094 cout << "Now making noise image..." << endl;
00095 uniformNoise(noise.begin(), -128, 128, noise.size());
00096 blur_image(noise, 0.5);
00097 cout << "Finished!" << endl;
00098
00099 cout << "Now allocating memory for target image" << endl;
00100 Image<double> target(X, Y, Z);
00101 cout << "Finished!" << endl;
00102 target = 0;
00103 clock_t tstart = clock();
00104 cout << "Now starting processing" << endl;
00105 LIC_3D(noise, field, target, &gauss, 2);
00106 cout << "Finished!" << endl;
00107 clock_t tend = clock();
00108
00109 int perm[] = {1, 2, 0, 3};
00110 target.permute(perm);
00111
00112 for (int z = 0; z < Z; z += (Z/10 < 1) ? 1 : Z/10) {
00113 cout << "now showing z slice: " << z << " out of " << Z << endl;
00114 display_image(target, z);
00115 }
00116 cout << "Total processing time: " << double(tend-tstart)/1000 << " ms." << endl;
00117
00118 return 1;
00119 };
00120
00121 double maxof(double a, double b, double c)
00122 {
00123 double res = a > b ? a : b;
00124 res = res > c ? res : c;
00125 return res;
00126 }
00127
00128 void monopole_field(double xpos, double ypos, double zpos, double q, Image<double>& I)
00129 {
00130 const int X = I.dimx();
00131 const int Y = I.dimy();
00132 const int Z = I.dimz();
00133 const double K = 0.001;
00134 const double M = maxof(X, Y, Z);
00135
00136 for (int z = 0; z < Z; ++z) {
00137 for (int y = 0; y < Y; ++y) {
00138 for (int x = 0; x < X; ++x) {
00139 const double dx = (x - xpos)/M;
00140 const double dy = (y - ypos)/M;
00141 const double dz = (z - zpos)/M;
00142 const double n = sqrt(dx*dx + dy*dy + dz*dz);
00143
00144 const double fac = double(q) / (K + (n * n * n));
00145
00146 I(x,y,z,0) += fac * dx;
00147 I(x,y,z,1) += fac * dy;
00148 I(x,y,z,2) += fac * dz;
00149 }
00150 }
00151 }
00152 }