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,8 +67,8 @@ void get_diff (float *result) | ||
67 | 67 | ||
68 | float valIn = tex2D(texIn, x, y)/255.0; | 68 | float valIn = tex2D(texIn, x, y)/255.0; |
69 | float valTemp = Template(x); | 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,7 +10,7 @@ | ||
10 | #include "stim/gl/gl_texture.h" | 10 | #include "stim/gl/gl_texture.h" |
11 | #include "stim/visualization/camera.h" | 11 | #include "stim/visualization/camera.h" |
12 | #include "stim/gl/error.h" | 12 | #include "stim/gl/error.h" |
13 | -#include "stim/math/vector.h" | 13 | +#include "stim/math/mathvec.h" |
14 | #include "stim/math/rect.h" | 14 | #include "stim/math/rect.h" |
15 | #include "stim/math/matrix.h" | 15 | #include "stim/math/matrix.h" |
16 | #include "stim/cuda/cost.h" | 16 | #include "stim/cuda/cost.h" |
@@ -64,19 +64,22 @@ class gl_spider | @@ -64,19 +64,22 @@ class gl_spider | ||
64 | findOptimalDirection() | 64 | findOptimalDirection() |
65 | { | 65 | { |
66 | //genTemplate(dV, 0); | 66 | //genTemplate(dV, 0); |
67 | + cout << "Direction Before: " << d << endl; | ||
67 | setMatrix(); | 68 | setMatrix(); |
68 | glCallList(dList); | 69 | glCallList(dList); |
69 | int best = getCost(); | 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 | next = (cT*next).norm(); | 77 | next = (cT*next).norm(); |
76 | setPosition( p[0]+next[0]*m[0]/stepsize, | 78 | setPosition( p[0]+next[0]*m[0]/stepsize, |
77 | p[1]+next[1]*m[0]/stepsize, | 79 | p[1]+next[1]*m[0]/stepsize, |
78 | p[2]+next[2]*m[0]/stepsize); | 80 | p[2]+next[2]*m[0]/stepsize); |
79 | setDirection(next[0], next[1], next[2]); | 81 | setDirection(next[0], next[1], next[2]); |
82 | + cout << "Direction After: " << d << endl; | ||
80 | } | 83 | } |
81 | 84 | ||
82 | /// Method for finding the best d for the spider. | 85 | /// Method for finding the best d for the spider. |
@@ -88,16 +91,16 @@ class gl_spider | @@ -88,16 +91,16 @@ class gl_spider | ||
88 | setMatrix(); | 91 | setMatrix(); |
89 | glCallList(dList+1); | 92 | glCallList(dList+1); |
90 | int best = getCost(); | 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 | next = cT*next; | 99 | next = cT*next; |
97 | - std::cout << "Optimal p:"<< next << std::endl; | ||
98 | setPosition( next[0]*S[0]*R[0], | 100 | setPosition( next[0]*S[0]*R[0], |
99 | next[1]*S[1]*R[1], | 101 | next[1]*S[1]*R[1], |
100 | next[2]*S[2]*R[2]); | 102 | next[2]*S[2]*R[2]); |
103 | + std::cout << "Optimal p:"<< p << std::endl; | ||
101 | } | 104 | } |
102 | 105 | ||
103 | /// Method for finding the best scale for the spider. | 106 | /// Method for finding the best scale for the spider. |
@@ -109,11 +112,11 @@ class gl_spider | @@ -109,11 +112,11 @@ class gl_spider | ||
109 | setMatrix(); | 112 | setMatrix(); |
110 | glCallList(dList+2); | 113 | glCallList(dList+2); |
111 | int best = getCost(); | 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 | next = cT*next; | 120 | next = cT*next; |
118 | std::cout << "Optimal Scale:"<< next << std::endl; | 121 | std::cout << "Optimal Scale:"<< next << std::endl; |
119 | setMagnitude(next[0]); | 122 | setMagnitude(next[0]); |
@@ -123,7 +126,7 @@ class gl_spider | @@ -123,7 +126,7 @@ class gl_spider | ||
123 | branchDetection() | 126 | branchDetection() |
124 | { | 127 | { |
125 | Bind(); | 128 | Bind(); |
126 | - positionTemplate(); | 129 | + setMatrix(); |
127 | glCallList(dList+3); | 130 | glCallList(dList+3); |
128 | 131 | ||
129 | int best = getCost(); | 132 | int best = getCost(); |
@@ -151,16 +154,17 @@ class gl_spider | @@ -151,16 +154,17 @@ class gl_spider | ||
151 | void | 154 | void |
152 | genDirectionVectors(float solidAngle = M_PI) | 155 | genDirectionVectors(float solidAngle = M_PI) |
153 | { | 156 | { |
157 | + //ofstream file; | ||
158 | + //file.open("dvectors.txt"); | ||
154 | //Set up the vectors necessary for Rectangle creation. | 159 | //Set up the vectors necessary for Rectangle creation. |
155 | vec<float> Y(1.0,0.0,0.0); | 160 | vec<float> Y(1.0,0.0,0.0); |
156 | vec<float> pos(0.0,0.0,0.0); | 161 | vec<float> pos(0.0,0.0,0.0); |
157 | vec<float> mag(1.0, 1.0, 1.0); | 162 | vec<float> mag(1.0, 1.0, 1.0); |
158 | vec<float> dir(0.0, 0.0, 1.0); | 163 | vec<float> dir(0.0, 0.0, 1.0); |
159 | 164 | ||
160 | - vec<float> d_s = direction.cart2sph().norm(); | ||
161 | //Set up the variable necessary for vector creation. | 165 | //Set up the variable necessary for vector creation. |
162 | vec<float> d_s = d.cart2sph().norm(); | 166 | vec<float> d_s = d.cart2sph().norm(); |
163 | - vec<float> temp; | 167 | + vec<float> temp(0,0,0); |
164 | int dim = (sqrt(numSamples)-1)/2; | 168 | int dim = (sqrt(numSamples)-1)/2; |
165 | float p0 = -M_PI; | 169 | float p0 = -M_PI; |
166 | float dt = solidAngle/(2.0 * ((float)dim + 1.0)); | 170 | float dt = solidAngle/(2.0 * ((float)dim + 1.0)); |
@@ -171,7 +175,7 @@ class gl_spider | @@ -171,7 +175,7 @@ class gl_spider | ||
171 | int idx = 0; | 175 | int idx = 0; |
172 | for(int i = -dim; i <= dim; i++){ | 176 | for(int i = -dim; i <= dim; i++){ |
173 | for(int j = -dim; j <= dim; j++){ | 177 | for(int j = -dim; j <= dim; j++){ |
174 | - | 178 | + |
175 | //Create linear index | 179 | //Create linear index |
176 | idx = (j+dim)+(i+dim)*((dim*2)+1); | 180 | idx = (j+dim)+(i+dim)*((dim*2)+1); |
177 | temp[0] = d_s[0]; //rotate vector | 181 | temp[0] = d_s[0]; //rotate vector |
@@ -179,6 +183,7 @@ class gl_spider | @@ -179,6 +183,7 @@ class gl_spider | ||
179 | temp[2] = d_s[2]+dt*(float) j; | 183 | temp[2] = d_s[2]+dt*(float) j; |
180 | 184 | ||
181 | temp = (temp.sph2cart()).norm(); //back to cart | 185 | temp = (temp.sph2cart()).norm(); //back to cart |
186 | + // file << temp[0] << "," << temp[1] << "," << temp[2] << endl; | ||
182 | dV.push_back(temp); | 187 | dV.push_back(temp); |
183 | if(cos(Y.dot(temp))< 0.087){ Y[0] = 0.0; Y[1] = 1.0;} | 188 | if(cos(Y.dot(temp))< 0.087){ Y[0] = 0.0; Y[1] = 1.0;} |
184 | else{Y[0] = 1.0; Y[1] = 0.0;} | 189 | else{Y[0] = 1.0; Y[1] = 0.0;} |
@@ -202,6 +207,8 @@ class gl_spider | @@ -202,6 +207,8 @@ class gl_spider | ||
202 | void | 207 | void |
203 | genPositionVectors(float delta = 0.2) | 208 | genPositionVectors(float delta = 0.2) |
204 | { | 209 | { |
210 | + ofstream file; | ||
211 | + file.open("pvectors.txt"); | ||
205 | //Set up the vectors necessary for Rectangle creation. | 212 | //Set up the vectors necessary for Rectangle creation. |
206 | vec<float> Y(1.0,0.0,0.0); | 213 | vec<float> Y(1.0,0.0,0.0); |
207 | vec<float> pos(0.0,0.0,0.0); | 214 | vec<float> pos(0.0,0.0,0.0); |
@@ -209,10 +216,11 @@ class gl_spider | @@ -209,10 +216,11 @@ class gl_spider | ||
209 | vec<float> dir(0.0, 0.0, 1.0); | 216 | vec<float> dir(0.0, 0.0, 1.0); |
210 | 217 | ||
211 | //Set up the variable necessary for vector creation. | 218 | //Set up the variable necessary for vector creation. |
212 | - vec<float> temp; | 219 | + vec<float> temp(0,0,0); |
213 | int dim = (sqrt(numSamples)-1)/2; | 220 | int dim = (sqrt(numSamples)-1)/2; |
214 | stim::rect<float> samplingPlane = | 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 | float step = 1.0/(dim); | 224 | float step = 1.0/(dim); |
217 | 225 | ||
218 | //Loop over the samples, keeping the original p sample | 226 | //Loop over the samples, keeping the original p sample |
@@ -228,6 +236,7 @@ class gl_spider | @@ -228,6 +236,7 @@ class gl_spider | ||
228 | 0.5+step*i, | 236 | 0.5+step*i, |
229 | 0.5+step*j | 237 | 0.5+step*j |
230 | ); | 238 | ); |
239 | + file << temp[0] << "," << temp[1] << "," << temp[2] << endl; | ||
231 | pV.push_back(temp); | 240 | pV.push_back(temp); |
232 | hor = stim::rect<float>(mag, | 241 | hor = stim::rect<float>(mag, |
233 | temp, dir, | 242 | temp, dir, |
@@ -262,7 +271,7 @@ class gl_spider | @@ -262,7 +271,7 @@ class gl_spider | ||
262 | float max = 1.0+delta; | 271 | float max = 1.0+delta; |
263 | float step = (max-min)/(numSamples-1); | 272 | float step = (max-min)/(numSamples-1); |
264 | float factor; | 273 | float factor; |
265 | - vec<float> temp; | 274 | + vec<float> temp(0.0,0.0,0.0); |
266 | 275 | ||
267 | glNewList(dList+2, GL_COMPILE); | 276 | glNewList(dList+2, GL_COMPILE); |
268 | for(int i = 0; i < numSamples; i++){ | 277 | for(int i = 0; i < numSamples; i++){ |
@@ -284,7 +293,6 @@ class gl_spider | @@ -284,7 +293,6 @@ class gl_spider | ||
284 | } | 293 | } |
285 | ///@param v_x x-coordinate in buffer-space, | 294 | ///@param v_x x-coordinate in buffer-space, |
286 | ///@param v_y y-coordinate in buffer-space. | 295 | ///@param v_y y-coordinate in buffer-space. |
287 | - ilVertex2f(0.0, j*10.0); | ||
288 | ///Samples the texturespace and places a sample in the provided coordinates | 296 | ///Samples the texturespace and places a sample in the provided coordinates |
289 | ///of bufferspace. | 297 | ///of bufferspace. |
290 | void | 298 | void |
@@ -434,7 +442,7 @@ class gl_spider | @@ -434,7 +442,7 @@ class gl_spider | ||
434 | ///Based on the p of the spider in real space (arbitrary). | 442 | ///Based on the p of the spider in real space (arbitrary). |
435 | void setMatrix() | 443 | void setMatrix() |
436 | { | 444 | { |
437 | - stim::vec<float, 4> rot = getRotation(d); | 445 | + stim::vec<float> rot = getRotation(d); |
438 | glMatrixMode(GL_TEXTURE); | 446 | glMatrixMode(GL_TEXTURE); |
439 | glLoadIdentity(); | 447 | glLoadIdentity(); |
440 | 448 | ||
@@ -514,20 +522,30 @@ class gl_spider | @@ -514,20 +522,30 @@ class gl_spider | ||
514 | gl_spider | 522 | gl_spider |
515 | (int samples = 1089) | 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 | numSamples = samples; | 533 | numSamples = samples; |
521 | } | 534 | } |
522 | 535 | ||
523 | ///temporary constructor for convenience, will be removed in further updates. | 536 | ///temporary constructor for convenience, will be removed in further updates. |
524 | gl_spider | 537 | gl_spider |
525 | (float pos_x, float pos_y, float pos_z, float dir_x, float dir_y, float dir_z, | 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,7 +569,7 @@ class gl_spider | ||
551 | GenerateFBO(20, numSamples*10); | 569 | GenerateFBO(20, numSamples*10); |
552 | setDims(0.6, 0.6, 1.0); | 570 | setDims(0.6, 0.6, 1.0); |
553 | setSize(512.0, 512.0, 426.0); | 571 | setSize(512.0, 512.0, 426.0); |
554 | - | 572 | + setMatrix(); |
555 | dList = glGenLists(3); | 573 | dList = glGenLists(3); |
556 | glListBase(dList); | 574 | glListBase(dList); |
557 | Bind(); | 575 | Bind(); |
@@ -664,10 +682,10 @@ class gl_spider | @@ -664,10 +682,10 @@ class gl_spider | ||
664 | ///@param dir, the vector to which we are rotating | 682 | ///@param dir, the vector to which we are rotating |
665 | ///given a vector to align to, finds the required | 683 | ///given a vector to align to, finds the required |
666 | ///axis and angle for glRotatef | 684 | ///axis and angle for glRotatef |
667 | - stim::vec<float, 4> | 685 | + stim::vec<float> |
668 | getRotation(stim::vec<float> dir) | 686 | getRotation(stim::vec<float> dir) |
669 | { | 687 | { |
670 | - stim::vec<float, 4> out; | 688 | + stim::vec<float> out(0,0,0,0);; |
671 | stim::vec<float> from(0,0,1); | 689 | stim::vec<float> from(0,0,1); |
672 | out[0] = acos(from.dot(dir))*M_PI/180; | 690 | out[0] = acos(from.dot(dir))*M_PI/180; |
673 | if(out[0] < 0.0001){ | 691 | if(out[0] < 0.0001){ |
@@ -718,7 +736,7 @@ class gl_spider | @@ -718,7 +736,7 @@ class gl_spider | ||
718 | findOptimalDirection(); | 736 | findOptimalDirection(); |
719 | findOptimalPosition(); | 737 | findOptimalPosition(); |
720 | findOptimalScale(); | 738 | findOptimalScale(); |
721 | - branchDetection(); | 739 | +// branchDetection(); |
722 | Unbind(); | 740 | Unbind(); |
723 | } | 741 | } |
724 | 742 |
stim/grids/grid.h
@@ -7,7 +7,7 @@ | @@ -7,7 +7,7 @@ | ||
7 | #include <fstream> | 7 | #include <fstream> |
8 | #include <cstdarg> | 8 | #include <cstdarg> |
9 | 9 | ||
10 | -#include "../math/vector.h" | 10 | +#include "../math/mathvec.h" |
11 | 11 | ||
12 | namespace stim{ | 12 | namespace stim{ |
13 | 13 | ||
@@ -20,8 +20,8 @@ class grid{ | @@ -20,8 +20,8 @@ class grid{ | ||
20 | 20 | ||
21 | protected: | 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 | T* ptr; //pointer to the data (on the GPU or CPU) | 25 | T* ptr; //pointer to the data (on the GPU or CPU) |
26 | 26 | ||
27 | ///Return the total number of values in the binary file | 27 | ///Return the total number of values in the binary file |
@@ -56,7 +56,7 @@ public: | @@ -56,7 +56,7 @@ public: | ||
56 | ///Constructor used to specify the grid size as a vector | 56 | ///Constructor used to specify the grid size as a vector |
57 | 57 | ||
58 | /// @param _R is a vector describing the grid resolution | 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 | //set the grid resolution | 61 | //set the grid resolution |
62 | R = _R; | 62 | R = _R; |
@@ -65,7 +65,7 @@ public: | @@ -65,7 +65,7 @@ public: | ||
65 | } | 65 | } |
66 | 66 | ||
67 | void | 67 | void |
68 | - setDim(stim::vec<float, D> s) | 68 | + setDim(stim::vec<float> s) |
69 | { | 69 | { |
70 | S = s; | 70 | S = s; |
71 | } | 71 | } |
@@ -106,7 +106,7 @@ public: | @@ -106,7 +106,7 @@ public: | ||
106 | /// @param filename is the name of the file containing the binary data | 106 | /// @param filename is the name of the file containing the binary data |
107 | /// @param S is the size of the binary file along each dimension | 107 | /// @param S is the size of the binary file along each dimension |
108 | /// @param header is the size of the header in bytes | 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 | R = S; //set the sample resolution | 111 | R = S; //set the sample resolution |
112 | 112 | ||
@@ -177,7 +177,7 @@ public: | @@ -177,7 +177,7 @@ public: | ||
177 | result<<"]"<<std::endl; | 177 | result<<"]"<<std::endl; |
178 | 178 | ||
179 | //calculate the number of values to output | 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 | for(unsigned long v = 0; v<nV; v++){ | 182 | for(unsigned long v = 0; v<nV; v++){ |
183 | result<<ptr[v]; | 183 | result<<ptr[v]; |
stim/grids/image_stack.h
@@ -51,10 +51,10 @@ public: | @@ -51,10 +51,10 @@ public: | ||
51 | stim::image<T> I(file_list[0].str()); | 51 | stim::image<T> I(file_list[0].str()); |
52 | 52 | ||
53 | //set the image resolution and number of channels | 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 | //allocate storage space | 59 | //allocate storage space |
60 | ptr = (T*)malloc(sizeof(T) * samples()); | 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,7 +4,7 @@ | ||
4 | //#include "rts/vector.h" | 4 | //#include "rts/vector.h" |
5 | #include <string.h> | 5 | #include <string.h> |
6 | #include <iostream> | 6 | #include <iostream> |
7 | -#include "vector.h" | 7 | +#include "mathvec.h" |
8 | #include "../cuda/callable.h" | 8 | #include "../cuda/callable.h" |
9 | 9 | ||
10 | namespace stim{ | 10 | namespace stim{ |
@@ -52,9 +52,12 @@ struct matrix | @@ -52,9 +52,12 @@ struct matrix | ||
52 | 52 | ||
53 | 53 | ||
54 | template<typename Y> | 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 | for(int r=0; r<N; r++) | 62 | for(int r=0; r<N; r++) |
60 | for(int c=0; c<N; c++) | 63 | for(int c=0; c<N; c++) |
stim/math/quaternion.h
@@ -26,13 +26,13 @@ public: | @@ -26,13 +26,13 @@ public: | ||
26 | 26 | ||
27 | CUDA_CALLABLE void CreateRotation(T theta, T ux, T uy, T uz){ | 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 | CreateRotation(theta, u); | 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 | //assign the given Euler rotation to this quaternion | 37 | //assign the given Euler rotation to this quaternion |
38 | w = (T)cos(theta/2); | 38 | w = (T)cos(theta/2); |
@@ -41,7 +41,7 @@ public: | @@ -41,7 +41,7 @@ public: | ||
41 | z = u_hat[2]*(T)sin(theta/2); | 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 | vec<T> r = from.cross(to); //compute the rotation vector | 46 | vec<T> r = from.cross(to); //compute the rotation vector |
47 | T theta = asin(r.len()); //compute the angle of the rotation about r | 47 | T theta = asin(r.len()); //compute the angle of the rotation about r |
stim/math/rect.h
@@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
3 | 3 | ||
4 | //enable CUDA_CALLABLE macro | 4 | //enable CUDA_CALLABLE macro |
5 | #include "../cuda/callable.h" | 5 | #include "../cuda/callable.h" |
6 | -#include "../math/vector.h" | 6 | +#include "../math/mathvec.h" |
7 | #include "../math/triangle.h" | 7 | #include "../math/triangle.h" |
8 | #include "../math/quaternion.h" | 8 | #include "../math/quaternion.h" |
9 | #include <iostream> | 9 | #include <iostream> |
@@ -13,7 +13,7 @@ | @@ -13,7 +13,7 @@ | ||
13 | namespace stim{ | 13 | namespace stim{ |
14 | 14 | ||
15 | //template for a rectangle class in ND space | 15 | //template for a rectangle class in ND space |
16 | -template <class T, int N = 3> | 16 | +template <class T> |
17 | struct rect | 17 | struct rect |
18 | { | 18 | { |
19 | /* | 19 | /* |
@@ -28,9 +28,9 @@ struct rect | @@ -28,9 +28,9 @@ struct rect | ||
28 | 28 | ||
29 | private: | 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 | CUDA_CALLABLE void scale(T factor){ | 35 | CUDA_CALLABLE void scale(T factor){ |
36 | X *= factor; | 36 | X *= factor; |
@@ -38,10 +38,10 @@ private: | @@ -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 | n = n.norm(); //normalize, just in case | 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 | quaternion<T> q; //create a quaternion | 45 | quaternion<T> q; //create a quaternion |
46 | q.CreateRotation(n_current, n); //initialize a rotation from n_current to n | 46 | q.CreateRotation(n_current, n); //initialize a rotation from n_current to n |
47 | 47 | ||
@@ -51,9 +51,9 @@ private: | @@ -51,9 +51,9 @@ private: | ||
51 | } | 51 | } |
52 | 52 | ||
53 | CUDA_CALLABLE void init(){ | 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 | public: | 59 | public: |
@@ -69,30 +69,22 @@ public: | @@ -69,30 +69,22 @@ public: | ||
69 | C[2] = z_pos; | 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 | //create a rectangle from a center point, normal, and size | 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 | init(); //start with the default setting | 75 | init(); //start with the default setting |
83 | C = c; | 76 | C = c; |
84 | - scale(size); //scale the rectangle | ||
85 | normal(n); //orient | 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 | C = center; | 82 | C = center; |
91 | X = directionX; | 83 | X = directionX; |
92 | Y = directionY; | 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 | C = center; | 89 | C = center; |
98 | X = directionX; | 90 | X = directionX; |
@@ -100,7 +92,7 @@ public: | @@ -100,7 +92,7 @@ public: | ||
100 | scale(size); | 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 | C = center; | 97 | C = center; |
106 | X = directionX; | 98 | X = directionX; |
@@ -114,7 +106,7 @@ public: | @@ -114,7 +106,7 @@ public: | ||
114 | } | 106 | } |
115 | 107 | ||
116 | //boolean comparison | 108 | //boolean comparison |
117 | - bool operator==(const rect<T, N> & rhs) | 109 | + bool operator==(const rect<T> & rhs) |
118 | { | 110 | { |
119 | if(C == rhs.C && X == rhs.X && Y == rhs.Y) | 111 | if(C == rhs.C && X == rhs.X && Y == rhs.Y) |
120 | return true; | 112 | return true; |
@@ -125,24 +117,24 @@ public: | @@ -125,24 +117,24 @@ public: | ||
125 | /******************************************* | 117 | /******************************************* |
126 | Return the normal for the rect | 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 | return (X.cross(Y)).norm(); | 122 | return (X.cross(Y)).norm(); |
131 | } | 123 | } |
132 | 124 | ||
133 | //get the world space value given the planar coordinates a, b in [0, 1] | 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 | //given the two parameters a, b = [0 1], returns the position in world space | 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 | result = A + X * a + Y * b; | 131 | result = A + X * a + Y * b; |
140 | 132 | ||
141 | return result; | 133 | return result; |
142 | } | 134 | } |
143 | 135 | ||
144 | //parenthesis operator returns the world space given rectangular coordinates a and b in [0 1] | 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 | return p(a, b); | 139 | return p(a, b); |
148 | } | 140 | } |
@@ -150,7 +142,7 @@ public: | @@ -150,7 +142,7 @@ public: | ||
150 | std::string str() | 142 | std::string str() |
151 | { | 143 | { |
152 | std::stringstream ss; | 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 | ss<<std::left<<"B="<<std::setfill('-')<<std::setw(20)<<A + Y<<">"<<"C="<<A + Y + X<<std::endl; | 146 | ss<<std::left<<"B="<<std::setfill('-')<<std::setw(20)<<A + Y<<">"<<"C="<<A + Y + X<<std::endl; |
155 | ss<<std::setfill(' ')<<std::setw(23)<<"|"<<"|"<<std::endl<<std::setw(23)<<"|"<<"|"<<std::endl; | 147 | ss<<std::setfill(' ')<<std::setw(23)<<"|"<<"|"<<std::endl<<std::setw(23)<<"|"<<"|"<<std::endl; |
156 | ss<<std::left<<"A="<<std::setfill('-')<<std::setw(20)<<A<<">"<<"D="<<A + X; | 148 | ss<<std::left<<"A="<<std::setfill('-')<<std::setw(20)<<A<<">"<<"D="<<A + X; |
@@ -160,12 +152,12 @@ public: | @@ -160,12 +152,12 @@ public: | ||
160 | } | 152 | } |
161 | 153 | ||
162 | //scales the rectangle by a value rhs | 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 | //scales the plane by a scalar value | 157 | //scales the plane by a scalar value |
166 | 158 | ||
167 | //create the new rectangle | 159 | //create the new rectangle |
168 | - rect<T, N> result = *this; | 160 | + rect<T> result = *this; |
169 | result.scale(rhs); | 161 | result.scale(rhs); |
170 | 162 | ||
171 | return result; | 163 | return result; |
@@ -173,15 +165,15 @@ public: | @@ -173,15 +165,15 @@ public: | ||
173 | } | 165 | } |
174 | 166 | ||
175 | //computes the distance between the specified point and this rectangle | 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 | //compute the distance between a point and this rect | 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 | //first break the rect up into two triangles | 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 | T d0 = T0.dist(p); | 179 | T d0 = T0.dist(p); |
@@ -193,9 +185,9 @@ public: | @@ -193,9 +185,9 @@ public: | ||
193 | return d1; | 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 | T da = (A - p).len(); | 191 | T da = (A - p).len(); |
200 | T db = (A+X - p).len(); | 192 | T db = (A+X - p).len(); |
201 | T dc = (A+Y - p).len(); | 193 | T dc = (A+Y - p).len(); |
@@ -208,7 +200,7 @@ public: | @@ -208,7 +200,7 @@ public: | ||
208 | } //end namespace rts | 200 | } //end namespace rts |
209 | 201 | ||
210 | template <typename T, int N> | 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 | os<<R.str(); | 205 | os<<R.str(); |
214 | return os; | 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,12 +3,12 @@ | ||
3 | 3 | ||
4 | //enable CUDA_CALLABLE macro | 4 | //enable CUDA_CALLABLE macro |
5 | #include "../cuda/callable.h" | 5 | #include "../cuda/callable.h" |
6 | -#include "../math/vector.h" | 6 | +#include "../math/mathvec.h" |
7 | #include <iostream> | 7 | #include <iostream> |
8 | 8 | ||
9 | namespace stim{ | 9 | namespace stim{ |
10 | 10 | ||
11 | -template <class T, int N=3> | 11 | +template <class T> |
12 | struct triangle | 12 | struct triangle |
13 | { | 13 | { |
14 | /* | 14 | /* |
@@ -23,15 +23,15 @@ struct triangle | @@ -23,15 +23,15 @@ struct triangle | ||
23 | */ | 23 | */ |
24 | private: | 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 | //This function returns the point specified by p = A + s(B-A) + t(C-A) | 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 | return A + s*E0 + t*E1; | 36 | return A + s*E0 + t*E1; |
37 | } | 37 | } |
@@ -46,26 +46,26 @@ struct triangle | @@ -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 | A = a; | 51 | A = a; |
52 | B = b; | 52 | B = b; |
53 | C = c; | 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 | return _p(s, t); | 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 | //comptue the distance between a point and this triangle | 63 | //comptue the distance between a point and this triangle |
64 | // This code is adapted from: http://www.geometrictools.com/Documentation/DistancePoint3Triangle3.pdf | 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 | T a = E0.dot(E0); | 70 | T a = E0.dot(E0); |
71 | T b = E0.dot(E1); | 71 | T b = E0.dot(E1); |
@@ -175,9 +175,9 @@ struct triangle | @@ -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 | return (p - n).len(); | 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 | #include "../math/quaternion.h" | 2 | #include "../math/quaternion.h" |
3 | #include "../math/matrix.h" | 3 | #include "../math/matrix.h" |
4 | 4 | ||
@@ -11,32 +11,32 @@ namespace stim{ | @@ -11,32 +11,32 @@ namespace stim{ | ||
11 | 11 | ||
12 | class camera | 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 | float focus; //focal length of the camera | 17 | float focus; //focal length of the camera |
18 | float fov; | 18 | float fov; |
19 | 19 | ||
20 | //private function makes sure that the up vector is orthogonal to the direction vector and both are normalized | 20 | //private function makes sure that the up vector is orthogonal to the direction vector and both are normalized |
21 | void stabalize() | 21 | void stabalize() |
22 | { | 22 | { |
23 | - vec<float, 3> side = up.cross(d); | 23 | + vec<float> side = up.cross(d); |
24 | up = d.cross(side); | 24 | up = d.cross(side); |
25 | up = up.norm(); | 25 | up = up.norm(); |
26 | d = d.norm(); | 26 | d = d.norm(); |
27 | } | 27 | } |
28 | 28 | ||
29 | public: | 29 | public: |
30 | - void setPosition(vec<float, 3> pos) | 30 | + void setPosition(vec<float> pos) |
31 | { | 31 | { |
32 | p = pos; | 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 | void setFocalDistance(float distance){focus = distance;} | 36 | void setFocalDistance(float distance){focus = distance;} |
37 | void setFOV(float field_of_view){fov = field_of_view;} | 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 | //find the new direction | 41 | //find the new direction |
42 | d = pos - p; | 42 | d = pos - p; |
@@ -47,22 +47,22 @@ public: | @@ -47,22 +47,22 @@ public: | ||
47 | //stabalize the camera | 47 | //stabalize the camera |
48 | stabalize(); | 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 | void LookAtDolly(float lx, float ly, float lz) | 53 | void LookAtDolly(float lx, float ly, float lz) |
54 | { | 54 | { |
55 | //find the current focus point | 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 | p = p + T; | 58 | p = p + T; |
59 | } | 59 | } |
60 | 60 | ||
61 | - void Dolly(vec<float, 3> direction) | 61 | + void Dolly(vec<float> direction) |
62 | { | 62 | { |
63 | p = p+direction; | 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 | void Push(float delta) | 66 | void Push(float delta) |
67 | { | 67 | { |
68 | if(delta > focus) | 68 | if(delta > focus) |
@@ -80,7 +80,7 @@ public: | @@ -80,7 +80,7 @@ public: | ||
80 | qx.CreateRotation(theta_x, up[0], up[1], up[2]); | 80 | qx.CreateRotation(theta_x, up[0], up[1], up[2]); |
81 | 81 | ||
82 | //y rotation is around the side axis | 82 | //y rotation is around the side axis |
83 | - vec<float, 3> side = up.cross(d); | 83 | + vec<float> side = up.cross(d); |
84 | quaternion<float> qy; | 84 | quaternion<float> qy; |
85 | qy.CreateRotation(theta_y, side[0], side[1], side[2]); | 85 | qy.CreateRotation(theta_y, side[0], side[1], side[2]); |
86 | 86 | ||
@@ -118,28 +118,28 @@ public: | @@ -118,28 +118,28 @@ public: | ||
118 | void OrbitFocus(float theta_x, float theta_y) | 118 | void OrbitFocus(float theta_x, float theta_y) |
119 | { | 119 | { |
120 | //find the focal point | 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 | //center the coordinate system on the focal point | 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 | //create the x rotation (around the up vector) | 126 | //create the x rotation (around the up vector) |
127 | quaternion<float> qx; | 127 | quaternion<float> qx; |
128 | qx.CreateRotation(theta_x, up[0], up[1], up[2]); | 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 | //get a side vector for theta_y rotation | 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 | quaternion<float> qy; | 134 | quaternion<float> qy; |
135 | qy.CreateRotation(theta_y, side[0], side[1], side[2]); | 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 | //perform the rotation on the centered camera position | 138 | //perform the rotation on the centered camera position |
139 | //centered = final.toMatrix()*centered; | 139 | //centered = final.toMatrix()*centered; |
140 | 140 | ||
141 | //re-position the camera | 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 | //make sure we are looking at the focal point | 144 | //make sure we are looking at the focal point |
145 | LookAt(focal_point); | 145 | LookAt(focal_point); |
@@ -151,21 +151,21 @@ public: | @@ -151,21 +151,21 @@ public: | ||
151 | 151 | ||
152 | void Slide(float u, float v) | 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 | p = p + (V * v) + (U * u); | 157 | p = p + (V * v) + (U * u); |
158 | } | 158 | } |
159 | 159 | ||
160 | //accessor methods | 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 | float getFOV(){return fov;} | 165 | float getFOV(){return fov;} |
166 | 166 | ||
167 | //output the camera settings | 167 | //output the camera settings |
168 | - const void print(std::ostream& output) | 168 | + void print(std::ostream& output) |
169 | { | 169 | { |
170 | output<<"Position: "<<p.str()<<std::endl; | 170 | output<<"Position: "<<p.str()<<std::endl; |
171 | 171 | ||
@@ -182,9 +182,9 @@ public: | @@ -182,9 +182,9 @@ public: | ||
182 | //constructor | 182 | //constructor |
183 | camera() | 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 | focus = 1; | 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 | #include <GL/gl.h> | 4 | #include <GL/gl.h> |
5 | 5 | ||
6 | #include <stim/gl/error.h> | 6 | #include <stim/gl/error.h> |
7 | #include <stim/visualization/colormap.h> | 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 | namespace stim{ | 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 | \ No newline at end of file | 188 | \ No newline at end of file |
stim/visualization/obj.h
@@ -6,6 +6,7 @@ | @@ -6,6 +6,7 @@ | ||
6 | #include <fstream> | 6 | #include <fstream> |
7 | #include <stdlib.h> | 7 | #include <stdlib.h> |
8 | #include <stim/parser/parser.h> | 8 | #include <stim/parser/parser.h> |
9 | +#include <stim/math/mathvec.h> | ||
9 | 10 | ||
10 | namespace stim{ | 11 | namespace stim{ |
11 | 12 | ||
@@ -34,37 +35,14 @@ protected: | @@ -34,37 +35,14 @@ protected: | ||
34 | 35 | ||
35 | enum token_type { OBJ_INVALID, OBJ_V, OBJ_VT, OBJ_VN, OBJ_P, OBJ_L, OBJ_F }; | 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 | vertex(){} | 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 | //constructor creates a vertex from a line string | 46 | //constructor creates a vertex from a line string |
69 | vertex(std::string line){ | 47 | vertex(std::string line){ |
70 | 48 | ||
@@ -305,6 +283,11 @@ protected: | @@ -305,6 +283,11 @@ protected: | ||
305 | } | 283 | } |
306 | 284 | ||
307 | public: | 285 | public: |
286 | + /// Constructor loads a Wavefront OBJ file | ||
287 | + obj(std::string filename){ | ||
288 | + load(filename); | ||
289 | + } | ||
290 | + | ||
308 | //functions for setting the texture coordinate for the next vertex | 291 | //functions for setting the texture coordinate for the next vertex |
309 | void TexCoord(T x){ update_vt(vertex(x));} | 292 | void TexCoord(T x){ update_vt(vertex(x));} |
310 | void TexCoord(T x, T y){ update_vt(vertex(x, y));} | 293 | void TexCoord(T x, T y){ update_vt(vertex(x, y));} |
@@ -504,6 +487,47 @@ public: | @@ -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 |