Commit 5eeaf94149e3255107b2bc3f48446c88acfbdf65

Authored by Pavel Govyadinov
2 parents 84583942 487a9b49

changer to the base stim/math/*, stim/grid/* and /stim/gl/* classes in order to …

…allow the new vector to function. Added general convenience push methods to the mathvec class, as well as changed a convenience constructor to a size constructor, many small fixes
stim/cuda/cost.h
... ... @@ -67,8 +67,8 @@ void get_diff (float *result)
67 67  
68 68 float valIn = tex2D(texIn, x, y)/255.0;
69 69 float valTemp = Template(x);
70   - //result[idx] = abs(valIn-valTemp);
71   - result[idx] = abs(valIn);
  70 + result[idx] = abs(valIn-valTemp);
  71 + //result[idx] = abs(valIn);
72 72 }
73 73  
74 74  
... ...
stim/gl/gl_spider.h
... ... @@ -10,7 +10,7 @@
10 10 #include "stim/gl/gl_texture.h"
11 11 #include "stim/visualization/camera.h"
12 12 #include "stim/gl/error.h"
13   -#include "stim/math/vector.h"
  13 +#include "stim/math/mathvec.h"
14 14 #include "stim/math/rect.h"
15 15 #include "stim/math/matrix.h"
16 16 #include "stim/cuda/cost.h"
... ... @@ -64,19 +64,22 @@ class gl_spider
64 64 findOptimalDirection()
65 65 {
66 66 //genTemplate(dV, 0);
  67 + cout << "Direction Before: " << d << endl;
67 68 setMatrix();
68 69 glCallList(dList);
69 70 int best = getCost();
70   - stim::vec<float, 4> next;
71   - next[0] = dV[best][0]*S[0]*R[0];
72   - next[1] = dV[best][1]*S[1]*R[1];
73   - next[2] = dV[best][2]*S[2]*R[2];
74   - next[3] = 1;
  71 + stim::vec<float> next(
  72 + dV[best][0]*S[0]*R[0],
  73 + dV[best][1]*S[1]*R[1],
  74 + dV[best][2]*S[2]*R[2],
  75 + 1);
  76 + //next = (cT*next).norm();
75 77 next = (cT*next).norm();
76 78 setPosition( p[0]+next[0]*m[0]/stepsize,
77 79 p[1]+next[1]*m[0]/stepsize,
78 80 p[2]+next[2]*m[0]/stepsize);
79 81 setDirection(next[0], next[1], next[2]);
  82 + cout << "Direction After: " << d << endl;
80 83 }
81 84  
82 85 /// Method for finding the best d for the spider.
... ... @@ -88,16 +91,16 @@ class gl_spider
88 91 setMatrix();
89 92 glCallList(dList+1);
90 93 int best = getCost();
91   - stim::vec<float, 4> next;
92   - next[0] = pV[best][0];
93   - next[1] = pV[best][1];
94   - next[2] = pV[best][2];
95   - next[3] = 1;
  94 + stim::vec<float> next(
  95 + pV[best][0],
  96 + pV[best][1],
  97 + pV[best][2],
  98 + 1);
96 99 next = cT*next;
97   - std::cout << "Optimal p:"<< next << std::endl;
98 100 setPosition( next[0]*S[0]*R[0],
99 101 next[1]*S[1]*R[1],
100 102 next[2]*S[2]*R[2]);
  103 + std::cout << "Optimal p:"<< p << std::endl;
101 104 }
102 105  
103 106 /// Method for finding the best scale for the spider.
... ... @@ -109,11 +112,11 @@ class gl_spider
109 112 setMatrix();
110 113 glCallList(dList+2);
111 114 int best = getCost();
112   - stim::vec<float, 4> next;
113   - next[0] = mV[best][0]*S[0]*R[0];
114   - next[1] = mV[best][1]*S[1]*R[1];
115   - next[2] = mV[best][2]*S[2]*R[2];
116   - next[3] = 1;
  115 + stim::vec<float> next(
  116 + mV[best][0]*S[0]*R[0],
  117 + mV[best][1]*S[1]*R[1],
  118 + mV[best][2]*S[2]*R[2],
  119 + 1);
117 120 next = cT*next;
118 121 std::cout << "Optimal Scale:"<< next << std::endl;
119 122 setMagnitude(next[0]);
... ... @@ -123,7 +126,7 @@ class gl_spider
123 126 branchDetection()
124 127 {
125 128 Bind();
126   - positionTemplate();
  129 + setMatrix();
127 130 glCallList(dList+3);
128 131  
129 132 int best = getCost();
... ... @@ -151,16 +154,17 @@ class gl_spider
151 154 void
152 155 genDirectionVectors(float solidAngle = M_PI)
153 156 {
  157 + //ofstream file;
  158 + //file.open("dvectors.txt");
154 159 //Set up the vectors necessary for Rectangle creation.
155 160 vec<float> Y(1.0,0.0,0.0);
156 161 vec<float> pos(0.0,0.0,0.0);
157 162 vec<float> mag(1.0, 1.0, 1.0);
158 163 vec<float> dir(0.0, 0.0, 1.0);
159 164  
160   - vec<float> d_s = direction.cart2sph().norm();
161 165 //Set up the variable necessary for vector creation.
162 166 vec<float> d_s = d.cart2sph().norm();
163   - vec<float> temp;
  167 + vec<float> temp(0,0,0);
164 168 int dim = (sqrt(numSamples)-1)/2;
165 169 float p0 = -M_PI;
166 170 float dt = solidAngle/(2.0 * ((float)dim + 1.0));
... ... @@ -171,7 +175,7 @@ class gl_spider
171 175 int idx = 0;
172 176 for(int i = -dim; i <= dim; i++){
173 177 for(int j = -dim; j <= dim; j++){
174   -
  178 +
175 179 //Create linear index
176 180 idx = (j+dim)+(i+dim)*((dim*2)+1);
177 181 temp[0] = d_s[0]; //rotate vector
... ... @@ -179,6 +183,7 @@ class gl_spider
179 183 temp[2] = d_s[2]+dt*(float) j;
180 184  
181 185 temp = (temp.sph2cart()).norm(); //back to cart
  186 + // file << temp[0] << "," << temp[1] << "," << temp[2] << endl;
182 187 dV.push_back(temp);
183 188 if(cos(Y.dot(temp))< 0.087){ Y[0] = 0.0; Y[1] = 1.0;}
184 189 else{Y[0] = 1.0; Y[1] = 0.0;}
... ... @@ -202,6 +207,8 @@ class gl_spider
202 207 void
203 208 genPositionVectors(float delta = 0.2)
204 209 {
  210 + ofstream file;
  211 + file.open("pvectors.txt");
205 212 //Set up the vectors necessary for Rectangle creation.
206 213 vec<float> Y(1.0,0.0,0.0);
207 214 vec<float> pos(0.0,0.0,0.0);
... ... @@ -209,10 +216,11 @@ class gl_spider
209 216 vec<float> dir(0.0, 0.0, 1.0);
210 217  
211 218 //Set up the variable necessary for vector creation.
212   - vec<float> temp;
  219 + vec<float> temp(0,0,0);
213 220 int dim = (sqrt(numSamples)-1)/2;
214 221 stim::rect<float> samplingPlane =
215   - stim::rect<float>(m[0]*delta, p, d);
  222 + stim::rect<float>(p, d);
  223 + samplingPlane.scale(m[0]*delta, m[0]*delta);
216 224 float step = 1.0/(dim);
217 225  
218 226 //Loop over the samples, keeping the original p sample
... ... @@ -228,6 +236,7 @@ class gl_spider
228 236 0.5+step*i,
229 237 0.5+step*j
230 238 );
  239 + file << temp[0] << "," << temp[1] << "," << temp[2] << endl;
231 240 pV.push_back(temp);
232 241 hor = stim::rect<float>(mag,
233 242 temp, dir,
... ... @@ -262,7 +271,7 @@ class gl_spider
262 271 float max = 1.0+delta;
263 272 float step = (max-min)/(numSamples-1);
264 273 float factor;
265   - vec<float> temp;
  274 + vec<float> temp(0.0,0.0,0.0);
266 275  
267 276 glNewList(dList+2, GL_COMPILE);
268 277 for(int i = 0; i < numSamples; i++){
... ... @@ -284,7 +293,6 @@ class gl_spider
284 293 }
285 294 ///@param v_x x-coordinate in buffer-space,
286 295 ///@param v_y y-coordinate in buffer-space.
287   - ilVertex2f(0.0, j*10.0);
288 296 ///Samples the texturespace and places a sample in the provided coordinates
289 297 ///of bufferspace.
290 298 void
... ... @@ -434,7 +442,7 @@ class gl_spider
434 442 ///Based on the p of the spider in real space (arbitrary).
435 443 void setMatrix()
436 444 {
437   - stim::vec<float, 4> rot = getRotation(d);
  445 + stim::vec<float> rot = getRotation(d);
438 446 glMatrixMode(GL_TEXTURE);
439 447 glLoadIdentity();
440 448  
... ... @@ -514,20 +522,30 @@ class gl_spider
514 522 gl_spider
515 523 (int samples = 1089)
516 524 {
517   - setPosition(0.0,0.0,0.0);
518   - setDirection(0.0,0.0,1.0);
519   - setMagnitude(1.0);
  525 + p.push(0.0,0.0,0.0);
  526 + d.push(0.0,0.0,1.0);
  527 + m.push(1.0, 1.0);
  528 + S.push(1.0,1.0,1.0);
  529 + R.push(1.0,1.0,1.0);
  530 + //setPosition(0.0,0.0,0.0);
  531 + //setDirection(0.0,0.0,1.0);
  532 + //setMagnitude(1.0);
520 533 numSamples = samples;
521 534 }
522 535  
523 536 ///temporary constructor for convenience, will be removed in further updates.
524 537 gl_spider
525 538 (float pos_x, float pos_y, float pos_z, float dir_x, float dir_y, float dir_z,
526   - float mag_x)
527   - {
528   - setPosition(pos_x, pos_y, pos_z);
529   - setDirection(dir_x, dir_y, dir_z);
530   - setMagnitude(mag_x);
  539 + float mag_x, int numSamples = 1089)
  540 + {
  541 + p.push(pos_x, pos_y, pos_z);
  542 + d.push(dir_x, dir_y, dir_z);
  543 + m.push(mag_x, mag_x);
  544 + S.push(1.0,1.0,1.0);
  545 + R.push(1.0,1.0,1.0);
  546 + //setPosition(pos_x, pos_y, pos_z);
  547 + //setDirection(dir_x, dir_y, dir_z);
  548 + //setMagnitude(mag_x);
531 549  
532 550 }
533 551  
... ... @@ -551,7 +569,7 @@ class gl_spider
551 569 GenerateFBO(20, numSamples*10);
552 570 setDims(0.6, 0.6, 1.0);
553 571 setSize(512.0, 512.0, 426.0);
554   -
  572 + setMatrix();
555 573 dList = glGenLists(3);
556 574 glListBase(dList);
557 575 Bind();
... ... @@ -664,10 +682,10 @@ class gl_spider
664 682 ///@param dir, the vector to which we are rotating
665 683 ///given a vector to align to, finds the required
666 684 ///axis and angle for glRotatef
667   - stim::vec<float, 4>
  685 + stim::vec<float>
668 686 getRotation(stim::vec<float> dir)
669 687 {
670   - stim::vec<float, 4> out;
  688 + stim::vec<float> out(0,0,0,0);;
671 689 stim::vec<float> from(0,0,1);
672 690 out[0] = acos(from.dot(dir))*M_PI/180;
673 691 if(out[0] < 0.0001){
... ... @@ -718,7 +736,7 @@ class gl_spider
718 736 findOptimalDirection();
719 737 findOptimalPosition();
720 738 findOptimalScale();
721   - branchDetection();
  739 +// branchDetection();
722 740 Unbind();
723 741 }
724 742  
... ...
stim/grids/grid.h
... ... @@ -7,7 +7,7 @@
7 7 #include <fstream>
8 8 #include <cstdarg>
9 9  
10   -#include "../math/vector.h"
  10 +#include "../math/mathvec.h"
11 11  
12 12 namespace stim{
13 13  
... ... @@ -20,8 +20,8 @@ class grid{
20 20  
21 21 protected:
22 22  
23   - stim::vec<unsigned long, D> R; //elements in each dimension
24   - stim::vec<float, D> S;
  23 + stim::vec<unsigned long> R; //elements in each dimension
  24 + stim::vec<float> S;
25 25 T* ptr; //pointer to the data (on the GPU or CPU)
26 26  
27 27 ///Return the total number of values in the binary file
... ... @@ -56,7 +56,7 @@ public:
56 56 ///Constructor used to specify the grid size as a vector
57 57  
58 58 /// @param _R is a vector describing the grid resolution
59   - grid( stim::vec<unsigned long, D> _R){
  59 + grid( stim::vec<unsigned long> _R){
60 60  
61 61 //set the grid resolution
62 62 R = _R;
... ... @@ -65,7 +65,7 @@ public:
65 65 }
66 66  
67 67 void
68   - setDim(stim::vec<float, D> s)
  68 + setDim(stim::vec<float> s)
69 69 {
70 70 S = s;
71 71 }
... ... @@ -106,7 +106,7 @@ public:
106 106 /// @param filename is the name of the file containing the binary data
107 107 /// @param S is the size of the binary file along each dimension
108 108 /// @param header is the size of the header in bytes
109   - void read(std::string filename, stim::vec<unsigned long, D> S, unsigned long header = 0){
  109 + void read(std::string filename, stim::vec<unsigned long> S, unsigned long header = 0){
110 110  
111 111 R = S; //set the sample resolution
112 112  
... ... @@ -177,7 +177,7 @@ public:
177 177 result<<"]"<<std::endl;
178 178  
179 179 //calculate the number of values to output
180   - unsigned long nV = min(R[0], (unsigned long)10);
  180 + unsigned long nV = min((unsigned long long)R[0], (unsigned long long)10);
181 181  
182 182 for(unsigned long v = 0; v<nV; v++){
183 183 result<<ptr[v];
... ...
stim/grids/image_stack.h
... ... @@ -51,10 +51,10 @@ public:
51 51 stim::image<T> I(file_list[0].str());
52 52  
53 53 //set the image resolution and number of channels
54   - R[0] = I.channels();
55   - R[1] = I.width();
56   - R[2] = I.height();
57   - R[3] = file_list.size();
  54 + R.push(I.channels());
  55 + R.push(I.width());
  56 + R.push(I.height());
  57 + R.push(file_list.size());
58 58  
59 59 //allocate storage space
60 60 ptr = (T*)malloc(sizeof(T) * samples());
... ...
stim/math/mathvec.h 0 → 100644
  1 +#ifndef RTS_VECTOR_H
  2 +#define RTS_VECTOR_H
  3 +
  4 +#include <iostream>
  5 +#include <cmath>
  6 +#include <sstream>
  7 +#include <vector>
  8 +#include "../cuda/callable.h"
  9 +
  10 +namespace stim
  11 +{
  12 +
  13 +
  14 +
  15 +template <class T>
  16 +struct vec : public std::vector<T>
  17 +{
  18 + using std::vector<T>::size;
  19 + using std::vector<T>::at;
  20 + using std::vector<T>::resize;
  21 + using std::vector<T>::push_back;
  22 + vec(){
  23 +
  24 + }
  25 +
  26 +// //efficiency constructors, makes construction easier for 1D-4D vectors
  27 + vec(T rhs)
  28 + {
  29 + resize(1, rhs);
  30 +// cerr << " Created a vector " << endl;
  31 +// //for(int i=0; i<N; i++)
  32 +// // v[i] = rhs;
  33 + }
  34 +
  35 +// vec(int s)
  36 +// {
  37 +// resize(s,0);
  38 +// }
  39 +
  40 + vec(T x, T y)
  41 + {
  42 + push_back(x);
  43 + push_back(y);
  44 + }
  45 + vec(T x, T y, T z)
  46 + {
  47 + push_back(x);
  48 + push_back(y);
  49 + push_back(z);
  50 + }
  51 + vec(T x, T y, T z, T w)
  52 + {
  53 + push_back(x);
  54 + push_back(y);
  55 + push_back(z);
  56 + push_back(w);
  57 + }
  58 +
  59 +
  60 +
  61 + //copy constructor
  62 + vec( const vec<T>& other){
  63 + unsigned int N = other.size();
  64 + for(int i=0; i<N; i++)
  65 + push_back(other[i]);
  66 + }
  67 +
  68 + vec<T> push(T x)
  69 + {
  70 + push_back(x);
  71 + return *this;
  72 + }
  73 +
  74 + vec<T> push(T x, T y)
  75 + {
  76 + push_back(x);
  77 + push_back(y);
  78 + return *this;
  79 + }
  80 + vec<T> push(T x, T y, T z)
  81 + {
  82 + push_back(x);
  83 + push_back(y);
  84 + push_back(z);
  85 + return *this;
  86 + }
  87 + vec<T> push(T x, T y, T z, T w)
  88 + {
  89 + push_back(x);
  90 + push_back(y);
  91 + push_back(z);
  92 + push_back(w);
  93 + return *this;
  94 + }
  95 + template< typename U >
  96 + operator vec<U>(){
  97 + unsigned int N = size();
  98 + vec<U> result;
  99 + for(int i=0; i<N; i++)
  100 + result.push_back(at(i));
  101 +
  102 + return result;
  103 + }
  104 +
  105 + //template<class U>
  106 + //friend vec<U, N>::operator vec<T, N>();
  107 +
  108 + T len() const
  109 + {
  110 + unsigned int N = size();
  111 +
  112 + //compute and return the vector length
  113 + T sum_sq = (T)0;
  114 + for(int i=0; i<N; i++)
  115 + {
  116 + sum_sq += pow( at(i), 2 );
  117 + }
  118 + return sqrt(sum_sq);
  119 +
  120 + }
  121 +
  122 + vec<T> cart2sph() const
  123 + {
  124 + //convert the vector from cartesian to spherical coordinates
  125 + //x, y, z -> r, theta, phi (where theta = 0 to 2*pi)
  126 +
  127 + vec<T> sph;
  128 + sph.push_back(std::sqrt(at(0)*at(0) + at(1)*at(1) + at(2)*at(2)));
  129 + sph.push_back(std::atan2(at(1), at(0)));
  130 +
  131 + if(sph[0] == 0)
  132 + sph.push_back(0);
  133 + else
  134 + sph.push_back(std::acos(at(2) / sph[0]));
  135 +
  136 + return sph;
  137 + }
  138 +
  139 + vec<T> sph2cart() const
  140 + {
  141 + //convert the vector from cartesian to spherical coordinates
  142 + //r, theta, phi -> x, y, z (where theta = 0 to 2*pi)
  143 +
  144 + vec<T> cart;
  145 + cart.push_back(at(0) * std::cos(at(1)) * std::sin(at(2)));
  146 + cart.push_back(at(0) * std::sin(at(1)) * std::sin(at(2)));
  147 + cart.push_back(at(0) * std::cos(at(2)));
  148 +
  149 + return cart;
  150 + }
  151 +
  152 + vec<T> norm() const
  153 + {
  154 + unsigned int N = size();
  155 +
  156 + //compute and return the unit vector
  157 + vec<T> result;
  158 +
  159 + //compute the vector length
  160 + T l = len();
  161 +
  162 + //normalize
  163 + for(int i=0; i<N; i++)
  164 + {
  165 + result.push_back(at(i) / l);
  166 + }
  167 +
  168 + return result;
  169 + }
  170 +
  171 + vec<T> cross(const vec<T> rhs) const
  172 + {
  173 + vec<T> result;
  174 +
  175 + //compute the cross product (only valid for 3D vectors)
  176 + result.push_back(at(1) * rhs[2] - at(2) * rhs[1]);
  177 + result.push_back(at(2) * rhs[0] - at(0) * rhs[2]);
  178 + result.push_back(at(0) * rhs[1] - at(1) * rhs[0]);
  179 +
  180 + return result;
  181 + }
  182 +
  183 + T dot(vec<T> rhs) const
  184 + {
  185 + T result = (T)0;
  186 + unsigned int N = size();
  187 + for(int i=0; i<N; i++)
  188 + result += at(i) * rhs[i];
  189 +
  190 + return result;
  191 +
  192 + }
  193 +
  194 + //arithmetic
  195 + vec<T> operator+(vec<T> rhs) const
  196 + {
  197 + vec<T> result;
  198 +
  199 + unsigned int N = size();
  200 + for(int i=0; i<N; i++)
  201 + result.push_back(at(i) + rhs[i]);
  202 +
  203 + return result;
  204 + }
  205 + vec<T> operator+(T rhs) const
  206 + {
  207 + vec<T> result;
  208 + unsigned int N = size();
  209 + for(int i=0; i<N; i++)
  210 + result.push_back(at(i) + rhs);
  211 +
  212 + return result;
  213 + }
  214 + vec<T> operator-(vec<T> rhs) const
  215 + {
  216 + vec<T> result;
  217 +
  218 + unsigned int N = size();
  219 + for(int i=0; i<N; i++)
  220 + result.push_back(at(i) - rhs[i]);
  221 +
  222 + return result;
  223 + }
  224 + vec<T> operator*(T rhs) const
  225 + {
  226 + vec<T> result;
  227 +
  228 + unsigned int N = size();
  229 + for(int i=0; i<N; i++)
  230 + result.push_back(at(i) * rhs);
  231 +
  232 + return result;
  233 + }
  234 + vec<T> operator/(T rhs) const
  235 + {
  236 + vec<T> result;
  237 +
  238 + unsigned int N = size();
  239 + for(int i=0; i<N; i++)
  240 + result.push_back(at(i) / rhs);
  241 +
  242 + return result;
  243 + }
  244 + vec<T> operator*=(T rhs){
  245 +
  246 + unsigned int N = size();
  247 + for(int i=0; i<N; i++)
  248 + at(i) = at(i) * rhs;
  249 + return *this;
  250 + }
  251 + vec<T> operator+=(vec<T> rhs){
  252 + unsigned int N = size();
  253 + for(int i=0; i<N; i++)
  254 + at(i) += rhs[i];
  255 + return *this;
  256 + }
  257 + vec<T> & operator=(T rhs){
  258 +
  259 + unsigned int N = size();
  260 + for(int i=0; i<N; i++)
  261 + at(i) = rhs;
  262 + return *this;
  263 + }
  264 +
  265 + template<typename Y>
  266 + vec<T> & operator=(vec<Y> rhs){
  267 + unsigned int N = rhs.size();
  268 + resize(N);
  269 +
  270 + for(int i=0; i<N; i++)
  271 + at(i) = rhs[i];
  272 + return *this;
  273 + }
  274 + //unary minus
  275 + vec<T> operator-() const{
  276 + vec<T> r;
  277 +
  278 + //negate the vector
  279 + unsigned int N = size();
  280 + for(int i=0; i<N; i++)
  281 + r.push_back(-at(i));
  282 +
  283 + return r;
  284 + }
  285 +
  286 +
  287 + std::string str() const
  288 + {
  289 + std::stringstream ss;
  290 +
  291 + unsigned int N = size();
  292 +
  293 + ss<<"[";
  294 + for(int i=0; i<N; i++)
  295 + {
  296 + ss<<at(i);
  297 + if(i != N-1)
  298 + ss<<", ";
  299 + }
  300 + ss<<"]";
  301 +
  302 + return ss.str();
  303 + }
  304 +
  305 +};
  306 +
  307 +
  308 +} //end namespace rts
  309 +
  310 +template <typename T>
  311 +std::ostream& operator<<(std::ostream& os, stim::vec<T> v)
  312 +{
  313 + os<<v.str();
  314 + return os;
  315 +}
  316 +
  317 +
  318 +
  319 +template <typename T>
  320 +stim::vec<T> operator*(T lhs, stim::vec<T> rhs)
  321 +{
  322 + stim::vec<T> r;
  323 +
  324 + return rhs * lhs;
  325 +}
  326 +
  327 +//#if __GNUC__ > 3 && __GNUC_MINOR__ > 7
  328 +//template<class T, int N> using rtsVector = rts::vector<T, N>;
  329 +//#endif
  330 +
  331 +#endif
... ...
stim/math/matrix.h
... ... @@ -4,7 +4,7 @@
4 4 //#include "rts/vector.h"
5 5 #include <string.h>
6 6 #include <iostream>
7   -#include "vector.h"
  7 +#include "mathvec.h"
8 8 #include "../cuda/callable.h"
9 9  
10 10 namespace stim{
... ... @@ -52,9 +52,12 @@ struct matrix
52 52  
53 53  
54 54 template<typename Y>
55   - CUDA_CALLABLE vec<Y, N> operator*(vec<Y, N> rhs)
  55 + CUDA_CALLABLE vec<Y> operator*(vec<Y> rhs)
56 56 {
57   - vec<Y, N> result;
  57 + unsigned int N = rhs.size();
  58 +
  59 + vec<Y> result;
  60 + result.resize(N);
58 61  
59 62 for(int r=0; r<N; r++)
60 63 for(int c=0; c<N; c++)
... ...
stim/math/quaternion.h
... ... @@ -26,13 +26,13 @@ public:
26 26  
27 27 CUDA_CALLABLE void CreateRotation(T theta, T ux, T uy, T uz){
28 28  
29   - vec<T, 3> u(ux, uy, uz);
  29 + vec<T> u(ux, uy, uz);
30 30 CreateRotation(theta, u);
31 31 }
32 32  
33   - CUDA_CALLABLE void CreateRotation(T theta, vec<T, 3> u){
  33 + CUDA_CALLABLE void CreateRotation(T theta, vec<T> u){
34 34  
35   - vec<T, 3> u_hat = u.norm();
  35 + vec<T> u_hat = u.norm();
36 36  
37 37 //assign the given Euler rotation to this quaternion
38 38 w = (T)cos(theta/2);
... ... @@ -41,7 +41,7 @@ public:
41 41 z = u_hat[2]*(T)sin(theta/2);
42 42 }
43 43  
44   - CUDA_CALLABLE void CreateRotation(vec<T, 3> from, vec<T, 3> to){
  44 + CUDA_CALLABLE void CreateRotation(vec<T> from, vec<T> to){
45 45  
46 46 vec<T> r = from.cross(to); //compute the rotation vector
47 47 T theta = asin(r.len()); //compute the angle of the rotation about r
... ...
stim/math/rect.h
... ... @@ -3,7 +3,7 @@
3 3  
4 4 //enable CUDA_CALLABLE macro
5 5 #include "../cuda/callable.h"
6   -#include "../math/vector.h"
  6 +#include "../math/mathvec.h"
7 7 #include "../math/triangle.h"
8 8 #include "../math/quaternion.h"
9 9 #include <iostream>
... ... @@ -13,7 +13,7 @@
13 13 namespace stim{
14 14  
15 15 //template for a rectangle class in ND space
16   -template <class T, int N = 3>
  16 +template <class T>
17 17 struct rect
18 18 {
19 19 /*
... ... @@ -28,9 +28,9 @@ struct rect
28 28  
29 29 private:
30 30  
31   - stim::vec<T, N> C;
32   - stim::vec<T, N> X;
33   - stim::vec<T, N> Y;
  31 + stim::vec<T> C;
  32 + stim::vec<T> X;
  33 + stim::vec<T> Y;
34 34  
35 35 CUDA_CALLABLE void scale(T factor){
36 36 X *= factor;
... ... @@ -38,10 +38,10 @@ private:
38 38 }
39 39  
40 40  
41   - CUDA_CALLABLE void normal(vec<T, N> n){ //orient the rectangle along the specified normal
  41 + CUDA_CALLABLE void normal(vec<T> n){ //orient the rectangle along the specified normal
42 42  
43 43 n = n.norm(); //normalize, just in case
44   - vec<T, N> n_current = X.cross(Y).norm(); //compute the current normal
  44 + vec<T> n_current = X.cross(Y).norm(); //compute the current normal
45 45 quaternion<T> q; //create a quaternion
46 46 q.CreateRotation(n_current, n); //initialize a rotation from n_current to n
47 47  
... ... @@ -51,9 +51,9 @@ private:
51 51 }
52 52  
53 53 CUDA_CALLABLE void init(){
54   - C = vec<T, N>(0, 0, 0);
55   - X = vec<T, N>(1, 0, 0);
56   - Y = vec<T, N>(0, 1, 0);
  54 + C = vec<T>(0, 0, 0);
  55 + X = vec<T>(1, 0, 0);
  56 + Y = vec<T>(0, 1, 0);
57 57 }
58 58  
59 59 public:
... ... @@ -69,30 +69,22 @@ public:
69 69 C[2] = z_pos;
70 70 }
71 71  
72   - //create a rectangle from a center point, normal, and size
73   - CUDA_CALLABLE rect(T size, vec<T, N> c, vec<T, N> n = vec<T, N>(0, 0, 1)){
74   - init(); //start with the default setting
75   - C = c;
76   - scale(size); //scale the rectangle
77   - normal(n); //orient
78   - }
79 72  
80 73 //create a rectangle from a center point, normal, and size
81   - CUDA_CALLABLE rect(vec<T,2> size, vec<T, N> c, vec<T, N> n = vec<T, N>(0, 0, 1)){
  74 + CUDA_CALLABLE rect(vec<T> c, vec<T> n = vec<T>(0, 0, 1)){
82 75 init(); //start with the default setting
83 76 C = c;
84   - scale(size); //scale the rectangle
85 77 normal(n); //orient
86 78 }
87 79  
88   - CUDA_CALLABLE rect(vec<T, N> center, vec<T, N> directionX, vec<T, N> directionY )
  80 + CUDA_CALLABLE rect(vec<T> center, vec<T> directionX, vec<T> directionY )
89 81 {
90 82 C = center;
91 83 X = directionX;
92 84 Y = directionY;
93 85 }
94 86  
95   - CUDA_CALLABLE rect(T size, vec<T, N> center, vec<T, N> directionX, vec<T, N> directionY )
  87 + CUDA_CALLABLE rect(T size, vec<T> center, vec<T> directionX, vec<T> directionY )
96 88 {
97 89 C = center;
98 90 X = directionX;
... ... @@ -100,7 +92,7 @@ public:
100 92 scale(size);
101 93 }
102 94  
103   - CUDA_CALLABLE rect(vec<T,N> size, vec<T, N> center, vec<T, N> directionX, vec<T, N> directionY )
  95 + CUDA_CALLABLE rect(vec<T> size, vec<T> center, vec<T> directionX, vec<T> directionY )
104 96 {
105 97 C = center;
106 98 X = directionX;
... ... @@ -114,7 +106,7 @@ public:
114 106 }
115 107  
116 108 //boolean comparison
117   - bool operator==(const rect<T, N> & rhs)
  109 + bool operator==(const rect<T> & rhs)
118 110 {
119 111 if(C == rhs.C && X == rhs.X && Y == rhs.Y)
120 112 return true;
... ... @@ -125,24 +117,24 @@ public:
125 117 /*******************************************
126 118 Return the normal for the rect
127 119 *******************************************/
128   - CUDA_CALLABLE stim::vec<T, N> n()
  120 + CUDA_CALLABLE stim::vec<T> n()
