Commit 5eeaf94149e3255107b2bc3f48446c88acfbdf65
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
Showing
14 changed files
with
839 additions
and
690 deletions
Show diff stats
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()); | ... | ... |
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; | ... | ... |
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 | ... | ... |