Commit c01958adbad61ab26da7cafe2bd52749322819fc
1 parent
a8ad9192
merged the two stim versions to work for volume-spider, and ONLY volume spider. …
…circle.h, cylinder.h, centerline.h and some other have been changed. Other compilation errors on linux also fixxed in spharmonic.h and gl_spharmonic.h
Showing
11 changed files
with
551 additions
and
596 deletions
Show diff stats
stim/biomodels/centerline.h
@@ -3,6 +3,7 @@ | @@ -3,6 +3,7 @@ | ||
3 | 3 | ||
4 | #include <vector> | 4 | #include <vector> |
5 | #include <stim/math/vec3.h> | 5 | #include <stim/math/vec3.h> |
6 | +//#include <ANN/ANN.h> | ||
6 | 7 | ||
7 | namespace stim{ | 8 | namespace stim{ |
8 | 9 | ||
@@ -11,134 +12,195 @@ namespace stim{ | @@ -11,134 +12,195 @@ namespace stim{ | ||
11 | * class to describe an interconnected (often biological) network. | 12 | * class to describe an interconnected (often biological) network. |
12 | */ | 13 | */ |
13 | template<typename T> | 14 | template<typename T> |
14 | -class centerline : public std::vector< stim::vec3<T> >{ | 15 | +class centerline{ |
15 | 16 | ||
16 | protected: | 17 | protected: |
18 | + unsigned int N; //number of points in the fiber | ||
19 | + double **c; //centerline (array of double pointers) | ||
20 | +// ANNkd_tree* kdt; //kd-tree stores all points in the fiber for fast searching | ||
21 | + | ||
22 | + /// Initialize an empty fiber | ||
23 | + void init() | ||
24 | + { | ||
25 | + N=0; | ||
26 | + c=NULL; | ||
27 | +// kdt = NULL; | ||
28 | + } | ||
17 | 29 | ||
18 | - std::vector<T> L; //stores the integrated length along the fiber (used for parameterization) | ||
19 | - | ||
20 | - ///Return the normalized direction vector at point i (average of the incoming and outgoing directions) | ||
21 | - vec3<T> d(size_t i) { | ||
22 | - if (size() <= 1) return vec3<T>(0, 0, 0); //if there is insufficient information to calculate the direction, return a null vector | ||
23 | - if (size() == 2) return (at(1) - at(0)).norm(); //if there are only two points, the direction vector at both is the direction of the line segment | ||
24 | - if (i == 0) return (at(1) - at(0)).norm(); //the first direction vector is oriented towards the first line segment | ||
25 | - if (i == size() - 1) return (at(size() - 1) - at(size() - 2)).norm(); //the last direction vector is oriented towards the last line segment | ||
26 | - | ||
27 | - //all other direction vectors are the average direction of the two joined line segments | ||
28 | - vec3<T> a = at(i) - at(i - 1); | ||
29 | - vec3<T> b = at(i + 1) - at(i); | ||
30 | - vec3<T> ab = a.norm() + b.norm(); | ||
31 | - return ab.norm(); | ||
32 | - } | ||
33 | - //initializes the integrated length vector to make parameterization easier, starting with index idx (all previous indices are assumed to be correct) | ||
34 | - void update_L(size_t start = 0) { | ||
35 | - L.resize(size()); //allocate space for the L array | ||
36 | - if (start == 0) { | ||
37 | - L[0] = 0; //initialize the length value for the first point to zero (0) | ||
38 | - start++; | ||
39 | - } | 30 | + /// Initialize a fiber with N centerline points (all located at [0, 0, 0] with radius 0) |
31 | + void init(unsigned int n) | ||
32 | + { | ||
33 | + | ||
34 | + N = n; //set the number of points | ||
35 | +// kdt = NULL; | ||
36 | + c = (double**) malloc(sizeof(double*) * N); //allocate the array pointer | ||
37 | + | ||
38 | + for(unsigned int i = 0; i < N; i++) //allocate space for each point | ||
39 | + c[i] = (double*) malloc(sizeof(double) * 3); | ||
40 | + } | ||
41 | + | ||
42 | + /// Copies an existing fiber to the current fiber | ||
43 | + | ||
44 | + /// @param cpy stores the new copy of the fiber | ||
45 | + void copy( const stim::centerline<T>& cpy, bool kd = 0){ | ||
46 | + | ||
47 | + ///allocate space for the new fiber | ||
48 | + init(cpy.N); | ||
40 | 49 | ||
41 | - stim::vec3<T> d; | ||
42 | - for (size_t i = start; i < size(); i++) { //for each line segment in the centerline | ||
43 | - d = at(i) - at(i - 1); | ||
44 | - L[i] = L[i - 1] + d.len(); //calculate the running length total | 50 | + ///copy the points |
51 | + for(unsigned int i = 0; i < N; i++){ | ||
52 | + for(unsigned int d = 0; d < 3; d++) //for each dimension | ||
53 | + c[i][d] = cpy.c[i][d]; //copy the coordinate | ||
45 | } | 54 | } |
55 | +// if(kd) | ||
56 | +// gen_kdtree(); //generate the kd tree for the new fiber | ||
46 | } | 57 | } |
47 | 58 | ||
48 | - void init() { | ||
49 | - if (size() == 0) return; //return if there aren't any points | ||
50 | - update_L(); | 59 | + /// generate a KD tree for points on fiber |
60 | +// void gen_kdtree() | ||
61 | +// { | ||
62 | +// int n_data = N; //create an array of data points | ||
63 | +// ANNpointArray pts = (ANNpointArray)c; //cast the centerline list to an ANNpointArray | ||
64 | +// kdt = new ANNkd_tree(pts, n_data, 3); //build a KD tree | ||
65 | +// } | ||
66 | + | ||
67 | + /// find distance between two points | ||
68 | + double dist(double* p0, double* p1){ | ||
69 | + | ||
70 | + double sum = 0; // initialize variables | ||
71 | + float v; | ||
72 | + for(unsigned int d = 0; d < 3; d++) | ||
73 | + { | ||
74 | + v = p1[d] - p0[d]; | ||
75 | + sum +=v * v; | ||
76 | + } | ||
77 | + return sqrt(sum); | ||
51 | } | 78 | } |
52 | 79 | ||
80 | + /// This function retreives the index for the fiber point closest to q | ||
81 | + | ||
82 | + /// @param q is a reference point used to find the closest point on the fiber center line | ||
83 | +// unsigned int ann( stim::vec<double> q ){ | ||
84 | +// ANNidxArray idx = new ANNidx[1]; //variable used to hold the nearest point | ||
85 | +// ANNdistArray sq_dist = new ANNdist[1]; //variable used to hold the squared distance to the nearest point | ||
86 | +// kdt->annkSearch(q.data(), 1, idx, sq_dist); //search the KD tree for the nearest neighbor | ||
87 | +// return *idx; | ||
88 | +// } | ||
89 | + | ||
53 | /// Returns a stim::vec representing the point at index i | 90 | /// Returns a stim::vec representing the point at index i |
54 | 91 | ||
55 | /// @param i is an index of the desired centerline point | 92 | /// @param i is an index of the desired centerline point |
56 | stim::vec<T> get_vec(unsigned i){ | 93 | stim::vec<T> get_vec(unsigned i){ |
57 | - return std::vector< stim::vec3<T> >::at(i); | ||
58 | - } | ||
59 | - | ||
60 | - ///finds the index of the point closest to the length l on the lower bound. | ||
61 | - ///binary search. | ||
62 | - size_t findIdx(T l) { | ||
63 | - for (size_t i = 1; i < L.size(); i++) { //for each point in the centerline | ||
64 | - if (L[i] > l) return i - 1; //if we have passed the desired length value, return i-1 | ||
65 | - } | ||
66 | - return L.size() - 1; | ||
67 | - /*size_t i = L.size() / 2; | ||
68 | - size_t max = L.size() - 1; | ||
69 | - size_t min = 0; | ||
70 | - while (i < L.size() - 1){ | ||
71 | - if (l < L[i]) { | ||
72 | - max = i; | ||
73 | - i = min + (max - min) / 2; | ||
74 | - } | ||
75 | - else if (L[i] <= l && L[i + 1] >= l) { | ||
76 | - break; | ||
77 | - } | ||
78 | - else { | ||
79 | - min = i; | ||
80 | - i = min + (max - min) / 2; | ||
81 | - } | ||
82 | - } | ||
83 | - return i;*/ | ||
84 | - } | 94 | + stim::vec3<T> r; |
95 | + r.resize(3); | ||
96 | + r[0] = c[i][0]; | ||
97 | + r[1] = c[i][1]; | ||
98 | + r[2] = c[i][2]; | ||
85 | 99 | ||
86 | - ///Returns a position vector at the given length into the fiber (based on the pvalue). | ||
87 | - ///Interpolates the radius along the line. | ||
88 | - ///@param l: the location of the in the cylinder. | ||
89 | - ///@param idx: integer location of the point closest to l but prior to it. | ||
90 | - stim::vec3<T> p(T l, int idx) { | ||
91 | - T rat = (l - L[idx]) / (L[idx + 1] - L[idx]); | ||
92 | - stim::vec3<T> v1 = at(idx); | ||
93 | - stim::vec3<T> v2 = at(idx + 1); | ||
94 | - return(v1 + (v2 - v1)*rat); | 100 | + return r; |
95 | } | 101 | } |
96 | 102 | ||
97 | 103 | ||
98 | public: | 104 | public: |
99 | 105 | ||
100 | - using std::vector< stim::vec3<T> >::at; | ||
101 | - using std::vector< stim::vec3<T> >::size; | ||
102 | - | ||
103 | - centerline() : std::vector< stim::vec3<T> >() { | 106 | + centerline(){ |
104 | init(); | 107 | init(); |
105 | } | 108 | } |
106 | - centerline(size_t n) : std::vector< stim::vec3<T> >(n){ | ||
107 | - init(); | 109 | + |
110 | + /// Copy constructor | ||
111 | + centerline(const stim::centerline<T> &obj){ | ||
112 | + copy(obj); | ||
108 | } | 113 | } |
109 | 114 | ||
110 | - //overload the push_back function to update the length vector | ||
111 | - void push_back(stim::vec3<T> p) { | ||
112 | - std::vector< stim::vec3<T> >::push_back(p); | ||
113 | - update_L(size() - 1); | 115 | + //temp constructor for graph visualization |
116 | + centerline(int n) | ||
117 | + { | ||
118 | + init(n); | ||
114 | } | 119 | } |
115 | 120 | ||
116 | - ///Returns a position vector at the given p-value (p value ranges from 0 to 1). | ||
117 | - ///interpolates the position along the line. | ||
118 | - ///@param pvalue: the location of the in the cylinder, from 0 (beginning to 1). | ||
119 | - stim::vec3<T> p(T pvalue) { | ||
120 | - if (pvalue <= 0.0) return at(0); //return the first element | ||
121 | - if (pvalue >= 1.0) return back(); //return the last element | 121 | + /// Constructor takes a list of stim::vec points, the radius at each point is set to zero |
122 | + centerline(std::vector< stim::vec<T> > p, bool kd = 0){ | ||
123 | + init(p.size()); //initialize the fiber | ||
124 | + | ||
125 | + //for each point, set the centerline position and radius | ||
126 | + for(unsigned int i = 0; i < N; i++){ | ||
122 | 127 | ||
123 | - T l = pvalue*L[L.size() - 1]; | ||
124 | - int idx = findIdx(l); | ||
125 | - return p(l, idx); | 128 | + //set the centerline position |
129 | + for(unsigned int d = 0; d < 3; d++) | ||
130 | + c[i][d] = (double) p[i][d]; | ||
131 | + | ||
132 | + //set the radius | ||
133 | + } | ||
134 | + //generate a kd tree | ||
135 | +// if(kd) | ||
136 | +// gen_kdtree(); | ||
126 | } | 137 | } |
127 | 138 | ||
128 | - ///Update centerline internal parameters (currently the L vector) | ||
129 | - void update() { | ||
130 | - init(); | 139 | + /// constructor takes a list of points |
140 | + centerline(std::vector< stim::vec3< T > > pos, bool kd = 0){ | ||
141 | + init(pos.size()); //initialize the fiber | ||
142 | + | ||
143 | + //for each point, set the centerline position and radius | ||
144 | + for(unsigned int i = 0; i < N; i++){ | ||
145 | + //set the centerline position | ||
146 | + for(unsigned int d = 0; d < 3; d++) | ||
147 | + c[i][d] = (double) pos[i][d]; | ||
148 | + //set the radius | ||
149 | + } | ||
150 | + | ||
151 | + //generate a kd tree | ||
152 | + //if(kd) | ||
153 | + // gen_kdtree(); | ||
154 | + } | ||
155 | + | ||
156 | + /// Assignment operation | ||
157 | + centerline& operator=(const centerline &rhs){ | ||
158 | + if(this == &rhs) return *this; //test for and handle self-assignment | ||
159 | + copy(rhs); | ||
160 | + return *this; | ||
131 | } | 161 | } |
132 | - ///Return the length of the entire centerline | ||
133 | - T length() { | ||
134 | - return L.back(); | 162 | + |
163 | + | ||
164 | + /// Return the point on the fiber closest to q | ||
165 | + /// @param q is the query point used to locate the nearest point on the fiber centerline | ||
166 | +// stim::vec<T> nearest(stim::vec<T> q){ | ||
167 | +// | ||
168 | +// stim::vec<double> temp( (double) q[0], (double) q[1], (double) q[2]); | ||
169 | +// | ||
170 | +// unsigned int idx = ann(temp); //determine the index of the nearest neighbor | ||
171 | +// | ||
172 | +// return stim::vec<T>((T) c[idx][0], (T) c[idx][1], (T) c[idx][2]); //return the nearest centerline point | ||
173 | +// } | ||
174 | + | ||
175 | + /// Return the point index on the fiber closest to q | ||
176 | + /// @param q is the query point used to locate the nearest point on the fiber centerline | ||
177 | +// unsigned int nearest_idx(stim::vec<T> q){ | ||
178 | +// | ||
179 | +// stim::vec<double> temp((double) q[0], (double) q[1], (double) q[2]); | ||
180 | +// | ||
181 | +// unsigned int idx = ann(temp); //determine the index of the nearest neighbor | ||
182 | +// | ||
183 | +// return idx; //return the nearest centerline point index | ||
184 | +// } | ||
185 | + | ||
186 | + /// Returns the fiber centerline as an array of stim::vec points | ||
187 | + std::vector< stim::vec<T> > get_centerline(){ | ||
188 | + | ||
189 | + //create an array of stim vectors | ||
190 | + std::vector< stim::vec3<T> > pts(N); | ||
191 | + | ||
192 | + //cast each point to a stim::vec, keeping only the position information | ||
193 | + for(unsigned int i = 0; i < N; i++) | ||
194 | + pts[i] = stim::vec3<T>((T) c[i][0], (T) c[i][1], (T) c[i][2]); | ||
195 | + | ||
196 | + //return the centerline array | ||
197 | + return pts; | ||
135 | } | 198 | } |
136 | 199 | ||
137 | /// Split the fiber at the specified index. If the index is an end point, only one fiber is returned | 200 | /// Split the fiber at the specified index. If the index is an end point, only one fiber is returned |
138 | std::vector< stim::centerline<T> > split(unsigned int idx){ | 201 | std::vector< stim::centerline<T> > split(unsigned int idx){ |
139 | 202 | ||
140 | - std::vector< stim::centerline<T> > fl; //create an array to store up to two fibers | ||
141 | - size_t N = size(); | 203 | + std::vector< stim::centerline<T> > fl; //create an array to store up to two fibers |
142 | 204 | ||
143 | //if the index is an end point, only the existing fiber is returned | 205 | //if the index is an end point, only the existing fiber is returned |
144 | if(idx == 0 || idx == N-1){ | 206 | if(idx == 0 || idx == N-1){ |
@@ -154,84 +216,123 @@ public: | @@ -154,84 +216,123 @@ public: | ||
154 | 216 | ||
155 | fl.resize(2); //set the array size to 2 | 217 | fl.resize(2); //set the array size to 2 |
156 | 218 | ||
157 | - fl[0] = stim::centerline<T>(N1); //set the size of each fiber | ||
158 | - fl[1] = stim::centerline<T>(N2); | 219 | + fl[0].init(N1); //set the size of each fiber |
220 | + fl[1].init(N2); | ||
159 | 221 | ||
160 | //copy both halves of the fiber | 222 | //copy both halves of the fiber |
161 | - unsigned int i; | 223 | + unsigned int i, d; |
162 | 224 | ||
163 | //first half | 225 | //first half |
164 | - for(i = 0; i < N1; i++) //for each centerline point | ||
165 | - fl[0][i] = std::vector< stim::vec3<T> >::at(i); | ||
166 | - fl[0].init(); //initialize the length vector | 226 | + for(i = 0; i < N1; i++){ //for each centerline point |
227 | + for(d = 0; d < 3; d++) | ||
228 | + fl[0].c[i][d] = c[i][d]; //copy each coordinate | ||
229 | + } | ||
167 | 230 | ||
168 | //second half | 231 | //second half |
169 | - for(i = 0; i < N2; i++) | ||
170 | - fl[1][i] = std::vector< stim::vec3<T> >::at(idx+i); | ||
171 | - fl[1].init(); //initialize the length vector | 232 | + for(i = 0; i < N2; i++){ |
233 | + for(d = 0; d < 3; d++) | ||
234 | + fl[1].c[i][d] = c[idx + i][d]; | ||
235 | + | ||
236 | + } | ||
172 | } | 237 | } |
173 | 238 | ||
174 | return fl; //return the array | 239 | return fl; //return the array |
175 | 240 | ||
176 | } | 241 | } |
177 | 242 | ||
243 | + /// Calculates the set of fibers resulting from a connection between the current fiber and a fiber f | ||
244 | + | ||
245 | + /// @param f is the fiber that will be connected to the current fiber | ||
246 | +/* std::vector< stim::centerline<T> > connect( stim::centerline<T> &f, double dist){ | ||
247 | + | ||
248 | + double min_dist; | ||
249 | + unsigned int idx0, idx1; | ||
250 | + | ||
251 | + //go through each point in the query fiber, looking for the indices for the closest points | ||
252 | + for(unsigned int i = 0; i < f.n_pts(); i++){ | ||
253 | + //Run through all points and find the index with the closest point, then partition the fiber and return two fibers. | ||
254 | + | ||
255 | + } | ||
256 | + | ||
257 | + | ||
258 | + | ||
259 | + } | ||
260 | +*/ | ||
178 | /// Outputs the fiber as a string | 261 | /// Outputs the fiber as a string |
179 | std::string str(){ | 262 | std::string str(){ |
180 | std::stringstream ss; | 263 | std::stringstream ss; |
181 | - size_t N = std::vector< stim::vec3<T> >::size(); | ||
182 | - ss << "---------[" << N << "]---------" << std::endl; | ||
183 | - for (size_t i = 0; i < N; i++) | ||
184 | - ss << std::vector< stim::vec3<T> >::at(i) << std::endl; | ||
185 | - ss << "--------------------" << std::endl; | 264 | + |
265 | + //create an iterator for the point list | ||
266 | + //typename std::list< point<T> >::iterator i; | ||
267 | + for(unsigned int i = 0; i < N; i++){ | ||
268 | + ss<<" [ "; | ||
269 | + for(unsigned int d = 0; d < 3; d++){ | ||
270 | + ss<<c[i][d]<<" "; | ||
271 | + } | ||
272 | + } | ||
186 | 273 | ||
187 | return ss.str(); | 274 | return ss.str(); |
188 | } | 275 | } |
189 | - | ||
190 | - /// Back method returns the last point in the fiber | ||
191 | - stim::vec3<T> back(){ | ||
192 | - return std::vector< stim::vec3<T> >::back(); | 276 | + /// Returns the number of centerline points in the fiber |
277 | + unsigned int size(){ | ||
278 | + return N; | ||
193 | } | 279 | } |
194 | 280 | ||
195 | - ////resample a fiber in the network | ||
196 | - stim::centerline<T> resample(T spacing) | ||
197 | - { | ||
198 | - //std::cout<<"fiber::resample()"<<std::endl; | ||
199 | 281 | ||
200 | - stim::vec3<T> v; //v-direction vector of the segment | ||
201 | - stim::vec3<T> p; //- intermediate point to be added | ||
202 | - stim::vec3<T> p1; // p1 - starting point of an segment on the fiber, | ||
203 | - stim::vec3<T> p2; // p2 - ending point, | ||
204 | - //double sum=0; //distance summation | 282 | + /// Bracket operator returns the element at index i |
205 | 283 | ||
206 | - size_t N = size(); | 284 | + /// @param i is the index of the element to be returned as a stim::vec |
285 | + stim::vec<T> operator[](unsigned i){ | ||
286 | + return get_vec(i); | ||
287 | + } | ||
207 | 288 | ||
208 | - centerline<T> new_c; // initialize list of new resampled points on the fiber | 289 | + /// Back method returns the last point in the fiber |
290 | + stim::vec<T> back(){ | ||
291 | + return get_vec(N-1); | ||
292 | + } | ||
293 | + ////resample a fiber in the network | ||
294 | + stim::centerline<T> resample(T spacing) | ||
295 | + { | ||
296 | + std::cout<<"fiber::resample()"<<std::endl; | ||
297 | + | ||
298 | + std::vector<T> v(3); //v-direction vector of the segment | ||
299 | + stim::vec<T> p(3); //- intermediate point to be added | ||
300 | + stim::vec<T> p1(3); // p1 - starting point of an segment on the fiber, | ||
301 | + stim::vec<T> p2(3); // p2 - ending point, | ||
302 | + double sum=0; //distance summation | ||
303 | + std::vector<stim::vec<T> > fiberPositions = centerline(); | ||
304 | + std::vector<stim::vec<T> > newPointList; // initialize list of new resampled points on the fiber | ||
209 | // for each point on the centerline (skip if it is the last point on centerline) | 305 | // for each point on the centerline (skip if it is the last point on centerline) |
306 | + //unsigned int N = fiberPositions.size(); // number of points on the fiber | ||
210 | for(unsigned int f=0; f< N-1; f++) | 307 | for(unsigned int f=0; f< N-1; f++) |
211 | - { | ||
212 | - p1 = at(f); | ||
213 | - p2 = at(f+1); | ||
214 | - v = p2 - p1; | 308 | + { |
215 | 309 | ||
216 | - T lengthSegment = v.len(); //find Length of the segment as distance between the starting and ending points of the segment | ||
217 | - | ||
218 | - if(lengthSegment >= spacing){ // if length of the segment is greater than standard deviation resample | ||
219 | - | ||
220 | - // repeat resampling until accumulated stepsize is equsl to length of the segment | ||
221 | - for(T step=0.0; step<lengthSegment; step+=spacing){ | ||
222 | - // calculate the resampled point by travelling step size in the direction of normalized gradient vector | ||
223 | - p = p1 + v * (step / lengthSegment); | ||
224 | - | ||
225 | - // add this resampled points to the new fiber list | ||
226 | - new_c.push_back(p); | 310 | + p1 = fiberPositions[f]; p2 = fiberPositions[f + 1]; v = p2 - p1; |
311 | + for(unsigned int d = 0; d < 3; d++){ | ||
312 | + sum +=v[d] * v[d];} //length of segment-distance between starting and ending point | ||
313 | + | ||
314 | + T lengthSegment = sqrt(sum); //find Length of the segment as distance between the starting and ending points of the segment | ||
315 | + | ||
316 | + if(lengthSegment >= spacing) // if length of the segment is greater than standard deviation resample | ||
317 | + { | ||
318 | + // repeat resampling until accumulated stepsize is equsl to length of the segment | ||
319 | + for(T step=0.0; step<lengthSegment; step+=spacing) | ||
320 | + { | ||
321 | + // calculate the resampled point by travelling step size in the direction of normalized gradient vector | ||
322 | + for(unsigned int i=0; i<3;i++) | ||
323 | + { | ||
324 | + p[i] = p1[i] + v[i]*(step/lengthSegment); | ||
325 | + } //for each dimension | ||
326 | + // add this resampled points to the new fiber list | ||
327 | + newPointList.push_back(p); | ||
328 | + } | ||
227 | } | 329 | } |
228 | - } | ||
229 | else // length of the segment is now less than standard deviation, push the ending point of the segment and proceed to the next point in the fiber | 330 | else // length of the segment is now less than standard deviation, push the ending point of the segment and proceed to the next point in the fiber |
230 | - new_c.push_back(at(f)); | ||
231 | - } | ||
232 | - new_c.push_back(at(N-1)); //add the last point on the fiber to the new fiber list | ||
233 | - //centerline newFiber(newPointList); | ||
234 | - return new_c; | 331 | + newPointList.push_back(fiberPositions[f+1]); |
332 | + } | ||
333 | + newPointList.push_back(fiberPositions[N-1]); //add the last point on the fiber to the new fiber list | ||
334 | + centerline newFiber(newPointList); | ||
335 | + return newFiber; | ||
235 | } | 336 | } |
236 | 337 | ||
237 | }; | 338 | }; |
stim/cuda/filter.cuh
@@ -180,6 +180,7 @@ namespace stim | @@ -180,6 +180,7 @@ namespace stim | ||
180 | #endif | 180 | #endif |
181 | 181 | ||
182 | 182 | ||
183 | +// stim::cuda::gpu_local_max<float>(centers, res, conn, DIM_X, DIM_Y); | ||
183 | stim::cuda::gpu_local_max<float>(centers, res, threshold, conn, DIM_X, DIM_Y); | 184 | stim::cuda::gpu_local_max<float>(centers, res, threshold, conn, DIM_X, DIM_Y); |
184 | 185 | ||
185 | cudaDeviceSynchronize(); | 186 | cudaDeviceSynchronize(); |
stim/cuda/ivote/local_max.cuh
@@ -10,24 +10,24 @@ namespace stim{ | @@ -10,24 +10,24 @@ namespace stim{ | ||
10 | 10 | ||
11 | // this kernel calculates the local maximum for finding the cell centers | 11 | // this kernel calculates the local maximum for finding the cell centers |
12 | template<typename T> | 12 | template<typename T> |
13 | - __global__ void cuda_local_max(T* gpuCenters, T* gpuVote, int conn, size_t x, size_t y){ | 13 | + __global__ void cuda_local_max(T* gpuCenters, T* gpuVote, T final_t, int conn, int x, int y){ |
14 | 14 | ||
15 | // calculate the 2D coordinates for this current thread. | 15 | // calculate the 2D coordinates for this current thread. |
16 | - size_t xi = blockIdx.x * blockDim.x + threadIdx.x; | ||
17 | - size_t yi = blockIdx.y * blockDim.y + threadIdx.y; | 16 | + int xi = blockIdx.x * blockDim.x + threadIdx.x; |
17 | + int yi = blockIdx.y * blockDim.y + threadIdx.y; | ||
18 | 18 | ||
19 | if(xi >= x || yi >= y) | 19 | if(xi >= x || yi >= y) |
20 | return; | 20 | return; |
21 | 21 | ||
22 | // convert 2D coordinates to 1D | 22 | // convert 2D coordinates to 1D |
23 | - size_t i = yi * x + xi; | 23 | + int i = yi * x + xi; |
24 | 24 | ||
25 | gpuCenters[i] = 0; //initialize the value at this location to zero | 25 | gpuCenters[i] = 0; //initialize the value at this location to zero |
26 | 26 | ||
27 | T val = gpuVote[i]; | 27 | T val = gpuVote[i]; |
28 | 28 | ||
29 | //compare to the threshold | 29 | //compare to the threshold |
30 | - //if(val < final_t) return; | 30 | + if(val < final_t) return; |
31 | 31 | ||
32 | //define an array to store indices with same vote value | 32 | //define an array to store indices with same vote value |
33 | /*int * IdxEq; | 33 | /*int * IdxEq; |
@@ -56,25 +56,24 @@ namespace stim{ | @@ -56,25 +56,24 @@ namespace stim{ | ||
56 | return; | 56 | return; |
57 | } | 57 | } |
58 | } */ | 58 | } */ |
59 | - //gpuCenters[i] = 1; | ||
60 | - gpuCenters[i] = gpuVote[i]; | 59 | + gpuCenters[i] = 1; |
61 | } | 60 | } |
62 | 61 | ||
63 | template<typename T> | 62 | template<typename T> |
64 | - void gpu_local_max(T* gpuCenters, T* gpuVote, unsigned int conn, size_t x, size_t y){ | 63 | + void gpu_local_max(T* gpuCenters, T* gpuVote, T final_t, unsigned int conn, unsigned int x, unsigned int y){ |
65 | 64 | ||
66 | unsigned int max_threads = stim::maxThreadsPerBlock(); | 65 | unsigned int max_threads = stim::maxThreadsPerBlock(); |
67 | /*dim3 threads(max_threads, 1); | 66 | /*dim3 threads(max_threads, 1); |
68 | dim3 blocks(x/threads.x + (x %threads.x == 0 ? 0:1) , y);*/ | 67 | dim3 blocks(x/threads.x + (x %threads.x == 0 ? 0:1) , y);*/ |
69 | - dim3 threads((unsigned int)sqrt(max_threads), (unsigned int)sqrt(max_threads) ); | ||
70 | - dim3 blocks((unsigned int)x/threads.x + 1, (unsigned int)y/threads.y + 1); | 68 | + dim3 threads( sqrt(max_threads), sqrt(max_threads) ); |
69 | + dim3 blocks(x/threads.x + 1, y/threads.y + 1); | ||
71 | 70 | ||
72 | //call the kernel to find the local maximum. | 71 | //call the kernel to find the local maximum. |
73 | - cuda_local_max <<< blocks, threads >>>(gpuCenters, gpuVote, conn, x, y); | 72 | + cuda_local_max <<< blocks, threads >>>(gpuCenters, gpuVote, final_t, conn, x, y); |
74 | } | 73 | } |
75 | 74 | ||
76 | template<typename T> | 75 | template<typename T> |
77 | - void cpu_local_max(T* cpuCenters, T* cpuVote, unsigned int conn, unsigned int x, unsigned int y){ | 76 | + void cpu_local_max(T* cpuCenters, T* cpuVote, T final_t, unsigned int conn, unsigned int x, unsigned int y){ |
78 | 77 | ||
79 | //calculate the number of bytes in the array | 78 | //calculate the number of bytes in the array |
80 | unsigned int bytes = x * y * sizeof(T); | 79 | unsigned int bytes = x * y * sizeof(T); |
@@ -91,7 +90,7 @@ namespace stim{ | @@ -91,7 +90,7 @@ namespace stim{ | ||
91 | HANDLE_ERROR(cudaMemcpy(gpuVote, cpuVote, bytes, cudaMemcpyHostToDevice)); | 90 | HANDLE_ERROR(cudaMemcpy(gpuVote, cpuVote, bytes, cudaMemcpyHostToDevice)); |
92 | 91 | ||
93 | //call the GPU version of the local max function | 92 | //call the GPU version of the local max function |
94 | - gpu_local_max<T>(gpuCenters, gpuVote, conn, x, y); | 93 | + gpu_local_max<T>(gpuCenters, gpuVote, final_t, conn, x, y); |
95 | 94 | ||
96 | //copy the cell centers data to the CPU | 95 | //copy the cell centers data to the CPU |
97 | cudaMemcpy(cpuCenters, gpuCenters, bytes, cudaMemcpyDeviceToHost) ; | 96 | cudaMemcpy(cpuCenters, gpuCenters, bytes, cudaMemcpyDeviceToHost) ; |
stim/gl/gl_spider.h
@@ -2,33 +2,47 @@ | @@ -2,33 +2,47 @@ | ||
2 | #define STIM_GL_SPIDER_H | 2 | #define STIM_GL_SPIDER_H |
3 | 3 | ||
4 | //#include <GL/glew.h> | 4 | //#include <GL/glew.h> |
5 | +///basic GL and Cuda libs | ||
5 | #include <GL/glut.h> | 6 | #include <GL/glut.h> |
6 | #include <cuda.h> | 7 | #include <cuda.h> |
7 | #include <cuda_gl_interop.h> | 8 | #include <cuda_gl_interop.h> |
8 | #include <cudaGL.h> | 9 | #include <cudaGL.h> |
9 | -#include <math.h> | 10 | + |
11 | +///stim .*h for gl tracking and visualization | ||
10 | #include <stim/gl/gl_texture.h> | 12 | #include <stim/gl/gl_texture.h> |
11 | -#include <stim/visualization/camera.h> | ||
12 | #include <stim/gl/error.h> | 13 | #include <stim/gl/error.h> |
14 | +#include <stim/visualization/camera.h> | ||
15 | +#include <stim/math/matrix_sq.h> | ||
16 | +#include <stim/cuda/spider_cost.cuh> | ||
17 | +#include <stim/visualization/glObj.h> | ||
18 | +#include <stim/cuda/cudatools/glbind.h> | ||
19 | + | ||
20 | +///stim *.h for CUDA | ||
21 | +#include <stim/cuda/cuda_texture.cuh> | ||
22 | +#include <stim/cuda/cudatools.h> | ||
23 | + | ||
24 | +///stim *.h for branch detection | ||
25 | +#include <stim/visualization/cylinder.h> | ||
26 | +#include <stim/cuda/branch_detection.cuh> | ||
27 | +#include "../../../volume-spider/glnetwork.h" | ||
28 | + | ||
29 | +/// *.h for math | ||
30 | +#include <math.h> | ||
13 | #include <stim/math/vector.h> | 31 | #include <stim/math/vector.h> |
14 | #include <stim/math/vec3.h> | 32 | #include <stim/math/vec3.h> |
15 | #include <stim/math/rect.h> | 33 | #include <stim/math/rect.h> |
16 | -#include <stim/math/matrix.h> | ||
17 | #include <stim/math/constants.h> | 34 | #include <stim/math/constants.h> |
18 | -#include <stim/cuda/spider_cost.cuh> | ||
19 | -#include <stim/cuda/cudatools/glbind.h> | ||
20 | #include <stim/cuda/arraymath.cuh> | 35 | #include <stim/cuda/arraymath.cuh> |
21 | -#include <stim/cuda/cuda_texture.cuh> | ||
22 | -#include <stim/cuda/cudatools.h> | ||
23 | -#include <stim/cuda/ivote.cuh> | ||
24 | -#include <stim/visualization/glObj.h> | 36 | +#include <stim/math/random.h> |
37 | + | ||
38 | + | ||
39 | +///c++ libs for everything | ||
25 | #include <vector> | 40 | #include <vector> |
26 | #include <stack> | 41 | #include <stack> |
27 | -#include <stim/cuda/branch_detection.cuh> | ||
28 | -#include "../../../volume-spider/glnetwork.h" | ||
29 | -#include <stim/visualization/cylinder.h> | ||
30 | #include <iostream> | 42 | #include <iostream> |
31 | #include <fstream> | 43 | #include <fstream> |
44 | + | ||
45 | +///Timing and debugging | ||
32 | #ifdef TIMING | 46 | #ifdef TIMING |
33 | #include <ctime> | 47 | #include <ctime> |
34 | #include <cstdio> | 48 | #include <cstdio> |
@@ -39,6 +53,7 @@ | @@ -39,6 +53,7 @@ | ||
39 | #include <ctime> | 53 | #include <ctime> |
40 | #endif | 54 | #endif |
41 | 55 | ||
56 | +// #include <stim/cuda/testKernel.cuh> | ||
42 | #ifdef DEBUG | 57 | #ifdef DEBUG |
43 | #include <stim/cuda/testKernel.cuh> | 58 | #include <stim/cuda/testKernel.cuh> |
44 | #endif | 59 | #endif |
@@ -61,6 +76,7 @@ class gl_spider // : public virtual gl_texture<T> | @@ -61,6 +76,7 @@ class gl_spider // : public virtual gl_texture<T> | ||
61 | double cost_time;// = 0; | 76 | double cost_time;// = 0; |
62 | double network_time;// = 0; | 77 | double network_time;// = 0; |
63 | double hit_time;// = 0; | 78 | double hit_time;// = 0; |
79 | + int iter_t; | ||
64 | #endif | 80 | #endif |
65 | 81 | ||
66 | stim::vec3<float> p; //vector designating the position of the spider. | 82 | stim::vec3<float> p; //vector designating the position of the spider. |
@@ -72,7 +88,7 @@ class gl_spider // : public virtual gl_texture<T> | @@ -72,7 +88,7 @@ class gl_spider // : public virtual gl_texture<T> | ||
72 | std::vector<float> mV; //A list of all the size vectors. | 88 | std::vector<float> mV; //A list of all the size vectors. |
73 | std::vector<float> lV; //A list of all the size vectors. | 89 | std::vector<float> lV; //A list of all the size vectors. |
74 | 90 | ||
75 | - stim::matrix<float, 4> cT; //current Transformation matrix (tissue)->(texture) | 91 | + stim::matrix_sq<float, 4> cT; //current Transformation matrix (tissue)->(texture) |
76 | GLuint texID; //OpenGL ID for the texture to be traced | 92 | GLuint texID; //OpenGL ID for the texture to be traced |
77 | stim::vec3<float> S; //Size of a voxel in the volume. | 93 | stim::vec3<float> S; //Size of a voxel in the volume. |
78 | stim::vec3<float> R; //Dimensions of the volume. | 94 | stim::vec3<float> R; //Dimensions of the volume. |
@@ -339,31 +355,6 @@ class gl_spider // : public virtual gl_texture<T> | @@ -339,31 +355,6 @@ class gl_spider // : public virtual gl_texture<T> | ||
339 | #endif | 355 | #endif |
340 | } | 356 | } |
341 | 357 | ||
342 | - | ||
343 | - float uniformRandom() | ||
344 | - { | ||
345 | - return ( (float)(rand()))/( (float)(RAND_MAX)); ///generates a random number between 0 and 1 using the uniform distribution. | ||
346 | - } | ||
347 | - | ||
348 | - float normalRandom() | ||
349 | - { | ||
350 | - float u1 = uniformRandom(); | ||
351 | - float u2 = uniformRandom(); | ||
352 | - return cos(2.0*atan(1.0)*u2)*sqrt(-1.0*log(u1)); ///generate a random number using the normal distribution between 0 and 1. | ||
353 | - } | ||
354 | - | ||
355 | - stim::vec3<float> uniformRandVector() | ||
356 | - { | ||
357 | - stim::vec3<float> r(uniformRandom(), uniformRandom(), 1.0); ///generate a random vector using the uniform distribution between 0 and 1. | ||
358 | - return r; | ||
359 | - } | ||
360 | - | ||
361 | - stim::vec3<float> normalRandVector() | ||
362 | - { | ||
363 | - stim::vec3<float> r(normalRandom(), normalRandom(), 1.0); ///generate a random vector using the normal distribution between 0 and 1. | ||
364 | - return r; | ||
365 | - } | ||
366 | - | ||
367 | 358 | ||
368 | //--------------------------------------------------------------------------// | 359 | //--------------------------------------------------------------------------// |
369 | //---------------------TEMPLATE CREATION METHODS----------------------------// | 360 | //---------------------TEMPLATE CREATION METHODS----------------------------// |
@@ -400,8 +391,8 @@ class gl_spider // : public virtual gl_texture<T> | @@ -400,8 +391,8 @@ class gl_spider // : public virtual gl_texture<T> | ||
400 | glNewList(dList, GL_COMPILE); ///create a display list of all the direction templates. | 391 | glNewList(dList, GL_COMPILE); ///create a display list of all the direction templates. |
401 | for(int i = 0; i < numSamples; i++) ///for each sample | 392 | for(int i = 0; i < numSamples; i++) ///for each sample |
402 | { | 393 | { |
403 | - z = uniformRandom()*range + Z[1]; ///generate a z coordinate | ||
404 | - theta = uniformRandom()*stim::TAU; ///generate a theta coordinate | 394 | + z = stim::Random<float>::uniformRandom()*range + Z[1]; ///generate a z coordinate |
395 | + theta = stim::Random<float>::uniformRandom()*stim::TAU; ///generate a theta coordinate | ||
405 | phi = acos(z); ///generate a phi from the z. | 396 | phi = acos(z); ///generate a phi from the z. |
406 | stim::vec3<float> sph(1, theta, phi); ///combine into a vector in spherical coordinates. | 397 | stim::vec3<float> sph(1, theta, phi); ///combine into a vector in spherical coordinates. |
407 | stim::vec3<float> cart = sph.sph2cart();///convert to cartesian. | 398 | stim::vec3<float> cart = sph.sph2cart();///convert to cartesian. |
@@ -460,7 +451,7 @@ class gl_spider // : public virtual gl_texture<T> | @@ -460,7 +451,7 @@ class gl_spider // : public virtual gl_texture<T> | ||
460 | UpdateBuffer(0.0, 0.0+0*n_pixels); | 451 | UpdateBuffer(0.0, 0.0+0*n_pixels); |
461 | for(int i = 1; i < numSamplesPos; i++) ///for the number of position samples | 452 | for(int i = 1; i < numSamplesPos; i++) ///for the number of position samples |
462 | { | 453 | { |
463 | - stim::vec3<float> temp = uniformRandVector(); ///generate a random point on a plane. | 454 | + stim::vec3<float> temp = stim::Random<float>::uniformRandVector(); ///generate a random point on a plane. |
464 | temp[0] = temp[0]*delta; | 455 | temp[0] = temp[0]*delta; |
465 | temp[1] = temp[1]*2*stim::PI; | 456 | temp[1] = temp[1]*2*stim::PI; |
466 | 457 | ||
@@ -953,6 +944,7 @@ class gl_spider // : public virtual gl_texture<T> | @@ -953,6 +944,7 @@ class gl_spider // : public virtual gl_texture<T> | ||
953 | cost_time = 0; | 944 | cost_time = 0; |
954 | network_time = 0; | 945 | network_time = 0; |
955 | hit_time = 0; | 946 | hit_time = 0; |
947 | + iter_t = 0; | ||
956 | #endif | 948 | #endif |
957 | #ifdef DEBUG | 949 | #ifdef DEBUG |
958 | iter = 0; | 950 | iter = 0; |
@@ -960,7 +952,7 @@ class gl_spider // : public virtual gl_texture<T> | @@ -960,7 +952,7 @@ class gl_spider // : public virtual gl_texture<T> | ||
960 | iter_dir = 0; | 952 | iter_dir = 0; |
961 | iter_siz = 0; | 953 | iter_siz = 0; |
962 | #endif | 954 | #endif |
963 | - stepsize = 6.0; | 955 | + stepsize = 3.0; |
964 | n_pixels = 16.0; | 956 | n_pixels = 16.0; |
965 | 957 | ||
966 | srand(100); | 958 | srand(100); |
@@ -1274,12 +1266,19 @@ class gl_spider // : public virtual gl_texture<T> | @@ -1274,12 +1266,19 @@ class gl_spider // : public virtual gl_texture<T> | ||
1274 | { | 1266 | { |
1275 | std::vector <double> ret; | 1267 | std::vector <double> ret; |
1276 | ret.resize(7); | 1268 | ret.resize(7); |
1269 | + // ret[0] = branch_time/(float)iter; | ||
1277 | ret[0] = branch_time; | 1270 | ret[0] = branch_time; |
1271 | + // ret[1] = direction_time/(float)iter; | ||
1278 | ret[1] = direction_time; | 1272 | ret[1] = direction_time; |
1273 | + // ret[2] = position_time/(float)iter; | ||
1279 | ret[2] = position_time; | 1274 | ret[2] = position_time; |
1275 | + // ret[3] = size_time/(float)iter; | ||
1280 | ret[3] = size_time; | 1276 | ret[3] = size_time; |
1277 | + // ret[4] = cost_time/(float)iter; | ||
1281 | ret[4] = cost_time; | 1278 | ret[4] = cost_time; |
1279 | + // ret[5] = network_time/(float)iter; | ||
1282 | ret[5] = network_time; | 1280 | ret[5] = network_time; |
1281 | + // ret[6] = hit_time/(float)iter; | ||
1283 | ret[6] = hit_time; | 1282 | ret[6] = hit_time; |
1284 | 1283 | ||
1285 | return ret; | 1284 | return ret; |
@@ -1311,6 +1310,7 @@ class gl_spider // : public virtual gl_texture<T> | @@ -1311,6 +1310,7 @@ class gl_spider // : public virtual gl_texture<T> | ||
1311 | setSeed(x, y, z); | 1310 | setSeed(x, y, z); |
1312 | setSeedVec(u, v, w); | 1311 | setSeedVec(u, v, w); |
1313 | setSeedMag(m); | 1312 | setSeedMag(m); |
1313 | + std::cout << getLastSeed() << getLastSeedVec() << std::cout; | ||
1314 | } | 1314 | } |
1315 | myfile.close(); | 1315 | myfile.close(); |
1316 | } else { | 1316 | } else { |
@@ -1320,7 +1320,7 @@ class gl_spider // : public virtual gl_texture<T> | @@ -1320,7 +1320,7 @@ class gl_spider // : public virtual gl_texture<T> | ||
1320 | 1320 | ||
1321 | ///Saves the network to a file. | 1321 | ///Saves the network to a file. |
1322 | void | 1322 | void |
1323 | - saveNetwork(std::string name) | 1323 | + saveNetwork(std::string name, int xoffset = 0, int yoffset = 0, int zoffset = 0) |
1324 | { | 1324 | { |
1325 | stim::glObj<float> sk1; | 1325 | stim::glObj<float> sk1; |
1326 | for(int i = 0; i < nt.sizeE(); i++) | 1326 | for(int i = 0; i < nt.sizeE(); i++) |
@@ -1331,7 +1331,7 @@ class gl_spider // : public virtual gl_texture<T> | @@ -1331,7 +1331,7 @@ class gl_spider // : public virtual gl_texture<T> | ||
1331 | for(int j = 0; j < ce.size(); j++) | 1331 | for(int j = 0; j < ce.size(); j++) |
1332 | { | 1332 | { |
1333 | sk1.TexCoord(cm[j]); | 1333 | sk1.TexCoord(cm[j]); |
1334 | - sk1.Vertex(ce[j][0], ce[j][1], ce[j][2]); | 1334 | + sk1.Vertex(ce[j][0]+xoffset, ce[j][1]+yoffset, ce[j][2]+zoffset); |
1335 | } | 1335 | } |
1336 | sk1.End(); | 1336 | sk1.End(); |
1337 | } | 1337 | } |
@@ -1408,6 +1408,11 @@ class gl_spider // : public virtual gl_texture<T> | @@ -1408,6 +1408,11 @@ class gl_spider // : public virtual gl_texture<T> | ||
1408 | #ifdef DEBUG | 1408 | #ifdef DEBUG |
1409 | std::cerr << std::endl; | 1409 | std::cerr << std::endl; |
1410 | #endif | 1410 | #endif |
1411 | + | ||
1412 | + #ifdef TIMING | ||
1413 | + iter_t++; | ||
1414 | + #endif | ||
1415 | + | ||
1411 | return current_cost; | 1416 | return current_cost; |
1412 | } | 1417 | } |
1413 | 1418 | ||
@@ -1422,36 +1427,6 @@ class gl_spider // : public virtual gl_texture<T> | @@ -1422,36 +1427,6 @@ class gl_spider // : public virtual gl_texture<T> | ||
1422 | //--------------------------------------------------------------------------// | 1427 | //--------------------------------------------------------------------------// |
1423 | //-----------------------------EXPERIMENTAL METHODS-------------------------// | 1428 | //-----------------------------EXPERIMENTAL METHODS-------------------------// |
1424 | //--------------------------------------------------------------------------// | 1429 | //--------------------------------------------------------------------------// |
1425 | - | ||
1426 | - void | ||
1427 | - MonteCarloDirectionVectors(int nSamples, float solidAngle = stim::TAU) | ||
1428 | - { | ||
1429 | -// float PHI[2];//, Z[2];//, range; | ||
1430 | -// PHI[0] = asin(solidAngle/2); | ||
1431 | -// PHI[1] = asin(0); | ||
1432 | - | ||
1433 | -// Z[0] = cos(PHI[0]); | ||
1434 | -// Z[1] = cos(PHI[1]); | ||
1435 | - | ||
1436 | -// range = Z[0] - Z[1]; | ||
1437 | - | ||
1438 | - std::vector<stim::vec3<float> > vecsUni; | ||
1439 | - for(int i = 0; i < numSamplesPos; i++) | ||
1440 | - { | ||
1441 | - stim::vec3<float> a(uniformRandom()*0.8, uniformRandom()*0.8, 0.0); | ||
1442 | - a[0] = a[0]-0.4; | ||
1443 | - a[1] = a[1]-0.4; | ||
1444 | - vecsUni.push_back(a); | ||
1445 | - } | ||
1446 | - | ||
1447 | - stringstream name; | ||
1448 | - for(int i = 0; i < numSamplesPos; i++) | ||
1449 | - name << vecsUni[i].str() << std::endl; | ||
1450 | - | ||
1451 | - std::ofstream outFile; | ||
1452 | - outFile.open("New_Pos_Vectors.txt"); | ||
1453 | - outFile << name.str().c_str(); | ||
1454 | - } | ||
1455 | /* | 1430 | /* |
1456 | void | 1431 | void |
1457 | DrawCylinder() | 1432 | DrawCylinder() |
@@ -1570,9 +1545,6 @@ class gl_spider // : public virtual gl_texture<T> | @@ -1570,9 +1545,6 @@ class gl_spider // : public virtual gl_texture<T> | ||
1570 | { | 1545 | { |
1571 | //Define the varibles and turn on Selection Mode | 1546 | //Define the varibles and turn on Selection Mode |
1572 | 1547 | ||
1573 | - #ifdef TIMING | ||
1574 | - gpuStartTimer(); | ||
1575 | - #endif | ||
1576 | 1548 | ||
1577 | GLuint selectBuf[2048]; ///size of the selection buffer in bytes. | 1549 | GLuint selectBuf[2048]; ///size of the selection buffer in bytes. |
1578 | GLint hits; ///hit fibers | 1550 | GLint hits; ///hit fibers |
@@ -1602,6 +1574,9 @@ class gl_spider // : public virtual gl_texture<T> | @@ -1602,6 +1574,9 @@ class gl_spider // : public virtual gl_texture<T> | ||
1602 | glPushMatrix(); | 1574 | glPushMatrix(); |
1603 | glLoadIdentity(); | 1575 | glLoadIdentity(); |
1604 | 1576 | ||
1577 | + #ifdef TIMING | ||
1578 | + gpuStartTimer(); | ||
1579 | + #endif | ||
1605 | CHECK_OPENGL_ERROR | 1580 | CHECK_OPENGL_ERROR |
1606 | gluLookAt(ps[0], ps[1], ps[2], | 1581 | gluLookAt(ps[0], ps[1], ps[2], |
1607 | ds[0], ds[1], ds[2], | 1582 | ds[0], ds[1], ds[2], |
@@ -1849,6 +1824,65 @@ class gl_spider // : public virtual gl_texture<T> | @@ -1849,6 +1824,65 @@ class gl_spider // : public virtual gl_texture<T> | ||
1849 | std::cout << "I broke out!" << std::endl; | 1824 | std::cout << "I broke out!" << std::endl; |
1850 | #endif | 1825 | #endif |
1851 | } | 1826 | } |
1827 | +//--------------------------------------------------------------------------// | ||
1828 | +//--------------------------------DEPRECIATED-------------------------------// | ||
1829 | +//--------------------------------------------------------------------------// | ||
1830 | +/* | ||
1831 | + float uniformRandom() | ||
1832 | + { | ||
1833 | + return ( (float)(rand()))/( (float)(RAND_MAX)); ///generates a random number between 0 and 1 using the uniform distribution. | ||
1834 | + } | ||
1835 | + | ||
1836 | + float normalRandom() | ||
1837 | + { | ||
1838 | + float u1 = uniformRandom(); | ||
1839 | + float u2 = uniformRandom(); | ||
1840 | + return cos(2.0*atan(1.0)*u2)*sqrt(-1.0*log(u1)); ///generate a random number using the normal distribution between 0 and 1. | ||
1841 | + } | ||
1842 | + | ||
1843 | + stim::vec3<float> uniformRandVector() | ||
1844 | + { | ||
1845 | + stim::vec3<float> r(uniformRandom(), uniformRandom(), 1.0); ///generate a random vector using the uniform distribution between 0 and 1. | ||
1846 | + return r; | ||
1847 | + } | ||
1848 | + | ||
1849 | + stim::vec3<float> normalRandVector() | ||
1850 | + { | ||
1851 | + stim::vec3<float> r(normalRandom(), normalRandom(), 1.0); ///generate a random vector using the normal distribution between 0 and 1. | ||
1852 | + return r; | ||
1853 | + } | ||
1854 | + | ||
1855 | + void | ||
1856 | + MonteCarloDirectionVectors(int nSamples, float solidAngle = stim::TAU) | ||
1857 | + { | ||
1858 | +// float PHI[2];//, Z[2];//, range; | ||
1859 | +// PHI[0] = asin(solidAngle/2); | ||
1860 | +// PHI[1] = asin(0); | ||
1861 | + | ||
1862 | +// Z[0] = cos(PHI[0]); | ||
1863 | +// Z[1] = cos(PHI[1]); | ||
1864 | + | ||
1865 | +// range = Z[0] - Z[1]; | ||
1866 | + | ||
1867 | + std::vector<stim::vec3<float> > vecsUni; | ||
1868 | + for(int i = 0; i < numSamplesPos; i++) | ||
1869 | + { | ||
1870 | + stim::vec3<float> a(uniformRandom()*0.8, uniformRandom()*0.8, 0.0); | ||
1871 | + a[0] = a[0]-0.4; | ||
1872 | + a[1] = a[1]-0.4; | ||
1873 | + vecsUni.push_back(a); | ||
1874 | + } | ||
1875 | + | ||
1876 | + stringstream name; | ||
1877 | + for(int i = 0; i < numSamplesPos; i++) | ||
1878 | + name << vecsUni[i].str() << std::endl; | ||
1879 | + | ||
1880 | + std::ofstream outFile; | ||
1881 | + outFile.open("New_Pos_Vectors.txt"); | ||
1882 | + outFile << name.str().c_str(); | ||
1883 | + } | ||
1884 | + | ||
1885 | +*/ | ||
1852 | }; | 1886 | }; |
1853 | } | 1887 | } |
1854 | #endif | 1888 | #endif |
stim/image/bmp.h
@@ -187,7 +187,7 @@ namespace stim { | @@ -187,7 +187,7 @@ namespace stim { | ||
187 | } | 187 | } |
188 | 188 | ||
189 | bool open(std::string filename) { //open the bitmap file and read the header data | 189 | bool open(std::string filename) { //open the bitmap file and read the header data |
190 | - file.open(filename, std::ifstream::binary); | 190 | + file.open(filename.c_str(), std::ifstream::binary); |
191 | if (!file) { | 191 | if (!file) { |
192 | std::cout << "stim::bmp ERROR: error opening file: " << filename.c_str() << std::endl; | 192 | std::cout << "stim::bmp ERROR: error opening file: " << filename.c_str() << std::endl; |
193 | return false; | 193 | return false; |
@@ -246,7 +246,7 @@ namespace stim { | @@ -246,7 +246,7 @@ namespace stim { | ||
246 | info_header.bcSize = sizeof(tagBITMAPCOREHEADER); | 246 | info_header.bcSize = sizeof(tagBITMAPCOREHEADER); |
247 | info_header.bcPlanes = 1; | 247 | info_header.bcPlanes = 1; |
248 | 248 | ||
249 | - std::ofstream outfile(filename, std::ios::binary); //open the output file for binary writing | 249 | + std::ofstream outfile(filename.c_str(), std::ios::binary); //open the output file for binary writing |
250 | outfile.write((char*)&file_header, sizeof(tagBITMAPFILEHEADER)); //write the file header | 250 | outfile.write((char*)&file_header, sizeof(tagBITMAPFILEHEADER)); //write the file header |
251 | outfile.write((char*)&info_header, sizeof(tagBITMAPCOREHEADER)); //write the information header | 251 | outfile.write((char*)&info_header, sizeof(tagBITMAPCOREHEADER)); //write the information header |
252 | 252 | ||
@@ -259,4 +259,4 @@ namespace stim { | @@ -259,4 +259,4 @@ namespace stim { | ||
259 | free(pad); | 259 | free(pad); |
260 | return true; | 260 | return true; |
261 | } | 261 | } |
262 | -} | ||
263 | \ No newline at end of file | 262 | \ No newline at end of file |
263 | +} |
stim/image/image.h
@@ -606,7 +606,7 @@ public: | @@ -606,7 +606,7 @@ public: | ||
606 | 606 | ||
607 | //crop regions given by an array of 1D index values | 607 | //crop regions given by an array of 1D index values |
608 | std::vector< image<T> > crop_idx(size_t w, size_t h, std::vector<size_t> idx) { | 608 | std::vector< image<T> > crop_idx(size_t w, size_t h, std::vector<size_t> idx) { |
609 | - std::vector<image<T>> result(idx.size()); //create an array of image files to return | 609 | + std::vector<image<T> > result(idx.size()); //create an array of image files to return |
610 | for (size_t i = 0; i < idx.size(); i++) { //for each specified index point | 610 | for (size_t i = 0; i < idx.size(); i++) { //for each specified index point |
611 | size_t y = idx[i] / X(); //calculate the y coordinate from the 1D index (center of ROI) | 611 | size_t y = idx[i] / X(); //calculate the y coordinate from the 1D index (center of ROI) |
612 | size_t x = idx[i] - y * X(); //calculate the x coordinate (center of ROI) | 612 | size_t x = idx[i] - y * X(); //calculate the x coordinate (center of ROI) |
stim/math/circle.h
@@ -18,14 +18,13 @@ class circle : plane<T> | @@ -18,14 +18,13 @@ class circle : plane<T> | ||
18 | 18 | ||
19 | private: | 19 | private: |
20 | 20 | ||
21 | - //stim::vec3<T> Y; | ||
22 | - T R; //radius of the circle | 21 | + stim::vec3<T> Y; |
23 | 22 | ||
24 | - /*CUDA_CALLABLE void | 23 | + CUDA_CALLABLE void |
25 | init() | 24 | init() |
26 | { | 25 | { |
27 | Y = U.cross(N).norm(); | 26 | Y = U.cross(N).norm(); |
28 | - }*/ | 27 | + } |
29 | 28 | ||
30 | public: | 29 | public: |
31 | using stim::plane<T>::n; | 30 | using stim::plane<T>::n; |
@@ -35,8 +34,6 @@ public: | @@ -35,8 +34,6 @@ public: | ||
35 | using stim::plane<T>::rotate; | 34 | using stim::plane<T>::rotate; |
36 | using stim::plane<T>::setU; | 35 | using stim::plane<T>::setU; |
37 | 36 | ||
38 | - using stim::plane<T>::init; | ||
39 | - | ||
40 | ///base constructor | 37 | ///base constructor |
41 | ///@param th value of the angle of the starting point from 0 to 360. | 38 | ///@param th value of the angle of the starting point from 0 to 360. |
42 | CUDA_CALLABLE | 39 | CUDA_CALLABLE |
@@ -45,28 +42,26 @@ public: | @@ -45,28 +42,26 @@ public: | ||
45 | init(); | 42 | init(); |
46 | } | 43 | } |
47 | 44 | ||
48 | - ///create a circle given a size and position in Z space. | 45 | + ///create a rectangle given a size and position in Z space. |
49 | ///@param size: size of the rectangle in ND space. | 46 | ///@param size: size of the rectangle in ND space. |
50 | ///@param z_pos z coordinate of the rectangle. | 47 | ///@param z_pos z coordinate of the rectangle. |
51 | CUDA_CALLABLE | 48 | CUDA_CALLABLE |
52 | - circle(T radius, T z_pos = (T)0) : plane<T>(z_pos) | 49 | + circle(T size, T z_pos = (T)0) : plane<T>() |
53 | { | 50 | { |
54 | - //center(stim::vec3<T>(0, 0, z_pos)); | ||
55 | - //scale(size); | ||
56 | - //init(); | ||
57 | - R = radius; | 51 | + center(stim::vec3<T>(0,0,z_pos)); |
52 | + scale(size); | ||
53 | + init(); | ||
58 | } | 54 | } |
59 | 55 | ||
60 | ///create a rectangle from a center point, normal | 56 | ///create a rectangle from a center point, normal |
61 | ///@param c: x,y,z location of the center. | 57 | ///@param c: x,y,z location of the center. |
62 | ///@param n: x,y,z direction of the normal. | 58 | ///@param n: x,y,z direction of the normal. |
63 | CUDA_CALLABLE | 59 | CUDA_CALLABLE |
64 | - circle(vec3<T> c, vec3<T> n = vec3<T>(0,0,1)) : plane<T>(n, c) | 60 | + circle(vec3<T> c, vec3<T> n = vec3<T>(0,0,1)) : plane<T>() |
65 | { | 61 | { |
66 | - //center(c); | ||
67 | - //normal(n); | ||
68 | - //init(); | ||
69 | - R = (T)1; | 62 | + center(c); |
63 | + normal(n); | ||
64 | + init(); | ||
70 | } | 65 | } |
71 | 66 | ||
72 | /*///create a rectangle from a center point, normal, and size | 67 | /*///create a rectangle from a center point, normal, and size |
@@ -89,18 +84,14 @@ public: | @@ -89,18 +84,14 @@ public: | ||
89 | ///@param n: x,y,z direction of the normal. | 84 | ///@param n: x,y,z direction of the normal. |
90 | ///@param u: x,y,z direction for the zero vector (from where the rotation starts) | 85 | ///@param u: x,y,z direction for the zero vector (from where the rotation starts) |
91 | CUDA_CALLABLE | 86 | CUDA_CALLABLE |
92 | - circle(vec3<T> c, T r, vec3<T> n = vec3<T>(0,0,1), vec3<T> u = vec3<T>(1, 0, 0)) : plane<T>() | 87 | + circle(vec3<T> c, T s, vec3<T> n = vec3<T>(0,0,1), vec3<T> u = vec3<T>(1, 0, 0)) : plane<T>() |
93 | { | 88 | { |
94 | - P = c; | ||
95 | - N = n; | 89 | + init(); |
96 | setU(u); | 90 | setU(u); |
97 | - R = r; | ||
98 | - //init(); | ||
99 | - //setU(u); | ||
100 | // U = u; | 91 | // U = u; |
101 | - //center(c); | ||
102 | - //normal(n); | ||
103 | - //scale(s); | 92 | + center(c); |
93 | + normal(n); | ||
94 | + scale(s); | ||
104 | } | 95 | } |
105 | 96 | ||
106 | ///scales the circle by a certain factor | 97 | ///scales the circle by a certain factor |
@@ -108,111 +99,86 @@ public: | @@ -108,111 +99,86 @@ public: | ||
108 | CUDA_CALLABLE | 99 | CUDA_CALLABLE |
109 | void scale(T factor) | 100 | void scale(T factor) |
110 | { | 101 | { |
111 | - //U *= factor; | ||
112 | - //Y *= factor; | ||
113 | - R *= factor; | ||
114 | - } | ||
115 | - | ||
116 | - ///set the radius of circle to a certain value | ||
117 | - ///@param value: the new radius of the circle | ||
118 | - CUDA_CALLABLE | ||
119 | - void set_R(T value) | ||
120 | - { | ||
121 | - R = value; | 102 | + U *= factor; |
103 | + Y *= factor; | ||
122 | } | 104 | } |
123 | 105 | ||
124 | ///sets the normal for the cirlce | 106 | ///sets the normal for the cirlce |
125 | ///@param n: x,y,z direction of the normal. | 107 | ///@param n: x,y,z direction of the normal. |
126 | CUDA_CALLABLE void | 108 | CUDA_CALLABLE void |
127 | - normal(vec3<T> n){ | ||
128 | - rotate(n); | 109 | + normal(vec3<T> n) |
110 | + { | ||
111 | + rotate(n, Y); | ||
129 | } | 112 | } |
130 | 113 | ||
131 | ///sets the center of the circle. | 114 | ///sets the center of the circle. |
132 | ///@param n: x,y,z location of the center. | 115 | ///@param n: x,y,z location of the center. |
133 | CUDA_CALLABLE void | 116 | CUDA_CALLABLE void |
134 | center(vec3<T> p){ | 117 | center(vec3<T> p){ |
135 | - P = p; | 118 | + this->P = p; |
136 | } | 119 | } |
137 | 120 | ||
138 | ///boolean comparison | 121 | ///boolean comparison |
139 | bool | 122 | bool |
140 | operator==(const circle<T> & rhs) | 123 | operator==(const circle<T> & rhs) |
141 | { | 124 | { |
142 | - if(P == rhs.P && U == rhs.U) | 125 | + if(P == rhs.P && U == rhs.U && Y == rhs.Y) |
143 | return true; | 126 | return true; |
144 | else | 127 | else |
145 | return false; | 128 | return false; |
146 | } | 129 | } |
147 | 130 | ||
148 | - //returns the point in world space corresponding to the polar coordinate (r, theta) | ||
149 | - CUDA_CALLABLE stim::vec3<T> | ||
150 | - p(T r, T theta) { | ||
151 | - T u = r * cos(theta); //calculate the coordinates in the planar space defined by the circle | ||
152 | - T v = r * sin(theta); | ||
153 | - | ||
154 | - vec3<T> V = U.cross(N); //calculate the orthogonal vector V | ||
155 | - return P + U * u + V * v; //calculate the cartesian coordinate of the specified point | ||
156 | - } | ||
157 | - | ||
158 | - //returns the point in world space corresponding to the value theta at radius R | ||
159 | - CUDA_CALLABLE stim::vec3<T> | ||
160 | - p(T theta) { | ||
161 | - return p(R, theta); | ||
162 | - } | ||
163 | - | ||
164 | - //get the world space value given the polar coordinates (r, theta) | ||
165 | - | ||
166 | ///get the world space value given the planar coordinates a, b in [0, 1] | 131 | ///get the world space value given the planar coordinates a, b in [0, 1] |
167 | - /*CUDA_CALLABLE stim::vec3<T> p(T a, T b) | 132 | + CUDA_CALLABLE stim::vec3<T> p(T a, T b) |
168 | { | 133 | { |
169 | stim::vec3<T> result; | 134 | stim::vec3<T> result; |
170 | 135 | ||
171 | vec3<T> A = this->P - this->U * (T)0.5 - Y * (T)0.5; | 136 | vec3<T> A = this->P - this->U * (T)0.5 - Y * (T)0.5; |
172 | result = A + this->U * a + Y * b; | 137 | result = A + this->U * a + Y * b; |
173 | return result; | 138 | return result; |
174 | - }*/ | 139 | + } |
175 | 140 | ||
176 | ///parenthesis operator returns the world space given rectangular coordinates a and b in [0 1] | 141 | ///parenthesis operator returns the world space given rectangular coordinates a and b in [0 1] |
177 | - CUDA_CALLABLE stim::vec3<T> operator()(T r, T theta) | 142 | + CUDA_CALLABLE stim::vec3<T> operator()(T a, T b) |
178 | { | 143 | { |
179 | - return p(r, theta); | ||
180 | - } | ||
181 | - | ||
182 | - //parenthesis operator returns the world space coordinate at the edge of the circle given theta | ||
183 | - CUDA_CALLABLE stim::vec3<T> operator()(T theta) { | ||
184 | - return p(theta); | 144 | + return p(a,b); |
185 | } | 145 | } |
186 | 146 | ||
187 | ///returns a vector with the points on the initialized circle. | 147 | ///returns a vector with the points on the initialized circle. |
188 | ///connecting the points results in a circle. | 148 | ///connecting the points results in a circle. |
189 | ///@param n: integer for the number of points representing the circle. | 149 | ///@param n: integer for the number of points representing the circle. |
190 | - std::vector< stim::vec3<T> > points(unsigned n) { | ||
191 | - std::vector< stim::vec3<T> > result(n); //initialize a vector of n points | ||
192 | - | ||
193 | - float dt = stim::TAU / n; | ||
194 | - for (unsigned i = 0; i < n; i++) | ||
195 | - result[i] = p(i * dt); //calculate a point on the edge of the circle | 150 | + std::vector<stim::vec3<T> > |
151 | + getPoints(int n) | ||
152 | + { | ||
153 | + std::vector<stim::vec3<T> > result; | ||
154 | + stim::vec3<T> point; | ||
155 | + T x,y; | ||
156 | + float step = 360.0/(float) n; | ||
157 | + for(float j = 0; j <= 360.0; j += step) | ||
158 | + { | ||
159 | + y = 0.5*cos(j*stim::TAU/360.0)+0.5; | ||
160 | + x = 0.5*sin(j*stim::TAU/360.0)+0.5; | ||
161 | + result.push_back(p(x,y)); | ||
162 | + } | ||
196 | return result; | 163 | return result; |
197 | } | 164 | } |
198 | - | ||
199 | - ///returns a vector with the points on the initialized circle | ||
200 | - ///connecting the points results in a circle | ||
201 | - ///@param n: integer for the number of points representing the circle | ||
202 | - ///the only difference between points and glpoints is that the first point appears twice in the returning lists | ||
203 | - std::vector< stim::vec3<T> > glpoints(unsigned n) { | ||
204 | - std::vector< stim::vec3<T> > result(n + 1); | ||
205 | - float dt = stim::TAU / n; | ||
206 | - for (unsigned i = 0; i < n; i++) | ||
207 | - result[i] = p(i * dt); | ||
208 | - result[n] = p(0); //close the circle! | ||
209 | - return result; | ||
210 | - } | ||
211 | 165 | ||
166 | + ///returns a vector with the points on the initialized circle. | ||
167 | + ///connecting the points results in a circle. | ||
168 | + ///@param n: integer for the number of points representing the circle. | ||
169 | + CUDA_CALLABLE stim::vec3<T> | ||
170 | + p(T theta) | ||
171 | + { | ||
172 | + T x,y; | ||
173 | + y = 0.5*cos(theta*STIM_TAU/360.0)+0.5; | ||
174 | + x = 0.5*sin(theta*STIM_TAU/360.0)+0.5; | ||
175 | + return p(x,y); | ||
176 | + } | ||
177 | + | ||
212 | std::string str() const | 178 | std::string str() const |
213 | { | 179 | { |
214 | std::stringstream ss; | 180 | std::stringstream ss; |
215 | - ss << "r = "<<R<<" (P=" << P.str() << ", N=" << N.str() << ", U=" << U.str() << ")"; | 181 | + ss << "(P=" << P.str() << ", N=" << N.str() << ", U=" << U.str() << ", Y=" << Y.str(); |
216 | return ss.str(); | 182 | return ss.str(); |
217 | } | 183 | } |
218 | 184 |
stim/math/random.h
@@ -17,7 +17,7 @@ protected: | @@ -17,7 +17,7 @@ protected: | ||
17 | if(seed <= 0) | 17 | if(seed <= 0) |
18 | srand(time(NULL)); | 18 | srand(time(NULL)); |
19 | else if(seed > 0) | 19 | else if(seed > 0) |
20 | - srand(time(seed)); | 20 | + srand(seed); |
21 | else | 21 | else |
22 | std::cout << "Error: Unknown value: in STIM::RANDOM" << std::endl; | 22 | std::cout << "Error: Unknown value: in STIM::RANDOM" << std::endl; |
23 | } | 23 | } |
stim/math/spharmonics.h
@@ -181,7 +181,7 @@ namespace stim { | @@ -181,7 +181,7 @@ namespace stim { | ||
181 | /// @param n is the number of points of the surface of the sphere used to create the PDF. DEFAULT 1000 | 181 | /// @param n is the number of points of the surface of the sphere used to create the PDF. DEFAULT 1000 |
182 | /// @param norm, a boolean that sets where the output vectors will be normalized between 0 and 1. | 182 | /// @param norm, a boolean that sets where the output vectors will be normalized between 0 and 1. |
183 | /// @param | 183 | /// @param |
184 | - /*void pdf(std::vector<stim::vec3<T> > sph_pts, unsigned int l, int m, stim::vec3<T> c = stim::vec3<T>(0, 0, 0), unsigned int n = 1000, bool norm = true, std::vector<T> w = std::vector<T>()) | 184 | + void pdf(std::vector<stim::vec3<T> > sph_pts, unsigned int l, int m, stim::vec3<T> c = stim::vec3<T>(0, 0, 0), unsigned int n = 1000, bool norm = true, std::vector<T> w = std::vector<T>()) |
185 | { | 185 | { |
186 | std::vector<double> weights; ///the weight at each point on the surface of the sphere. | 186 | std::vector<double> weights; ///the weight at each point on the surface of the sphere. |
187 | // weights.resize(n); | 187 | // weights.resize(n); |
@@ -223,7 +223,7 @@ namespace stim { | @@ -223,7 +223,7 @@ namespace stim { | ||
223 | } | 223 | } |
224 | } | 224 | } |
225 | mcEnd(); | 225 | mcEnd(); |
226 | - }*/ | 226 | + } |
227 | 227 | ||
228 | std::string str() { | 228 | std::string str() { |
229 | 229 | ||
@@ -313,6 +313,52 @@ namespace stim { | @@ -313,6 +313,52 @@ namespace stim { | ||
313 | T operator()(T theta, T phi) { | 313 | T operator()(T theta, T phi) { |
314 | return p(theta, phi); | 314 | return p(theta, phi); |
315 | } | 315 | } |
316 | + | ||
317 | + //overload arithmetic operations | ||
318 | + | ||
319 | + spharmonics<T> operator*(T rhs) const { | ||
320 | + | ||
321 | + spharmonics<T> result(C.size()); //create a new spherical harmonics object | ||
322 | + | ||
323 | + for (size_t c = 0; c < C.size(); c++) //for each coefficient | ||
324 | + | ||
325 | + result.C[c] = C[c] * rhs; //calculate the factor and store the result in the new spharmonics object | ||
326 | + | ||
327 | + return result; | ||
328 | + | ||
329 | + } | ||
330 | + | ||
331 | + | ||
332 | + | ||
333 | + spharmonics<T> operator+(spharmonics<T> rhs) { | ||
334 | + | ||
335 | + size_t low = std::min(C.size(), rhs.C.size()); //store the number of coefficients in the lowest object | ||
336 | + size_t high = std::max(C.size(), rhs.C.size()); //store the number of coefficients in the result | ||
337 | + bool rhs_lowest = false; //true if rhs has the lowest number of coefficients | ||
338 | + if (rhs.C.size() < C.size()) rhs_lowest = true; //if rhs has a lower number of coefficients, set the flag | ||
339 | + | ||
340 | + | ||
341 | + | ||
342 | + spharmonics<T> result(high); //create a new object | ||
343 | + | ||
344 | + size_t c; | ||
345 | + for (c = 0; c < low; c++) //perform the first batch of additions | ||
346 | + result.C[c] = C[c] + rhs.C[c]; //perform the addition | ||
347 | + | ||
348 | + for (c = low; c < high; c++) { | ||
349 | + if (rhs_lowest) | ||
350 | + result.C[c] = C[c]; | ||
351 | + else | ||
352 | + result.C[c] = rhs.C[c]; | ||
353 | + } | ||
354 | + return result; | ||
355 | + } | ||
356 | + | ||
357 | + | ||
358 | + | ||
359 | + spharmonics<T> operator-(spharmonics<T> rhs) { | ||
360 | + return (*this) + (rhs * (T)(-1)); | ||
361 | + } | ||
316 | /// Fill an NxN grid with the spherical function for theta = [0 2pi] and phi = [0 pi] | 362 | /// Fill an NxN grid with the spherical function for theta = [0 2pi] and phi = [0 pi] |
317 | void get_func(T* data, size_t X, size_t Y) { | 363 | void get_func(T* data, size_t X, size_t Y) { |
318 | T dt = stim::TAU / (T)X; //calculate the step size in each direction | 364 | T dt = stim::TAU / (T)X; //calculate the step size in each direction |
@@ -351,4 +397,4 @@ namespace stim { | @@ -351,4 +397,4 @@ namespace stim { | ||
351 | } | 397 | } |
352 | 398 | ||
353 | 399 | ||
354 | -#endif | ||
355 | \ No newline at end of file | 400 | \ No newline at end of file |
401 | +#endif |
stim/visualization/cylinder.h
@@ -3,268 +3,56 @@ | @@ -3,268 +3,56 @@ | ||
3 | #include <iostream> | 3 | #include <iostream> |
4 | #include <stim/math/circle.h> | 4 | #include <stim/math/circle.h> |
5 | #include <stim/biomodels/centerline.h> | 5 | #include <stim/biomodels/centerline.h> |
6 | -#include <stim/visualization/obj.h> | ||
7 | 6 | ||
7 | +/* | ||
8 | + | ||
9 | +*/ | ||
8 | 10 | ||
9 | namespace stim | 11 | namespace stim |
10 | { | 12 | { |
11 | template<typename T> | 13 | template<typename T> |
12 | -class cylinder : public centerline<T> { | ||
13 | -protected: | ||
14 | - | ||
15 | - using stim::centerline<T>::d; | 14 | +class cylinder |
15 | + : public centerline<T> | ||
16 | +{ | ||
17 | + private: | ||
18 | + stim::circle<T> s; //an arbitrary circle | ||
19 | + std::vector<stim::circle<T> > e; //an array of circles that store the centerline | ||
16 | 20 | ||
17 | - std::vector< stim::vec3<T> > U; //stores the array of U vectors defining the Frenet frame | ||
18 | - std::vector< T > R; //stores a list of magnitudes for each point in the centerline (assuming mags[0] is the radius) | 21 | + std::vector<stim::vec3<T> > norms; |
22 | + std::vector<stim::vec<T> > Us; | ||
23 | + std::vector<stim::vec<T> > mags; //stores a list of magnitudes for each point in the centerline (assuming mags[0] is the radius) | ||
24 | + std::vector< T > L; //length of the cylinder at each position (pre-integration) | ||
19 | 25 | ||
20 | - using stim::centerline<T>::findIdx; | ||
21 | - | ||
22 | - //calculates the U values for each point to initialize the frenet frame | ||
23 | - // this function assumes that the centerline has already been set | ||
24 | - void init() { | ||
25 | - U.resize(size()); //allocate space for the frenet frame vectors | ||
26 | - R.resize(size()); | ||
27 | - | ||
28 | - stim::circle<T> c; //create a circle | ||
29 | - stim::vec3<T> d0, d1; | ||
30 | - for (size_t i = 0; i < size() - 1; i++) { //for each line segment in the centerline | ||
31 | - c.rotate(d(i)); //rotate the circle to match that normal | ||
32 | - U[i] = c.U; //save the U vector from the circle | ||
33 | - } | ||
34 | - U[size() - 1] = c.U; //for the last point, duplicate the final frenet frame vector | ||
35 | - } | ||
36 | - | ||
37 | -public: | ||
38 | - | ||
39 | - using stim::centerline<T>::size; | ||
40 | - using stim::centerline<T>::at; | ||
41 | - using stim::centerline<T>::L; | ||
42 | - using stim::centerline<T>::length; | ||
43 | - | ||
44 | - cylinder() : centerline<T>(){} | ||
45 | - | ||
46 | - cylinder(centerline<T>c) : centerline<T>(c) { | ||
47 | - init(); | ||
48 | - } | ||
49 | - | ||
50 | - //cylinder(centerline<T>c, T r) : centerline(c) { | ||
51 | - // init(); | ||
52 | - // //add_mag(r); | ||
53 | - //} | ||
54 | - | ||
55 | - //initialize a cylinder with a list of points and magnitude values | ||
56 | - //cylinder(centerline<T>c, std::vector<T> r) : centerline(c){ | ||
57 | - // init(); | ||
58 | - // //add_mag(r); | ||
59 | - //} | ||
60 | - | ||
61 | - //copy the original radius | ||
62 | - void copy_r(std::vector<T> radius) { | ||
63 | - for (unsigned i = 0; i < radius.size(); i++) | ||
64 | - R[i] = radius[i]; | ||
65 | - } | ||
66 | - | ||
67 | - ///Returns magnitude i at the given length into the fiber (based on the pvalue). | ||
68 | - ///Interpolates the position along the line. | ||
69 | - ///@param l: the location of the in the cylinder. | ||
70 | - ///@param idx: integer location of the point closest to l but prior to it. | ||
71 | - T r(T l, int idx) { | ||
72 | - T a = (l - L[idx]) / (L[idx + 1] - L[idx]); | ||
73 | - T v2 = (R[idx] + (R[idx + 1] - R[idx])*a); | ||
74 | - | ||
75 | - return v2; | ||
76 | - } | ||
77 | - | ||
78 | - ///Returns the ith magnitude at the given p-value (p value ranges from 0 to 1). | ||
79 | - ///interpolates the radius along the line. | ||
80 | - ///@param pvalue: the location of the in the cylinder, from 0 (beginning to 1). | ||
81 | - T rl(T pvalue) { | ||
82 | - if (pvalue <= 0.0) return R[0]; | ||
83 | - if (pvalue >= 1.0) return R[size() - 1]; | ||
84 | - | ||
85 | - T l = pvalue*L[L.size() - 1]; | ||
86 | - int idx = findIdx(l); | ||
87 | - return r(l, idx); | ||
88 | - } | ||
89 | - | ||
90 | - /// Returns the magnitude at the given index | ||
91 | - /// @param i is the index of the desired point | ||
92 | - /// @param r is the index of the magnitude value | ||
93 | - T r(unsigned i) { | ||
94 | - return R[i]; | ||
95 | - } | ||
96 | - | ||
97 | - ///adds a magnitude to each point in the cylinder | ||
98 | - /*void add_mag(V val = 0) { | ||
99 | - if (M.size() == 0) M.resize(size()); //if the magnitude vector isn't initialized, resize it to match the centerline | ||
100 | - for (size_t i = 0; i < size(); i++) //for each point | ||
101 | - R[i].push_back(val); //add this value to the magnitude vector at each point | ||
102 | - }*/ | ||
103 | - | ||
104 | - //adds a magnitude based on a list of magnitudes for each point | ||
105 | - /*void add_mag(std::vector<T> val) { | ||
106 | - if (M.size() == 0) M.resize(size()); //if the magnitude vector isn't initialized, resize it to match the centerline | ||
107 | - for (size_t i = 0; i < size(); i++) //for each point | ||
108 | - R[i].push_back(val[i]); //add this value to the magnitude vector at each point | ||
109 | - }*/ | ||
110 | - | ||
111 | - //sets the value of magnitude m at point i | ||
112 | - void set_r(size_t i, T r) { | ||
113 | - R[i] = r; | ||
114 | - } | ||
115 | - | ||
116 | - /*size_t nmags() { | ||
117 | - if (M.size() == 0) return 0; | ||
118 | - else return R[0].size(); | ||
119 | - }*/ | ||
120 | - | ||
121 | - ///Returns a circle representing the cylinder cross section at point i | ||
122 | - stim::circle<T> circ(size_t i) { | ||
123 | - return stim::circle<T>(at(i), R[i], d(i), U[i]); | ||
124 | - } | ||
125 | - | ||
126 | - ///Returns an OBJ object representing the cylinder with a radial tesselation value of N using magnitude m | ||
127 | - stim::obj<T> OBJ(size_t N) { | ||
128 | - stim::obj<T> out; //create an OBJ object | ||
129 | - stim::circle<T> c0, c1; | ||
130 | - std::vector< stim::vec3<T> > p0, p1; //allocate space for the point sets representing the circles bounding each cylinder segment | ||
131 | - T u0, u1, v0, v1; //allocate variables to store running texture coordinates | ||
132 | - for (size_t i = 1; i < size(); i++) { //for each line segment in the cylinder | ||
133 | - c0 = circ(i - 1); //get the two circles bounding the line segment | ||
134 | - c1 = circ(i); | ||
135 | - | ||
136 | - p0 = c0.points(N); //get t points for each of the end caps | ||
137 | - p1 = c1.points(N); | ||
138 | - | ||
139 | - u0 = L[i - 1] / length(); //calculate the texture coordinate (u, v) where u runs along the cylinder length | ||
140 | - u1 = L[i] / length(); | ||
141 | - | ||
142 | - for (size_t n = 1; n < N; n++) { //for each point in the circle | ||
143 | - v0 = (double)(n-1) / (double)(N - 1); //v texture coordinate runs around the cylinder | ||
144 | - v1 = (double)(n) / (double)(N - 1); | ||
145 | - out.Begin(OBJ_FACE); //start a face (quad) | ||
146 | - out.TexCoord(u0, v0); | ||
147 | - out.Vertex(p0[n - 1][0], p0[n - 1][1], p0[n - 1][2]); //output the points composing a strip of quads wrapping the cylinder segment | ||
148 | - out.TexCoord(u1, v0); | ||
149 | - out.Vertex(p1[n - 1][0], p1[n - 1][1], p1[n - 1][2]); | ||
150 | - | ||
151 | - out.TexCoord(u0, v1); | ||
152 | - out.Vertex(p1[n][0], p1[n][1], p1[n][2]); | ||
153 | - out.TexCoord(u1, v1); | ||
154 | - out.Vertex(p0[n][0], p0[n][1], p0[n][2]); | ||
155 | - out.End(); | ||
156 | - } | ||
157 | - v0 = (double)(N - 2) / (double)(N - 1); //v texture coordinate runs around the cylinder | ||
158 | - v1 = 1.0; | ||
159 | - out.Begin(OBJ_FACE); | ||
160 | - out.TexCoord(u0, v0); | ||
161 | - out.Vertex(p0[N - 1][0], p0[N - 1][1], p0[N - 1][2]); //output the points composing a strip of quads wrapping the cylinder segment | ||
162 | - out.TexCoord(u1, v0); | ||
163 | - out.Vertex(p1[N - 1][0], p1[N - 1][1], p1[N - 1][2]); | ||
164 | - | ||
165 | - out.TexCoord(u0, v1); | ||
166 | - out.Vertex(p1[0][0], p1[0][1], p1[0][2]); | ||
167 | - out.TexCoord(u1, v1); | ||
168 | - out.Vertex(p0[0][0], p0[0][1], p0[0][2]); | ||
169 | - out.End(); | ||
170 | - } | ||
171 | - return out; | ||
172 | - } | ||
173 | - | ||
174 | - std::string str() { | ||
175 | - std::stringstream ss; | ||
176 | - size_t N = std::vector< stim::vec3<T> >::size(); | ||
177 | - ss << "---------[" << N << "]---------" << std::endl; | ||
178 | - for (size_t i = 0; i < N; i++) | ||
179 | - ss << std::vector< stim::vec3<T> >::at(i) << " r = " << R[i] << " u = " << U[i] << std::endl; | ||
180 | - ss << "--------------------" << std::endl; | ||
181 | - | ||
182 | - return ss.str(); | ||
183 | - } | ||
184 | - | ||
185 | - /// Integrates a magnitude value along the cylinder. | ||
186 | - /// @param m is the magnitude value to be integrated (this is usually the radius) | ||
187 | - T integrate() { | ||
188 | - T sum = 0; //initialize the integral to zero | ||
189 | - if (L.size() == 1) | ||
190 | - return sum; | ||
191 | - else { | ||
192 | - T m0, m1; //allocate space for both magnitudes in a single segment | ||
193 | - m0 = R[0]; //initialize the first point and magnitude to the first point in the cylinder | ||
194 | - T len = L[1]; //allocate space for the segment length | ||
195 | 26 | ||
27 | + using stim::centerline<T>::c; | ||
28 | + using stim::centerline<T>::N; | ||
29 | + | ||
30 | + ///default init | ||
31 | + void | ||
32 | + init() | ||
33 | + { | ||
196 | 34 | ||
197 | - for (unsigned p = 1; p < size(); p++) { //for every consecutive point in the cylinder | ||
198 | - m1 = R[p]; | ||
199 | - if (p > 1) len = (L[p] - L[p - 1]); //calculate the segment length using the L array | ||
200 | - sum += (m0 + m1) / (T)2.0 * len; //add the average magnitude, weighted by the segment length | ||
201 | - m0 = m1; //move to the next segment by shifting points | ||
202 | - } | ||
203 | - return sum; //return the integral | ||
204 | - } | ||
205 | - } | ||
206 | - | ||
207 | - /// Resamples the cylinder to provide a maximum distance of "spacing" between centerline points. All current | ||
208 | - /// centerline points are guaranteed to exist in the new cylinder | ||
209 | - /// @param spacing is the maximum spacing allowed between sample points | ||
210 | - cylinder<T> resample(T spacing) { | ||
211 | - cylinder<T> c = stim::centerline<T>::resample(spacing); //resample the centerline and use it to create a new cylinder | ||
212 | - | ||
213 | - //size_t nm = nmags(); //get the number of magnitude values in the current cylinder | ||
214 | - //if (nm > 0) { //if there are magnitude values | ||
215 | - // std::vector<T> magvec(nm, 0); //create a magnitude vector for a single point | ||
216 | - // c.M.resize(c.size(), magvec); //allocate space for a magnitude vector at each point of the new cylinder | ||
217 | - //} | ||
218 | - | ||
219 | - T l, t; | ||
220 | - for (size_t i = 0; i < c.size(); i++) { //for each point in the new cylinder | ||
221 | - l = c.L[i]; //get the length along the new cylinder | ||
222 | - t = l / length(); //calculate the parameter value along the new cylinder | ||
223 | - //for (size_t mag = 0; mag < nm; mag++) { //for each magnitude value | ||
224 | - c.R[i] = r(t); //retrieve the interpolated magnitude from the current cylinder and store it in the new one | ||
225 | - //} | ||
226 | - } | ||
227 | - return c; | ||
228 | - } | ||
229 | - | ||
230 | - std::vector< stim::cylinder<T> > split(unsigned int idx) { | ||
231 | - | ||
232 | - unsigned N = size(); | ||
233 | - std::vector< stim::centerline<T> > LL; | ||
234 | - LL.resize(2); | ||
235 | - LL = (*this).centerline<T>::split(idx); | ||
236 | - std::vector< stim::cylinder<T> > C(LL.size()); | ||
237 | - unsigned i = 0; | ||
238 | - C[0] = LL[0]; | ||
239 | - //C[0].R.resize(idx); | ||
240 | - for (; i < idx + 1; i++) { | ||
241 | - //for(unsigned d = 0; d < 3; d++) | ||
242 | - //C[0][i][d] = LL[0].c[i][d]; | ||
243 | - C[0].R[i] = R[i]; | ||
244 | - //C[0].R[i].resize(1); | ||
245 | - } | ||
246 | - if (C.size() == 2) { | ||
247 | - C[1] = LL[1]; | ||
248 | - i--; | ||
249 | - //C[1].M.resize(N - idx); | ||
250 | - for (; i < N; i++) { | ||
251 | - //for(unsigned d = 0; d < 3; d++) | ||
252 | - //C[1][i - idx][d] = LL[1].c[i - idx][d]; | ||
253 | - C[1].R[i - idx] = R[i]; | ||
254 | - //C[1].M[i - idx].resize(1); | ||
255 | - } | ||
256 | } | 35 | } |
257 | 36 | ||
258 | - return C; | ||
259 | - } | ||
260 | - | 37 | + ///Calculate the physical length of the fiber at each point in the fiber. |
38 | + void | ||
39 | + calculateL() | ||
40 | + { | ||
41 | +/* L.resize(inP.size()); | ||
42 | + T temp = (T)0; | ||
43 | + L[0] = 0; | ||
44 | + for(size_t i = 1; i < L.size(); i++) | ||
45 | + { | ||
46 | + temp += (inP[i-1] - inP[i]).len(); | ||
47 | + L[i] = temp; | ||
48 | + } | ||
49 | +*/ } | ||
261 | 50 | ||
262 | - /* | ||
263 | - ///inits the cylinder from a list of points (std::vector of stim::vec3 --inP) and magnitudes (inM) | 51 | + ///inits the cylinder from a list of points (std::vector of stim::vec3 --inP) and radii (inM) |
264 | void | 52 | void |
265 | - init(centerline inP, std::vector< std::vector<T> > inM) { | ||
266 | - M = inM; //the magnitude vector can be copied directly | ||
267 | - (*this) = inP; //the centerline can be copied to this class directly | 53 | + init(std::vector<stim::vec3<T> > inP, std::vector<stim::vec<T> > inM) |
54 | + { | ||
55 | + mags = inM; | ||
268 | stim::vec3<float> v1; | 56 | stim::vec3<float> v1; |
269 | stim::vec3<float> v2; | 57 | stim::vec3<float> v2; |
270 | e.resize(inP.size()); | 58 | e.resize(inP.size()); |
@@ -286,7 +74,7 @@ public: | @@ -286,7 +74,7 @@ public: | ||
286 | } | 74 | } |
287 | 75 | ||
288 | stim::vec3<T> dr = (inP[1] - inP[0]).norm(); | 76 | stim::vec3<T> dr = (inP[1] - inP[0]).norm(); |
289 | - s = stim::circle<T>(inP[0], inR[0][0], dr, stim::vec3<T>(1,0,0)); | 77 | + s = stim::circle<T>(inP[0], inM[0][0], dr, stim::vec3<T>(1,0,0)); |
290 | norms[0] = s.N; | 78 | norms[0] = s.N; |
291 | e[0] = s; | 79 | e[0] = s; |
292 | Us[0] = e[0].U; | 80 | Us[0] = e[0].U; |
@@ -300,7 +88,7 @@ public: | @@ -300,7 +88,7 @@ public: | ||
300 | 88 | ||
301 | norms[i] = s.N; | 89 | norms[i] = s.N; |
302 | 90 | ||
303 | - s.scale(inR[i][0]/inR[i-1][0]); | 91 | + s.scale(inM[i][0]/inM[i-1][0]); |
304 | e[i] = s; | 92 | e[i] = s; |
305 | Us[i] = e[i].U; | 93 | Us[i] = e[i].U; |
306 | } | 94 | } |
@@ -312,7 +100,7 @@ public: | @@ -312,7 +100,7 @@ public: | ||
312 | 100 | ||
313 | norms[j] = s.N; | 101 | norms[j] = s.N; |
314 | 102 | ||
315 | - s.scale(inR[j][0]/inR[j-1][0]); | 103 | + s.scale(inM[j][0]/inM[j-1][0]); |
316 | e[j] = s; | 104 | e[j] = s; |
317 | Us[j] = e[j].U; | 105 | Us[j] = e[j].U; |
318 | } | 106 | } |
@@ -439,7 +227,7 @@ public: | @@ -439,7 +227,7 @@ public: | ||
439 | stim::vec<T> zero(0.0,0.0); | 227 | stim::vec<T> zero(0.0,0.0); |
440 | temp.resize(inM.size(), zero); | 228 | temp.resize(inM.size(), zero); |
441 | for(int i = 0; i < inM.size(); i++) | 229 | for(int i = 0; i < inM.size(); i++) |
442 | - temp[i][0] = inR[i]; | 230 | + temp[i][0] = inM[i]; |
443 | init(inP, temp); | 231 | init(inP, temp); |
444 | } | 232 | } |
445 | 233 | ||
@@ -458,18 +246,13 @@ public: | @@ -458,18 +246,13 @@ public: | ||
458 | init(inP, inM); | 246 | init(inP, inM); |
459 | } | 247 | } |
460 | 248 | ||
461 | - //assignment operator creates a cylinder from a centerline (default radius is zero) | ||
462 | - cylinder& operator=(stim::centerline<T> c) { | ||
463 | - init(c); | ||
464 | - } | ||
465 | - | ||
466 | ///Returns the number of points on the cylinder centerline | 249 | ///Returns the number of points on the cylinder centerline |
467 | 250 | ||
468 | unsigned int size(){ | 251 | unsigned int size(){ |
469 | return N; | 252 | return N; |
470 | } | 253 | } |
471 | 254 | ||
472 | - | 255 | + |
473 | ///Returns a position vector at the given p-value (p value ranges from 0 to 1). | 256 | ///Returns a position vector at the given p-value (p value ranges from 0 to 1). |
474 | ///interpolates the position along the line. | 257 | ///interpolates the position along the line. |
475 | ///@param pvalue: the location of the in the cylinder, from 0 (beginning to 1). | 258 | ///@param pvalue: the location of the in the cylinder, from 0 (beginning to 1). |
@@ -483,7 +266,22 @@ public: | @@ -483,7 +266,22 @@ public: | ||
483 | T l = pvalue*L[L.size()-1]; | 266 | T l = pvalue*L[L.size()-1]; |
484 | int idx = findIdx(l); | 267 | int idx = findIdx(l); |
485 | return (p(l,idx)); | 268 | return (p(l,idx)); |
486 | - } | 269 | +/* T rat = (l-L[idx])/(L[idx+1]-L[idx]); |
270 | + stim::vec3<T> v1( | ||
271 | + c[idx][0], | ||
272 | + c[idx][1], | ||
273 | + c[idx][2] | ||
274 | + ); | ||
275 | + | ||
276 | + stim::vec3<T> v2( | ||
277 | + c[idx+1][0], | ||
278 | + c[idx+1][1], | ||
279 | + c[idx+1][2] | ||
280 | + ); | ||
281 | + | ||
282 | +// return( e[idx].P + (e[idx+1].P-e[idx].P)*rat); | ||
283 | + return( v1 + (v2 - v1)*rat); | ||
284 | +*/ } | ||
487 | 285 | ||
488 | ///Returns a position vector at the given length into the fiber (based on the pvalue). | 286 | ///Returns a position vector at the given length into the fiber (based on the pvalue). |
489 | ///Interpolates the radius along the line. | 287 | ///Interpolates the radius along the line. |
@@ -523,7 +321,10 @@ public: | @@ -523,7 +321,10 @@ public: | ||
523 | T l = pvalue*L[L.size()-1]; | 321 | T l = pvalue*L[L.size()-1]; |
524 | int idx = findIdx(l); | 322 | int idx = findIdx(l); |
525 | return (r(l,idx)); | 323 | return (r(l,idx)); |
526 | - } | 324 | +/* T rat = (l-L[idx])/(L[idx+1]-L[idx]); |
325 | +// return (mags[idx][0] + (mags[idx+1][0]-mags[idx][0])*rat); | ||
326 | + return (e[idx].U.len() + (e[idx+1].U.len() - e[idx].U.len())*rat); | ||
327 | +*/ } | ||
527 | 328 | ||
528 | ///Returns a radius at the given length into the fiber (based on the pvalue). | 329 | ///Returns a radius at the given length into the fiber (based on the pvalue). |
529 | ///Interpolates the position along the line. | 330 | ///Interpolates the position along the line. |
@@ -705,10 +506,10 @@ public: | @@ -705,10 +506,10 @@ public: | ||
705 | 506 | ||
706 | return cylinder<T>(result); | 507 | return cylinder<T>(result); |
707 | 508 | ||
708 | - }*/ | 509 | + } |
709 | 510 | ||
710 | 511 | ||
711 | }; | 512 | }; |
712 | 513 | ||
713 | } | 514 | } |
714 | -#endif | ||
715 | \ No newline at end of file | 515 | \ No newline at end of file |
516 | +#endif |
stim/visualization/gl_spharmonics.h
@@ -51,6 +51,13 @@ namespace stim { | @@ -51,6 +51,13 @@ namespace stim { | ||
51 | magnitude = true; | 51 | magnitude = true; |
52 | } | 52 | } |
53 | 53 | ||
54 | + gl_spharmonics(stim::spharmonics<T> disp, stim::spharmonics<T> color, size_t slices) : | ||
55 | + gl_spharmonics<T>(slices) | ||
56 | + { | ||
57 | + Sc = color; | ||
58 | + Sd = disp; | ||
59 | + } | ||
60 | + | ||
54 | ~gl_spharmonics() { | 61 | ~gl_spharmonics() { |
55 | if (dlist) glDeleteLists(dlist, 1); //delete the display list when the object is destroyed | 62 | if (dlist) glDeleteLists(dlist, 1); //delete the display list when the object is destroyed |
56 | } | 63 | } |
@@ -166,13 +173,13 @@ namespace stim { | @@ -166,13 +173,13 @@ namespace stim { | ||
166 | } | 173 | } |
167 | 174 | ||
168 | /// Project a set of samples onto the basis | 175 | /// Project a set of samples onto the basis |
169 | - void project(std::vector<vec3<float>>& vlist, size_t nc) { | 176 | + void project(std::vector<vec3<float> >& vlist, size_t nc) { |
170 | Sd.project(vlist, nc); | 177 | Sd.project(vlist, nc); |
171 | Sc = Sd; | 178 | Sc = Sd; |
172 | } | 179 | } |
173 | 180 | ||
174 | /// Calculate a density function from a list of points in spherical coordinates | 181 | /// Calculate a density function from a list of points in spherical coordinates |
175 | - void pdf(std::vector<stim::vec3<T>>& vlist, size_t nc) { | 182 | + void pdf(std::vector<stim::vec3<T> >& vlist, size_t nc) { |
176 | Sd.pdf(vlist, nc); | 183 | Sd.pdf(vlist, nc); |
177 | Sc = Sd; | 184 | Sc = Sd; |
178 | } | 185 | } |
@@ -196,4 +203,4 @@ namespace stim { | @@ -196,4 +203,4 @@ namespace stim { | ||
196 | 203 | ||
197 | 204 | ||
198 | 205 | ||
199 | -#endif | ||
200 | \ No newline at end of file | 206 | \ No newline at end of file |
207 | +#endif |