129 121 {
130 122 return (X.cross(Y)).norm();
131 123 }
132 124  
133 125 //get the world space value given the planar coordinates a, b in [0, 1]
134   - CUDA_CALLABLE stim::vec<T, N> p(T a, T b)
  126 + CUDA_CALLABLE stim::vec<T> p(T a, T b)
135 127 {
136   - stim::vec<T, N> result;
  128 + stim::vec<T> result;
137 129 //given the two parameters a, b = [0 1], returns the position in world space
138   - vec<T, N> A = C - X * (T)0.5 - Y * (T)0.5;
  130 + vec<T> A = C - X * (T)0.5 - Y * (T)0.5;
139 131 result = A + X * a + Y * b;
140 132  
141 133 return result;
142 134 }
143 135  
144 136 //parenthesis operator returns the world space given rectangular coordinates a and b in [0 1]
145   - CUDA_CALLABLE stim::vec<T, N> operator()(T a, T b)
  137 + CUDA_CALLABLE stim::vec<T> operator()(T a, T b)
146 138 {
147 139 return p(a, b);
148 140 }
... ... @@ -150,7 +142,7 @@ public:
150 142 std::string str()
151 143 {
152 144 std::stringstream ss;
153   - vec<T, N> A = C - X * (T)0.5 - Y * (T)0.5;
  145 + vec<T> A = C - X * (T)0.5 - Y * (T)0.5;
154 146 ss<<std::left<<"B="<<std::setfill('-')<<std::setw(20)<<A + Y<<">"<<"C="<<A + Y + X<<std::endl;
155 147 ss<<std::setfill(' ')<<std::setw(23)<<"|"<<"|"<<std::endl<<std::setw(23)<<"|"<<"|"<<std::endl;
156 148 ss<<std::left<<"A="<<std::setfill('-')<<std::setw(20)<<A<<">"<<"D="<<A + X;
... ... @@ -160,12 +152,12 @@ public:
160 152 }
161 153  
162 154 //scales the rectangle by a value rhs
163   - CUDA_CALLABLE rect<T, N> operator*(T rhs)
  155 + CUDA_CALLABLE rect<T> operator*(T rhs)
164 156 {
165 157 //scales the plane by a scalar value
166 158  
167 159 //create the new rectangle
168   - rect<T, N> result = *this;
  160 + rect<T> result = *this;
169 161 result.scale(rhs);
170 162  
171 163 return result;
... ... @@ -173,15 +165,15 @@ public:
173 165 }
174 166  
175 167 //computes the distance between the specified point and this rectangle
176   - CUDA_CALLABLE T dist(vec<T, N> p)
  168 + CUDA_CALLABLE T dist(vec<T> p)
177 169 {
178 170 //compute the distance between a point and this rect
179 171  
180   - vec<T, N> A = C - X * (T)0.5 - Y * (T)0.5;
  172 + vec<T> A = C - X * (T)0.5 - Y * (T)0.5;
181 173  
182 174 //first break the rect up into two triangles
183   - triangle<T, N> T0(A, A+X, A+Y);
184   - triangle<T, N> T1(A+X+Y, A+X, A+Y);
  175 + triangle<T> T0(A, A+X, A+Y);
  176 + triangle<T> T1(A+X+Y, A+X, A+Y);
185 177  
186 178  
187 179 T d0 = T0.dist(p);
... ... @@ -193,9 +185,9 @@ public:
193 185 return d1;
194 186 }
195 187  
196   - CUDA_CALLABLE T dist_max(vec<T, N> p)
  188 + CUDA_CALLABLE T dist_max(vec<T> p)
197 189 {
198   - vec<T, N> A = C - X * (T)0.5 - Y * (T)0.5;
  190 + vec<T> A = C - X * (T)0.5 - Y * (T)0.5;
199 191 T da = (A - p).len();
200 192 T db = (A+X - p).len();
201 193 T dc = (A+Y - p).len();
... ... @@ -208,7 +200,7 @@ public:
208 200 } //end namespace rts
209 201  
210 202 template <typename T, int N>
211   -std::ostream& operator<<(std::ostream& os, stim::rect<T, N> R)
  203 +std::ostream& operator<<(std::ostream& os, stim::rect<T> R)
212 204 {
213 205 os<<R.str();
214 206 return os;
... ...
stim/math/spharmonics.h 0 → 100644
  1 +#ifndef STIM_SPH_HARMONICS
  2 +#define STIM_SPH_HARMONICS
  3 +
  4 +
  5 +#include <boost/math/special_functions/spherical_harmonic.hpp>
  6 +#include <vector>
  7 +
  8 +#define PI 3.14159
  9 +#define WIRE_SCALE 1.001
  10 +namespace stim{
  11 +
  12 +template<class T>
  13 +class spharmonics{
  14 +
  15 +protected:
  16 +
  17 + std::vector<T> C; //list of SH coefficients
  18 +
  19 + unsigned int mcN; //number of Monte-Carlo samples
  20 +
  21 + //calculate the value of the SH basis function (l, m) at (theta, phi)
  22 + //here, theta = [0, PI], phi = [0, 2*PI]
  23 + double SH(int l, int m, double theta, double phi){
  24 + return boost::math::spherical_harmonic_r(l, m, phi, theta);
  25 + }
  26 +
  27 + unsigned int coeff_1d(unsigned int l, int m){
  28 + return pow(l + 1, 2) - (l - m) - 1;
  29 + }
  30 +
  31 +
  32 +
  33 +
  34 +public:
  35 +
  36 + void push(double c){
  37 + C.push_back(c);
  38 + }
  39 +
  40 + void resize(unsigned int n){
  41 + C.resize(n);
  42 + }
  43 +
  44 + void setc(unsigned int l, int m, T value){
  45 + unsigned int c = coeff_1d(l, m);
  46 + C[c] = value;
  47 + }
  48 +
  49 + void setc(unsigned int c, T value){
  50 + C[c] = value;
  51 + }
  52 +
  53 + /// Initialize Monte-Carlo sampling of a function using N spherical harmonics coefficients
  54 +
  55 + /// @param N is the number of spherical harmonics coefficients used to represent the user function
  56 + void mcBegin(unsigned int coefficients){
  57 + C.resize(coefficients, 0);
  58 + mcN = 0;
  59 + }
  60 +
  61 + void mcBegin(unsigned int l, int m){
  62 + unsigned int c = pow(l + 1, 2) - (l - m);
  63 + mcBegin(c);
  64 + }
  65 +
  66 + void mcSample(double theta, double phi, double val){
  67 +
  68 + int l, m;
  69 + double sh;
  70 +
  71 + l = m = 0;
  72 + for(unsigned int i = 0; i < C.size(); i++){
  73 +
  74 + sh = SH(l, m, theta, phi);
  75 + C[i] += sh * val;
  76 +
  77 + m++; //increment m
  78 +
  79 + //if we're in a new tier, increment l and set m = -l
  80 + if(m > l){
  81 + l++;
  82 + m = -l;
  83 + }
  84 + } //end for all coefficients
  85 +
  86 + //increment the number of samples
  87 + mcN++;
  88 +
  89 + } //end mcSample()
  90 +
  91 + void mcEnd(){
  92 +
  93 + //divide all coefficients by the number of samples
  94 + for(unsigned int i = 0; i < C.size(); i++)
  95 + C[i] /= mcN;
  96 + }
  97 +
  98 + /// Generates a PDF describing the probability distribution of points on a spherical surface
  99 +
  100 + /// @param sph_pts is a list of points in spherical coordinates (theta, phi) where theta = [0, 2pi] and phi = [0, pi]
  101 + /// @param l is the maximum degree of the spherical harmonic function
  102 + /// @param m is the maximum order
  103 + void pdf(std::vector<stim::vec<double>> sph_pts, unsigned int l, int m){
  104 +
  105 + mcBegin( l, m ); //begin spherical harmonic sampling
  106 +
  107 + unsigned int nP = sph_pts.size();
  108 +
  109 + for(unsigned int p = 0; p < nP; p++){
  110 + mcSample(sph_pts[p][1], sph_pts[p][2], 1.0);
  111 + }
  112 +
  113 + mcEnd();
  114 + }
  115 +
  116 + std::string str(){
  117 +
  118 + std::stringstream ss;
  119 +
  120 + int l, m;
  121 + l = m = 0;
  122 + for(unsigned int i = 0; i < C.size(); i++){
  123 +
  124 + ss<<C[i]<<'\t';
  125 +
  126 + m++; //increment m
  127 +
  128 + //if we're in a new tier, increment l and set m = -l
  129 + if(m > l){
  130 + l++;
  131 + m = -l;
  132 +
  133 + ss<<std::endl;
  134 +
  135 + }
  136 + }
  137 +
  138 + return ss.str();
  139 +
  140 +
  141 + }
  142 +
  143 + /// Returns the value of the function at the coordinate (theta, phi)
  144 +
  145 + /// @param theta = [0, 2pi]
  146 + /// @param phi = [0, pi]
  147 + double operator()(double theta, double phi){
  148 +
  149 + double fx = 0;
  150 +
  151 + int l = 0;
  152 + int m = 0;
  153 + for(unsigned int i = 0; i < C.size(); i++){
  154 + fx += C[i] * SH(l, m, theta, phi);
  155 + m++;
  156 + if(m > l){
  157 + l++;
  158 + m = -l;
  159 + }
  160 +
  161 + }
  162 +
  163 + return fx;
  164 + }
  165 +
  166 +}; //end class sph_harmonics
  167 +
  168 +
  169 +
  170 +
  171 +}
  172 +
  173 +
  174 +#endif
... ...
stim/math/triangle.h
... ... @@ -3,12 +3,12 @@
3 3  
4 4 //enable CUDA_CALLABLE macro
5 5 #include "../cuda/callable.h"
6   -#include "../math/vector.h"
  6 +#include "../math/mathvec.h"
7 7 #include <iostream>
8 8  
9 9 namespace stim{
10 10  
11   -template <class T, int N=3>
  11 +template <class T>
12 12 struct triangle
13 13 {
14 14 /*
... ... @@ -23,15 +23,15 @@ struct triangle
23 23 */
24 24 private:
25 25  
26   - vec<T, N> A;
27   - vec<T, N> B;
28   - vec<T, N> C;
  26 + vec<T> A;
  27 + vec<T> B;
  28 + vec<T> C;
29 29  
30   - CUDA_CALLABLE vec<T, N> _p(T s, T t)
  30 + CUDA_CALLABLE vec<T> _p(T s, T t)
31 31 {
32 32 //This function returns the point specified by p = A + s(B-A) + t(C-A)
33   - vec<T, N> E0 = B-A;
34   - vec<T, N> E1 = C-A;
  33 + vec<T> E0 = B-A;
  34 + vec<T> E1 = C-A;
35 35  
36 36 return A + s*E0 + t*E1;
37 37 }
... ... @@ -46,26 +46,26 @@ struct triangle
46 46  
47 47 }
48 48  
49   - CUDA_CALLABLE triangle(vec<T, N> a, vec<T, N> b, vec<T, N> c)
  49 + CUDA_CALLABLE triangle(vec<T> a, vec<T> b, vec<T> c)
50 50 {
51 51 A = a;
52 52 B = b;
53 53 C = c;
54 54 }
55 55  
56   - CUDA_CALLABLE stim::vec<T, N> operator()(T s, T t)
  56 + CUDA_CALLABLE stim::vec<T> operator()(T s, T t)
57 57 {
58 58 return _p(s, t);
59 59 }
60 60  
61   - CUDA_CALLABLE vec<T, N> nearest(vec<T, N> p)
  61 + CUDA_CALLABLE vec<T> nearest(vec<T> p)
62 62 {
63 63 //comptue the distance between a point and this triangle
64 64 // This code is adapted from: http://www.geometrictools.com/Documentation/DistancePoint3Triangle3.pdf
65 65  
66   - vec<T, N> E0 = B-A;
67   - vec<T, N> E1 = C-A;
68   - vec<T, N> D = A - p;
  66 + vec<T> E0 = B-A;
  67 + vec<T> E1 = C-A;
  68 + vec<T> D = A - p;
69 69  
70 70 T a = E0.dot(E0);
71 71 T b = E0.dot(E1);
... ... @@ -175,9 +175,9 @@ struct triangle
175 175  
176 176 }
177 177  
178   - CUDA_CALLABLE T dist(vec<T, N> p)
  178 + CUDA_CALLABLE T dist(vec<T> p)
179 179 {
180   - vec<T, N> n = nearest(p);
  180 + vec<T> n = nearest(p);
181 181  
182 182 return (p - n).len();
183 183 }
... ...
stim/math/vector.h deleted
1   -#ifndef RTS_VECTOR_H
2   -#define RTS_VECTOR_H
3   -
4   -#include <iostream>
5   -#include <cmath>
6   -#include <sstream>
7   -//#include "rts/math/point.h"
8   -#include "../cuda/callable.h"
9   -
10   -
11   -namespace stim
12   -{
13   -
14   -
15   -
16   -template <class T, int N=3>
17   -struct vec
18   -{
19   - T v[N];
20   -
21   - CUDA_CALLABLE vec()
22   - {
23   - //memset(v, 0, sizeof(T) * N);
24   - for(int i=0; i<N; i++)
25   - v[i] = 0;
26   - }
27   -
28   - //efficiency constructor, makes construction easier for 1D-4D vectors
29   - CUDA_CALLABLE vec(T rhs)
30   - {
31   - for(int i=0; i<N; i++)
32   - v[i] = rhs;
33   - }
34   - CUDA_CALLABLE vec(T x, T y)
35   - {
36   - v[0] = x;
37   - v[1] = y;
38   - }
39   - CUDA_CALLABLE vec(T x, T y, T z)
40   - {
41   - v[0] = x;
42   - v[1] = y;
43   - v[2] = z;
44   - }
45   - CUDA_CALLABLE vec(T x, T y, T z, T w)
46   - {
47   - v[0] = x;
48   - v[1] = y;
49   - v[2] = z;
50   - v[3] = w;
51   - }
52   -
53   - //copy constructor
54   - CUDA_CALLABLE vec( const vec<T, N>& other){
55   - for(int i=0; i<N; i++)
56   - v[i] = other.v[i];
57   - }
58   -
59   -
60   - template< typename U >
61   - CUDA_CALLABLE operator vec<U, N>(){
62   - vec<U, N> result;
63   - for(int i=0; i<N; i++)
64   - result.v[i] = v[i];
65   -
66   - return result;
67   - }
68   -
69   - //template<class U>
70   - //friend vec<U, N>::operator vec<T, N>();
71   -
72   - CUDA_CALLABLE T len() const
73   - {
74   - //compute and return the vector length
75   - T sum_sq = (T)0;
76   - for(int i=0; i<N; i++)
77   - {
78   - sum_sq += v[i] * v[i];
79   - }
80   - return sqrt(sum_sq);
81   -
82   - }
83   -
84   - CUDA_CALLABLE vec<T, N> cart2sph() const
85   - {
86   - //convert the vector from cartesian to spherical coordinates
87   - //x, y, z -> r, theta, phi (where theta = 0 to 2*pi)
88   -
89   - vec<T, N> sph;
90   - sph[0] = std::sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
91   - sph[1] = std::atan2(v[1], v[0]);
92   - sph[2] = std::acos(v[2] / sph[0]);
93   -
94   - return sph;
95   - }
96   -
97   - CUDA_CALLABLE vec<T, N> sph2cart() const
98   - {
99   - //convert the vector from cartesian to spherical coordinates
100   - //r, theta, phi -> x, y, z (where theta = 0 to 2*pi)
101   -
102   - vec<T, N> cart;
103   - cart[0] = v[0] * std::cos(v[1]) * std::sin(v[2]);
104   - cart[1] = v[0] * std::sin(v[1]) * std::sin(v[2]);
105   - cart[2] = v[0] * std::cos(v[2]);
106   -
107   - return cart;
108   - }
109   -
110   - CUDA_CALLABLE vec<T, N> norm() const
111   - {
112   - //compute and return the vector norm
113   - vec<T, N> result;
114   -
115   - //compute the vector length
116   - T l = len();
117   -
118   - //normalize
119   - for(int i=0; i<N; i++)
120   - {
121   - result.v[i] = v[i] / l;
122   - }
123   -
124   - return result;
125   - }
126   -
127   - CUDA_CALLABLE vec<T, 3> cross(const vec<T, 3> rhs) const
128   - {
129   - vec<T, 3> result;
130   -
131   - //compute the cross product (only valid for 3D vectors)
132   - result[0] = v[1] * rhs.v[2] - v[2] * rhs.v[1];
133   - result[1] = v[2] * rhs.v[0] - v[0] * rhs.v[2];
134   - result[2] = v[0] * rhs.v[1] - v[1] * rhs.v[0];
135   -
136   - return result;
137   - }
138   -
139   - CUDA_CALLABLE T dot(vec<T, N> rhs) const
140   - {
141   - T result = (T)0;
142   -
143   - for(int i=0; i<N; i++)
144   - result += v[i] * rhs.v[i];
145   -
146   - return result;
147   -
148   - }
149   -
150   - //arithmetic
151   - CUDA_CALLABLE vec<T, N> operator+(vec<T, N> rhs) const
152   - {
153   - vec<T, N> result;
154   -
155   - for(int i=0; i<N; i++)
156   - result.v[i] = v[i] + rhs.v[i];
157   -
158   - return result;
159   - }
160   - CUDA_CALLABLE vec<T, N> operator+(T rhs) const
161   - {
162   - vec<T, N> result;
163   -
164   - for(int i=0; i<N; i++)
165   - result.v[i] = v[i] + rhs;
166   -
167   - return result;
168   - }
169   - CUDA_CALLABLE vec<T, N> operator-(vec<T, N> rhs) const
170   - {
171   - vec<T, N> result;
172   -
173   - for(int i=0; i<N; i++)
174   - result.v[i] = v[i] - rhs.v[i];
175   -
176   - return result;
177   - }
178   - CUDA_CALLABLE vec<T, N> operator*(T rhs) const
179   - {
180   - vec<T, N> result;
181   -
182   - for(int i=0; i<N; i++)
183   - result.v[i] = v[i] * rhs;
184   -
185   - return result;
186   - }
187   - CUDA_CALLABLE vec<T, N> operator/(T rhs) const
188   - {
189   - vec<T, N> result;
190   -
191   - for(int i=0; i<N; i++)
192   - result.v[i] = v[i] / rhs;
193   -
194   - return result;
195   - }
196   - CUDA_CALLABLE vec<T, N> operator*=(T rhs){
197   - for(int i=0; i<N; i++)
198   - v[i] = v[i] * rhs;
199   - return *this;
200   - }
201   - CUDA_CALLABLE vec<T, N> & operator=(T rhs){
202   - for(int i=0; i<N; i++)
203   - v[i] = rhs;
204   - return *this;
205   - }
206   - template<typename Y>
207   - CUDA_CALLABLE vec<T, N> & operator=(vec<Y, N> rhs){
208   - for(int i=0; i<N; i++)
209   - v[i] = rhs.v[i];
210   - return *this;
211   - }
212   - //unary minus
213   - CUDA_CALLABLE vec<T, N> operator-() const{
214   - vec<T, N> r;
215   -
216   - //negate the vector
217   - for(int i=0; i<N; i++)
218   - r.v[i] = -v[i];
219   -
220   - return r;
221   - }
222   -
223   - CUDA_CALLABLE bool operator==(vec<T, N> rhs) const
224   - {
225   - if ( (rhs.v[0] == v[0]) && (rhs.v[1] == v[1]) && (rhs.v[2] == v[2]) )
226   - return true;
227   -
228   - return false;
229   - }
230   -
231   - std::string str() const
232   - {
233   - std::stringstream ss;
234   -
235   - ss<<"[";
236   - for(int i=0; i<N; i++)
237   - {
238   - ss<<v[i];
239   - if(i != N-1)
240   - ss<<", ";
241   - }
242   - ss<<"]";
243   -
244   - return ss.str();
245   - }
246   -
247   - //bracket operator - allows assignment to the vector
248   - CUDA_CALLABLE T& operator[](const unsigned int i)
249   - {
250   - return v[i];
251   - }
252   -
253   -};
254   -
255   -
256   -} //end namespace rts
257   -
258   -template <typename T, int N>
259   -std::ostream& operator<<(std::ostream& os, stim::vec<T, N> v)
260   -{
261   - os<<v.str();
262   - return os;
263   -}
264   -
265   -
266   -
267   -template <typename T, int N>
268   -CUDA_CALLABLE stim::vec<T, N> operator*(T lhs, stim::vec<T, N> rhs)
269   -{
270   - stim::vec<T, N> r;
271   -
272   - return rhs * lhs;
273   -}
274   -
275   -//#if __GNUC__ > 3 && __GNUC_MINOR__ > 7
276   -//template<class T, int N> using rtsVector = rts::vector<T, N>;
277   -//#endif
278   -
279   -#endif
stim/visualization/camera.h
1   -#include "../math/vector.h"
  1 +#include "../math/mathvec.h"
2 2 #include "../math/quaternion.h"
3 3 #include "../math/matrix.h"
4 4  
... ... @@ -11,32 +11,32 @@ namespace stim{
11 11  
12 12 class camera
13 13 {
14   - vec<float, 3> d; //direction that the camera is pointing
15   - vec<float, 3> p; //position of the camera
16   - vec<float, 3> up; //"up" direction
  14 + vec<float> d; //direction that the camera is pointing
  15 + vec<float> p; //position of the camera
  16 + vec<float> up; //"up" direction
17 17 float focus; //focal length of the camera
18 18 float fov;
19 19  
20 20 //private function makes sure that the up vector is orthogonal to the direction vector and both are normalized
21 21 void stabalize()
22 22 {
23   - vec<float, 3> side = up.cross(d);
  23 + vec<float> side = up.cross(d);
24 24 up = d.cross(side);
25 25 up = up.norm();
26 26 d = d.norm();
27 27 }
28 28  
29 29 public:
30   - void setPosition(vec<float, 3> pos)
  30 + void setPosition(vec<float> pos)
31 31 {
32 32 p = pos;
33 33 }
34   - void setPosition(float x, float y, float z){setPosition(vec<float, 3>(x, y, z));}
  34 + void setPosition(float x, float y, float z){setPosition(vec<float>(x, y, z));}
35 35  
36 36 void setFocalDistance(float distance){focus = distance;}
37 37 void setFOV(float field_of_view){fov = field_of_view;}
38 38  
39   - void LookAt(vec<float, 3> pos)
  39 + void LookAt(vec<float> pos)
40 40 {
41 41 //find the new direction
42 42 d = pos - p;
... ... @@ -47,22 +47,22 @@ public:
47 47 //stabalize the camera
48 48 stabalize();
49 49 }
50   - void LookAt(float px, float py, float pz){LookAt(vec<float, 3>(px, py, pz));}
51   - void LookAt(vec<float, 3> pos, vec<float, 3> new_up){up = new_up; LookAt(pos);}
52   - void LookAt(float px, float py, float pz, float ux, float uy, float uz){LookAt(vec<float, 3>(px, py, pz), vec<float, 3>(ux, uy, uz));}
  50 + void LookAt(float px, float py, float pz){LookAt(vec<float>(px, py, pz));}
  51 + void LookAt(vec<float> pos, vec<float> new_up){up = new_up; LookAt(pos);}
  52 + void LookAt(float px, float py, float pz, float ux, float uy, float uz){LookAt(vec<float>(px, py, pz), vec<float>(ux, uy, uz));}
53 53 void LookAtDolly(float lx, float ly, float lz)
54 54 {
55 55 //find the current focus point
56   - vec<float, 3> f = p + focus*d;
57   - vec<float, 3> T = vec<float, 3>(lx, ly, lz) - f;
  56 + vec<float> f = p + focus*d;
  57 + vec<float> T = vec<float>(lx, ly, lz) - f;
58 58 p = p + T;
59 59 }
60 60  
61   - void Dolly(vec<float, 3> direction)
  61 + void Dolly(vec<float> direction)
62 62 {
63 63 p = p+direction;
64 64 }
65   - void Dolly(float x, float y, float z){Dolly(vec<float, 3>(x, y, z));}
  65 + void Dolly(float x, float y, float z){Dolly(vec<float>(x, y, z));}
66 66 void Push(float delta)
67 67 {
68 68 if(delta > focus)
... ... @@ -80,7 +80,7 @@ public:
80 80 qx.CreateRotation(theta_x, up[0], up[1], up[2]);
81 81  
82 82 //y rotation is around the side axis
83   - vec<float, 3> side = up.cross(d);
  83 + vec<float> side = up.cross(d);
84 84 quaternion<float> qy;
85 85 qy.CreateRotation(theta_y, side[0], side[1], side[2]);
86 86  
... ... @@ -118,28 +118,28 @@ public:
118 118 void OrbitFocus(float theta_x, float theta_y)
119 119 {
120 120 //find the focal point
121   - vec<float, 3> focal_point = p + focus*d;
  121 + vec<float> focal_point = p + focus*d;
122 122  
123 123 //center the coordinate system on the focal point
124   - vec<float, 3> centered = p - (focal_point - vec<float, 3>(0, 0, 0));
  124 + vec<float> centered = p - (focal_point - vec<float>(0, 0, 0));
125 125  
126 126 //create the x rotation (around the up vector)
127 127 quaternion<float> qx;
128 128 qx.CreateRotation(theta_x, up[0], up[1], up[2]);
129   - centered = vec<float, 3>(0, 0, 0) + qx.toMatrix3()*(centered - vec<float, 3>(0, 0, 0));
  129 + centered = vec<float>(0, 0, 0) + qx.toMatrix3()*(centered - vec<float>(0, 0, 0));
130 130  
131 131 //get a side vector for theta_y rotation
132   - vec<float, 3> side = up.cross((vec<float, 3>(0, 0, 0) - centered).norm());
  132 + vec<float> side = up.cross((vec<float>(0, 0, 0) - centered).norm());
133 133  
134 134 quaternion<float> qy;
135 135 qy.CreateRotation(theta_y, side[0], side[1], side[2]);
136   - centered = vec<float, 3>(0, 0, 0) + qy.toMatrix3()*(centered - vec<float, 3>(0, 0, 0));
  136 + centered = vec<float>(0, 0, 0) + qy.toMatrix3()*(centered - vec<float>(0, 0, 0));
137 137  
138 138 //perform the rotation on the centered camera position
139 139 //centered = final.toMatrix()*centered;
140 140  
141 141 //re-position the camera
142   - p = centered + (focal_point - vec<float, 3>(0, 0, 0));
  142 + p = centered + (focal_point - vec<float>(0, 0, 0));
143 143  
144 144 //make sure we are looking at the focal point
145 145 LookAt(focal_point);
... ... @@ -151,21 +151,21 @@ public:
151 151  
152 152 void Slide(float u, float v)
153 153 {
154   - vec<float, 3> V = up.norm();
155   - vec<float, 3> U = up.cross(d).norm();
  154 + vec<float> V = up.norm();
  155 + vec<float> U = up.cross(d).norm();
156 156  
157 157 p = p + (V * v) + (U * u);
158 158 }
159 159  
160 160 //accessor methods
161   - vec<float, 3> getPosition(){return p;}
162   - vec<float, 3> getUp(){return up;}
163   - vec<float, 3> getDirection(){return d;}
164   - vec<float, 3> getLookAt(){return p + focus*d;}
  161 + vec<float> getPosition(){return p;}
  162 + vec<float> getUp(){return up;}
  163 + vec<float> getDirection(){return d;}
  164 + vec<float> getLookAt(){return p + focus*d;}
165 165 float getFOV(){return fov;}
166 166  
167 167 //output the camera settings
168   - const void print(std::ostream& output)
  168 + void print(std::ostream& output)
169 169 {
170 170 output<<"Position: "<<p.str()<<std::endl;
171 171  
... ... @@ -182,9 +182,9 @@ public:
182 182 //constructor
183 183 camera()
184 184 {
185   - p = vec<float, 3>(0, 0, 0);
186   - d = vec<float, 3>(0, 0, 1);
187   - up = vec<float, 3>(0, 1, 0);
  185 + p = vec<float>(0, 0, 0);
  186 + d = vec<float>(0, 0, 1);
  187 + up = vec<float>(0, 1, 0);
188 188 focus = 1;
189 189  
190 190 }
... ...
stim/visualization/sph_harmonics.h renamed to stim/visualization/gl_spharmonics.h
1   -#ifndef STIM_SPH_HARMONICS
2   -#define STIM_SPH_HARMONICS
  1 +#ifndef STIM_GL_SPHARMONICS_H
  2 +#define STIM_GL_SPHARMONICS_H
3 3  
4 4 #include <GL/gl.h>
5 5  
6 6 #include <stim/gl/error.h>
7 7 #include <stim/visualization/colormap.h>
8   -#include <vector>
  8 +#include <stim/math/spharmonics.h>
9 9  
10   -#define PI 3.14159
11   -#define WIRE_SCALE 1.001
12 10 namespace stim{
13 11  
14   - class sph_harmonics{
  12 +
  13 +template <typename T>
  14 +class gl_spharmonics : public spharmonics<T>{
15 15  
16   - private:
  16 +protected:
  17 +
  18 + T* func; //stores the raw function data (samples at each point)
17 19  
18   - double* func; //stores the raw function data (samples at each point)
  20 + GLuint color_tex; //texture map that acts as a colormap for the spherical function
  21 +
  22 + unsigned int N; //resolution of the spherical grid
19 23  
20   - GLuint color_tex; //texture map that acts as a colormap for the spherical function
21   -
22   - unsigned int N; //resolution of the spherical grid
  24 + void gen_function(){
23 25  
24   - std::vector<double> C; //list of SH coefficients
  26 + //initialize the function to zero
  27 + memset(func, 0, sizeof(double) * N * N);
25 28  
  29 + double theta, phi;
  30 + double result;
  31 + int l, m;
26 32  
27   - //evaluates an associated Legendre polynomial (-l <= m <= l)
28   - double P(int l,int m,double x)
29   - {
30   - // evaluate an Associated Legendre Polynomial P(l,m,x) at x
31   - double pmm = 1.0;
32   - if(m>0) {
33   - double somx2 = sqrt((1.0-x)*(1.0+x));
34   - double fact = 1.0;
35   - for(int i=1; i<=m; i++) {
36   - pmm *= (-fact) * somx2;
37   - fact += 2.0;
38   - }
39   - }
40   - if(l==m) return pmm;
41   - double pmmp1 = x * (2.0*m+1.0) * pmm;
42   - if(l==m+1) return pmmp1;
43   - double pll = 0.0;
44   - for(int ll=m+2; ll<=l; ++ll) {
45   - pll = ( (2.0*ll-1.0)*x*pmmp1-(ll+m-1.0)*pmm ) / (ll-m);
46   - pmm = pmmp1;
47   - pmmp1 = pll;
48   - }
49   - return pll;
50   - }
51 33  
52   - //recursively calculate a factorial given a positive integer n
53   - unsigned int factorial(unsigned int n) {
54   - if (n == 0)
55   - return 1;
56   - return n * factorial(n - 1);
57   - }
58   -
59   - //calculate the SH scaling constant
60   - double K(int l, int m){
  34 + l = m = 0;
  35 + //for each coefficient
  36 + for(unsigned int c = 0; c < C.size(); c++){
61 37  
62   - // renormalisation constant for SH function
63   - double temp = ((2.0*l+1.0)*factorial(l-m)) / (4.0*PI*factorial(l+m));
64   - return sqrt(temp);
65   - }
  38 + //iterate through the entire 2D grid representing the function
  39 + for(unsigned int xi = 0; xi < N; xi++){
  40 + for(unsigned int yi = 0; yi < N; yi++){
66 41  
67   - //calculate the value of the SH basis function (l, m) at (theta, phi)
68   - //here, theta = [0, PI], phi = [0, 2*PI]
69   - double SH(int l, int m, double theta, double phi){
70   - // return a point sample of a Spherical Harmonic basis function
71   - // l is the band, range [0..N]
72   - // m in the range [-l..l]
73   - // theta in the range [0..Pi]
74   - // phi in the range [0..2*Pi]
75   - const double sqrt2 = sqrt(2.0);
76   - if(m==0) return K(l,0)*P(l,m,cos(theta));
77   - else if(m>0) return sqrt2*K(l,m)*cos(m*phi)*P(l,m,cos(theta));
78   - else return sqrt2*K(l,-m)*sin(-m*phi)*P(l,-m,cos(theta));
79   - }
  42 + //get the spherical coordinates for each grid point
  43 + theta = (2 * PI) * ((double)xi / (N-1));
  44 + phi = PI * ((double)yi / (N-1));
80 45  
81   - void gen_function(){
  46 + //sum the contribution of the current spherical harmonic based on the coefficient
  47 + result = C[c] * SH(l, m, theta, phi);
82 48  
83   - //initialize the function to zero
84   - memset(func, 0, sizeof(double) * N * N);
85   -
86   - double theta, phi;
87   - double result;
88   - int l, m;
89   -
90   - l = m = 0;
91   - for(unsigned int c = 0; c < C.size(); c++){
92   -
93   -
94   - for(unsigned int xi = 0; xi < N; xi++)
95   - for(unsigned int yi = 0; yi < N; yi++){
96   -
97   - theta = (2 * PI) * ((double)xi / (N-1));
98   - phi = PI * ((double)yi / (N-1));
99   - result = C[c] * SH(l, m, phi, theta); //phi and theta are reversed here (damn physicists)
100   - func[yi * N + xi] += result;
101   - }
102   -
103   - m++; //increment m
104   -
105   - //if we're in a new tier, increment l and set m = -l
106   - if(m > l){
107   - l++;
108   - m = -l;
  49 + //store the result in a 2D array (which will later be used as a texture map)
  50 + func[yi * N + xi] += result;
109 51 }
110 52 }
111   - }
112   -
113   - void gl_prep_draw(){
114 53  
115   - //enable depth testing
116   - //this has to be used instead of culling because the sphere can have negative values
117   - glEnable(GL_DEPTH_TEST);
118   - glDepthMask(GL_TRUE);
119   - glEnable(GL_TEXTURE_2D); //enable 2D texture mapping
  54 + //keep track of m and l here
  55 + m++; //increment m
  56 + //if we're in a new tier, increment l and set m = -l
  57 + if(m > l){
  58 + l++;
  59 + m = -l;
  60 + }
120 61 }
  62 + }
121 63  
122   - //draw a texture mapped sphere representing the function surface
123   - void gl_draw_sphere() {
124   -
125   - //PI is used to convert from spherical to cartesian coordinates
126   - //const double PI = 3.14159;
127   -
128   - //bind the 2D texture representing the color map
129   - glBindTexture(GL_TEXTURE_2D, color_tex);
130   -
131   - //Draw the Sphere
132   - int i, j;
133   -
134   - for(i = 1; i <= N-1; i++) {
135   - double phi0 = PI * ((double) (i - 1) / (N-1));
136   - double phi1 = PI * ((double) i / (N-1));
137   -
138   - glBegin(GL_QUAD_STRIP);
139   - for(j = 0; j <= N; j++) {
140   -
141   - //calculate the indices into the function array
142   - int phi0_i = i-1;
143   - int phi1_i = i;
144   - int theta_i = j;
145   - if(theta_i == N)
146   - theta_i = 0;
147   -
148   - double v0 = func[phi0_i * N + theta_i];
149   - double v1 = func[phi1_i * N + theta_i];
150   -
151   - v0 = fabs(v0);
152   - v1 = fabs(v1);
153   -
154   -
155   - double theta = 2 * PI * (double) (j - 1) / N;
156   - double x0 = v0 * cos(theta) * sin(phi0);
157   - double y0 = v0 * sin(theta) * sin(phi0);
158   - double z0 = v0 * cos(phi0);
159   -
160   - double x1 = v1 * cos(theta) * sin(phi1);
161   - double y1 = v1 * sin(theta) * sin(phi1);
162   - double z1 = v1 * cos(phi1);
163   -
164   - glTexCoord2f(theta / (2 * PI), phi0 / PI);
165   - glVertex3f(x0, y0, z0);
166   -
167   - glTexCoord2f(theta / (2 * PI), phi1 / PI);
168   - glVertex3f(x1, y1, z1);
169   - }
170   - glEnd();
171   - }
172   - }
  64 + void gl_prep_draw(){
173 65  
174   - //draw a wire frame sphere representing the function surface
175   - void gl_draw_wireframe() {
  66 + //enable depth testing
  67 + //this has to be used instead of culling because the sphere can have negative values
  68 + glEnable(GL_DEPTH_TEST);
  69 + glDepthMask(GL_TRUE);
  70 + glEnable(GL_TEXTURE_2D); //enable 2D texture mapping
  71 + }
176 72  
177   - //PI is used to convert from spherical to cartesian coordinates
178   - //const double PI = 3.14159;
  73 + //draw a texture mapped sphere representing the function surface
  74 + void gl_draw_sphere() {
179 75  
180   - //bind the 2D texture representing the color map
181   - glDisable(GL_TEXTURE_2D);
182   - glColor3f(0.0f, 0.0f, 0.0f);
  76 + //bind the 2D texture representing the color map
  77 + glBindTexture(GL_TEXTURE_2D, color_tex);
183 78  
184   - //Draw the Sphere
185   - int i, j;
  79 + //Draw the Sphere
  80 + int i, j;
186 81  
187   - for(i = 1; i <= N-1; i++) {
188   - double phi0 = PI * ((double) (i - 1) / (N-1));
189   - double phi1 = PI * ((double) i / (N-1));
  82 + for(i = 1; i <= N-1; i++) {
  83 + double phi0 = PI * ((double) (i - 1) / (N-1));
  84 + double phi1 = PI * ((double) i / (N-1));
190 85  
191   - glBegin(GL_LINE_STRIP);
192   - for(j = 0; j <= N; j++) {
  86 + glBegin(GL_QUAD_STRIP);
  87 + for(j = 0; j <= N; j++) {
193 88  
194   - //calculate the indices into the function array
195   - int phi0_i = i-1;
196   - int phi1_i = i;
197   - int theta_i = j;
198   - if(theta_i == N)
199   - theta_i = 0;
  89 + //calculate the indices into the function array
  90 + int phi0_i = i-1;
  91 + int phi1_i = i;
  92 + int theta_i = j;
  93 + if(theta_i == N)
  94 + theta_i = 0;
200 95  
201   - double v0 = func[phi0_i * N + theta_i];
202   - double v1 = func[phi1_i * N + theta_i];
  96 + double v0 = func[phi0_i * N + theta_i];
  97 + double v1 = func[phi1_i * N + theta_i];
203 98  
204   - v0 = fabs(v0);
205   - v1 = fabs(v1);
  99 + v0 = fabs(v0);
  100 + v1 = fabs(v1);
206 101  
207 102  
208   - double theta = 2 * PI * (double) (j - 1) / N;
209   - double x0 = WIRE_SCALE * v0 * cos(theta) * sin(phi0);
210   - double y0 = WIRE_SCALE * v0 * sin(theta) * sin(phi0);
211   - double z0 = WIRE_SCALE * v0 * cos(phi0);
  103 + double theta = 2 * PI * (double) (j - 1) / N;
  104 + double x0 = v0 * cos(theta) * sin(phi0);
  105 + double y0 = v0 * sin(theta) * sin(phi0);
  106 + double z0 = v0 * cos(phi0);
212 107  
213   - double x1 = WIRE_SCALE * v1 * cos(theta) * sin(phi1);
214   - double y1 = WIRE_SCALE * v1 * sin(theta) * sin(phi1);
215   - double z1 = WIRE_SCALE * v1 * cos(phi1);
  108 + double x1 = v1 * cos(theta) * sin(phi1);
  109 + double y1 = v1 * sin(theta) * sin(phi1);
  110 + double z1 = v1 * cos(phi1);
216 111  
217   - glTexCoord2f(theta / (2 * PI), phi0 / PI);
218   - glVertex3f(x0, y0, z0);
  112 + glTexCoord2f(theta / (2 * PI), phi0 / PI);
  113 + glVertex3f(x0, y0, z0);
219 114  
220   - glTexCoord2f(theta / (2 * PI), phi1 / PI);
221   - glVertex3f(x1, y1, z1);
222   - }
223   - glEnd();
224   - }
225   - }
  115 + glTexCoord2f(theta / (2 * PI), phi1 / PI);
  116 + glVertex3f(x1, y1, z1);
  117 + }
  118 + glEnd();
  119 + }
  120 + }
226 121  
227   - void init(unsigned int n){
  122 + void gl_init(unsigned int n){
228 123  
229   - //set the sphere resolution
230   - N = n;
  124 + //set the sphere resolution
  125 + N = n;
231 126  
232   - //allocate space for the color map
233   - unsigned int bytes = N * N * sizeof(unsigned char) * 3;
234   - unsigned char* color_image;
235   - color_image = (unsigned char*) malloc(bytes);
  127 + //allocate space for the color map
  128 + unsigned int bytes = N * N * sizeof(unsigned char) * 3;
  129 + unsigned char* color_image;
  130 + color_image = (unsigned char*) malloc(bytes);
236 131  
237   - //allocate space for the function
238   - func = (double*) malloc(N * N * sizeof(double));
  132 + //allocate space for the function
  133 + func = (double*) malloc(N * N * sizeof(double));
239 134  
240   - //generate a function (temporary)
241   - gen_function();
  135 + //generate a functional representation that will be used for the texture map and vertices
  136 + gen_function();
242 137  
243   - //generate a colormap from the function
244   - stim::cpu2cpu<double>(func, color_image, N*N, stim::cmBrewer);
  138 + //generate a colormap from the function
  139 + stim::cpu2cpu<double>(func, color_image, N*N, stim::cmBrewer);
245 140  
246   - //prep everything for drawing
247   - gl_prep_draw();
  141 + //prep everything for drawing
  142 + gl_prep_draw();
248 143  
249   - //generate an OpenGL texture map in the current context
250   - glGenTextures(1, &color_tex);
251   - //bind the texture
252   - glBindTexture(GL_TEXTURE_2D, color_tex);
  144 + //generate an OpenGL texture map in the current context
  145 + glGenTextures(1, &color_tex);
  146 + //bind the texture
  147 + glBindTexture(GL_TEXTURE_2D, color_tex);
253 148  
254   - //copy the color data from the buffer to the GPU
255   - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, N, N, 0, GL_RGB, GL_UNSIGNED_BYTE, color_image);
  149 + //copy the color data from the buffer to the GPU
  150 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, N, N, 0, GL_RGB, GL_UNSIGNED_BYTE, color_image);
256 151  
257   - //initialize all of the texture parameters
258   - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
259   - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
260   - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
261   - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
262   - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  152 + //initialize all of the texture parameters
  153 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  154 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  155 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  156 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  157 + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
263 158  
264   - //free the buffer
265   - free(color_image);
266   - }
267   -
268   -
269   - public:
  159 + //free the buffer
  160 + free(color_image);
  161 + }
270 162  
271   - void glRender(){
272   - //set all OpenGL parameters required for drawing
273   - gl_prep_draw();
274   -
275   - //draw the sphere
276   - gl_draw_sphere();
277   - //gl_draw_wireframe();
278   -
279   - }
280   -
281   - void glInit(unsigned int n){
282   - init(n);
283   - }
284   -
285   - void push(double c){
286   - C.push_back(c);
287   - }
  163 +public:
288 164  
  165 + void glRender(){
  166 + //set all OpenGL parameters required for drawing
  167 + gl_prep_draw();
289 168  
  169 + //draw the sphere
  170 + gl_draw_sphere();
  171 + }
290 172  
  173 + void glInit(unsigned int n = 256){
  174 + gl_init(n);
  175 + gen_function();
  176 + }
291 177  
292 178  
293   - }; //end class sph_harmonics
  179 +}; //end gl_spharmonics
294 180  
295 181  
  182 +}; //end namespace stim
296 183  
297 184  
298   -}
299 185  
300 186  
301   -#endif
  187 +#endif
302 188 \ No newline at end of file
... ...
stim/visualization/obj.h
... ... @@ -6,6 +6,7 @@
6 6 #include <fstream>
7 7 #include <stdlib.h>
8 8 #include <stim/parser/parser.h>
  9 +#include <stim/math/mathvec.h>
9 10  
10 11 namespace stim{
11 12  
... ... @@ -34,37 +35,14 @@ protected:
34 35  
35 36 enum token_type { OBJ_INVALID, OBJ_V, OBJ_VT, OBJ_VN, OBJ_P, OBJ_L, OBJ_F };
36 37  
37   - struct vertex : public std::vector<T>{
  38 + struct vertex : public stim::vec<T>{
38 39  
39   - using std::vector<T>::push_back;
40   - using std::vector<T>::size;
41   - using std::vector<T>::at;
  40 + using vec<T>::push_back;
  41 + using vec<T>::size;
  42 + using vec<T>::at;
42 43  
43 44 vertex(){}
44 45  
45   - //constructors for quickly building vertices with arbitrary numbers of components
46   - vertex(T x){
47   - push_back(x);
48   - }
49   -
50   - vertex(T x, T y){
51   - push_back(x);
52   - push_back(y);
53   - }
54   -
55   - vertex(T x, T y, T z){
56   - push_back(x);
57   - push_back(y);
58   - push_back(z);
59   - }
60   -
61   - vertex(T x, T y, T z, T w){
62   - push_back(x);
63   - push_back(y);
64   - push_back(z);
65   - push_back(w);
66   - }
67   -
68 46 //constructor creates a vertex from a line string
69 47 vertex(std::string line){
70 48  
... ... @@ -305,6 +283,11 @@ protected:
305 283 }
306 284  
307 285 public:
  286 + /// Constructor loads a Wavefront OBJ file
  287 + obj(std::string filename){
  288 + load(filename);
  289 + }
  290 +
308 291 //functions for setting the texture coordinate for the next vertex
309 292 void TexCoord(T x){ update_vt(vertex(x));}
310 293 void TexCoord(T x, T y){ update_vt(vertex(x, y));}
... ... @@ -504,6 +487,47 @@ public:
504 487  
505 488 }
506 489  
  490 + /// Return the number of position vertices in the OBJ model
  491 + unsigned int numV(){
  492 + return V.size();
  493 + }
  494 +
  495 + /// Retrieve the vertex stored in index i
  496 +
  497 + /// @param i is the desired vertex index
  498 + stim::vec<T> getV(unsigned int i){
  499 +
  500 + stim::vec<T> v = V[i];
  501 + return v;
  502 + }
  503 +
  504 + stim::vec<T> centroid(){
  505 +
  506 + //get the number of coordinates
  507 + unsigned int N = V[0].size();
  508 +
  509 + //allocate space for the minimum and maximum coordinate points (bounding box corners)
  510 + stim::vec<float> vmin, vmax;
  511 + vmin.resize(N);
  512 + vmax.resize(N);
  513 +
  514 + //find the minimum and maximum value for each coordinate
  515 + unsigned int NV = V.size();
  516 + for(unsigned int v = 0; v < NV; v++)
  517 + for(unsigned int i = 0; i < N; i++){
  518 +
  519 + if(V[v][i] < vmin[i])
  520 + vmin[i] = V[v][i];
  521 + if(V[v][i] > vmax[i])
  522 + vmax[i] = V[v][i];
  523 + }
  524 +
  525 + //find the centroid using the min and max points
  526 + stim::vec<T> c = vmin * 0.5 + vmax * 0.5;
  527 +
  528 + return c;
  529 + }
  530 +
507 531  
508 532 };
509 533  
... ...