Blame view

stim/visualization/cylinder.h 13.7 KB
5b6c317a   Pavel Govyadinov   implemented the c...
1
2
3
4
  #ifndef STIM_CYLINDER_H
  #define STIM_CYLINDER_H
  #include <iostream>
  #include <stim/math/circle.h>
0311ab81   Pavel Govyadinov   fixed some issues...
5
  #include <stim/biomodels/centerline.h>
5b6c317a   Pavel Govyadinov   implemented the c...
6
  
96e8ab1f   David Mayerich   fixed stim::cylin...
7
8
9
  /*
  	
  */
5b6c317a   Pavel Govyadinov   implemented the c...
10
11
12
13
14
  
  namespace stim
  {
  template<typename T>
  class cylinder
0311ab81   Pavel Govyadinov   fixed some issues...
15
   : public centerline<T>
5b6c317a   Pavel Govyadinov   implemented the c...
16
17
  {
  	private:
96e8ab1f   David Mayerich   fixed stim::cylin...
18
19
  		stim::circle<T> s;							//an arbitrary circle
  		std::vector<stim::circle<T> > e;			//an array of circles that store the centerline
0311ab81   Pavel Govyadinov   fixed some issues...
20
21
22
  
  		std::vector<stim::vec3<T> > norms;
  		std::vector<stim::vec<T> > Us;
96e8ab1f   David Mayerich   fixed stim::cylin...
23
24
  		std::vector<stim::vec<T> > mags;			//stores a list of magnitudes for each point in the centerline (assuming mags[0] is the radius)
  		std::vector< T > L;							//length of the cylinder at each position (pre-integration)
0311ab81   Pavel Govyadinov   fixed some issues...
25
26
27
28
  
  
  		using stim::centerline<T>::c;
  		using stim::centerline<T>::N;
26aee9ed   Pavel Govyadinov   changed circle cl...
29
30
  	
  		///default init	
5b6c317a   Pavel Govyadinov   implemented the c...
31
  		void
26aee9ed   Pavel Govyadinov   changed circle cl...
32
33
  		init()
  		{
10654a1f   Pavel Govyadinov   added the necessa...
34
  
5b6c317a   Pavel Govyadinov   implemented the c...
35
36
  		}
  
0311ab81   Pavel Govyadinov   fixed some issues...
37
38
39
40
41
42
43
44
45
46
47
48
49
50
  		///Calculate the physical length of the fiber at each point in the fiber.
  		void
  		calculateL()
  		{
  /*			L.resize(inP.size());
  			T temp = (T)0;
  			L[0] = 0;
  			for(size_t i = 1; i < L.size(); i++)
  			{
  				temp += (inP[i-1] - inP[i]).len();
  				L[i] = temp;
  			}
  */		}
  
7d3162a2   Pavel Govyadinov   fixed majority of...
51
  		///inits the cylinder from a list of points (std::vector of stim::vec3 --inP) and radii (inM)
5b6c317a   Pavel Govyadinov   implemented the c...
52
  		void
308a743c   David Mayerich   fixed class compa...
53
  		init(std::vector<stim::vec3<T> > inP, std::vector<stim::vec<T> > inM)
26aee9ed   Pavel Govyadinov   changed circle cl...
54
  		{
5b6c317a   Pavel Govyadinov   implemented the c...
55
  			mags = inM;
308a743c   David Mayerich   fixed class compa...
56
57
  			stim::vec3<float> v1;
  			stim::vec3<float> v2;
8c4f5d84   Pavel Govyadinov   fixed the issue w...
58
  			e.resize(inP.size());
0311ab81   Pavel Govyadinov   fixed some issues...
59
60
61
62
  
  			norms.resize(inP.size());
  			Us.resize(inP.size());
  
8c4f5d84   Pavel Govyadinov   fixed the issue w...
63
64
  			if(inP.size() < 2)
  				return;
8495a970   Pavel Govyadinov   added comments to...
65
66
  
  			//calculate each L.
1b2858a2   David Mayerich   fixed some commen...
67
68
69
  			L.resize(inP.size());						//the number of precomputed lengths will equal the number of points
  			T temp = (T)0;								//length up to that point
  			L[0] = temp;
308a743c   David Mayerich   fixed class compa...
70
  			for(size_t i = 1; i < L.size(); i++)
10654a1f   Pavel Govyadinov   added the necessa...
71
  			{
8c4f5d84   Pavel Govyadinov   fixed the issue w...
72
  				temp += (inP[i-1] - inP[i]).len();
bf23ee36   Pavel Govyadinov   more minor bug fi...
73
  				L[i] = temp;
10654a1f   Pavel Govyadinov   added the necessa...
74
  			}
9c97e126   David Mayerich   added an axis-ali...
75
  
308a743c   David Mayerich   fixed class compa...
76
77
  			stim::vec3<T> dr = (inP[1] - inP[0]).norm();
  			s = stim::circle<T>(inP[0], inM[0][0], dr, stim::vec3<T>(1,0,0));
0311ab81   Pavel Govyadinov   fixed some issues...
78
  			norms[0] = s.N;
8c4f5d84   Pavel Govyadinov   fixed the issue w...
79
  			e[0] = s;
0311ab81   Pavel Govyadinov   fixed some issues...
80
  			Us[0] = e[0].U;
308a743c   David Mayerich   fixed class compa...
81
  			for(size_t i = 1; i < inP.size()-1; i++)
8c4f5d84   Pavel Govyadinov   fixed the issue w...
82
83
84
85
86
87
  			{
  				s.center(inP[i]);
  				v1 = (inP[i] - inP[i-1]).norm();
  				v2 = (inP[i+1] - inP[i]).norm();
  				dr = (v1+v2).norm();
  				s.normal(dr);
0311ab81   Pavel Govyadinov   fixed some issues...
88
89
90
  
  				norms[i] = s.N;
  
8c4f5d84   Pavel Govyadinov   fixed the issue w...
91
92
  				s.scale(inM[i][0]/inM[i-1][0]);
  				e[i] = s;
0311ab81   Pavel Govyadinov   fixed some issues...
93
  				Us[i] = e[i].U;
8c4f5d84   Pavel Govyadinov   fixed the issue w...
94
95
96
97
98
99
  			}
  			
  			int j = inP.size()-1;
  			s.center(inP[j]);
  			dr = (inP[j] - inP[j-1]).norm();
  			s.normal(dr);
0311ab81   Pavel Govyadinov   fixed some issues...
100
101
102
  
  			norms[j] = s.N;
  
8c4f5d84   Pavel Govyadinov   fixed the issue w...
103
104
  			s.scale(inM[j][0]/inM[j-1][0]);
  			e[j] = s;
0311ab81   Pavel Govyadinov   fixed some issues...
105
  			Us[j] = e[j].U;
26aee9ed   Pavel Govyadinov   changed circle cl...
106
107
  		}
  		
8495a970   Pavel Govyadinov   added comments to...
108
  		///returns the direction vector at point idx.
308a743c   David Mayerich   fixed class compa...
109
  		stim::vec3<T>
26aee9ed   Pavel Govyadinov   changed circle cl...
110
111
112
113
  		d(int idx)
  		{
  			if(idx == 0)
  			{
0311ab81   Pavel Govyadinov   fixed some issues...
114
115
116
117
118
119
120
  				stim::vec3<T> temp(
  						c[idx+1][0]-c[idx][0],	
  						c[idx+1][1]-c[idx][1],	
  						c[idx+1][2]-c[idx][2]
  						);	
  //				return (e[idx+1].P - e[idx].P).norm();
  				return (temp.norm());
26aee9ed   Pavel Govyadinov   changed circle cl...
121
  			}
0311ab81   Pavel Govyadinov   fixed some issues...
122
  			else if(idx == N-1)
26aee9ed   Pavel Govyadinov   changed circle cl...
123
  			{
0311ab81   Pavel Govyadinov   fixed some issues...
124
125
126
127
128
129
130
  				stim::vec3<T> temp(
  						c[idx][0]-c[idx+1][0],	
  						c[idx][1]-c[idx+1][1],	
  						c[idx][2]-c[idx+1][2]
  						);	
  			//	return (e[idx].P - e[idx-1].P).norm();
  				return (temp.norm());
26aee9ed   Pavel Govyadinov   changed circle cl...
131
132
133
  			}
  			else
  			{
8c4f5d84   Pavel Govyadinov   fixed the issue w...
134
  //				return (e[idx+1].P - e[idx].P).norm();
0311ab81   Pavel Govyadinov   fixed some issues...
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
  //				stim::vec3<float> v1 = (e[idx].P-e[idx-1].P).norm();
  				stim::vec3<T> v1(
  						c[idx][0]-c[idx-1][0],	
  						c[idx][1]-c[idx-1][1],	
  						c[idx][2]-c[idx-1][2]
  						);	
  						
  //				stim::vec3<float> v2 = (e[idx+1].P-e[idx].P).norm();
  				stim::vec3<T> v2(
  						c[idx+1][0]-c[idx][0],	
  						c[idx+1][1]-c[idx][1],	
  						c[idx+1][2]-c[idx][2]
  						);
  					
  				return (v1.norm()+v2.norm()).norm();			
8c4f5d84   Pavel Govyadinov   fixed the issue w...
150
151
152
  			} 
  	//		return e[idx].N;	
  
10654a1f   Pavel Govyadinov   added the necessa...
153
154
  		}
  
308a743c   David Mayerich   fixed class compa...
155
  		stim::vec3<T>
8c4f5d84   Pavel Govyadinov   fixed the issue w...
156
  		d(T l, int idx)
26aee9ed   Pavel Govyadinov   changed circle cl...
157
  		{
0311ab81   Pavel Govyadinov   fixed some issues...
158
  			if(idx == 0 || idx == N-1)
10654a1f   Pavel Govyadinov   added the necessa...
159
  			{
0311ab81   Pavel Govyadinov   fixed some issues...
160
161
  				return norms[idx];
  //				return e[idx].N;
10654a1f   Pavel Govyadinov   added the necessa...
162
  			}
8c4f5d84   Pavel Govyadinov   fixed the issue w...
163
164
  			else
  			{
0311ab81   Pavel Govyadinov   fixed some issues...
165
  				
8c4f5d84   Pavel Govyadinov   fixed the issue w...
166
  				T rat = (l-L[idx])/(L[idx+1]-L[idx]);
0311ab81   Pavel Govyadinov   fixed some issues...
167
168
  				return(	norms[idx] + (norms[idx+1] - norms[idx])*rat);
  //				return(	e[idx].N + (e[idx+1].N - e[idx].N)*rat);
8c4f5d84   Pavel Govyadinov   fixed the issue w...
169
  			} 
10654a1f   Pavel Govyadinov   added the necessa...
170
171
  		}
  
8c4f5d84   Pavel Govyadinov   fixed the issue w...
172
  
8495a970   Pavel Govyadinov   added comments to...
173
174
  		///finds the index of the point closest to the length l on the lower bound.
  		///binary search.
10654a1f   Pavel Govyadinov   added the necessa...
175
  		int
26aee9ed   Pavel Govyadinov   changed circle cl...
176
177
178
179
180
  		findIdx(T l)
  		{
  			unsigned int i = L.size()/2;
  			unsigned int max = L.size()-1;
  			unsigned int min = 0;
26aee9ed   Pavel Govyadinov   changed circle cl...
181
  			while(i > 0 && i < L.size()-1)
10654a1f   Pavel Govyadinov   added the necessa...
182
  			{
8c4f5d84   Pavel Govyadinov   fixed the issue w...
183
184
  //				std::cerr << "Trying " << i << std::endl;
  //				std::cerr << "l is " << l << ", L[" << i << "]" << L[i] << std::endl;
26aee9ed   Pavel Govyadinov   changed circle cl...
185
  				if(l < L[i])
10654a1f   Pavel Govyadinov   added the necessa...
186
  				{
26aee9ed   Pavel Govyadinov   changed circle cl...
187
  					max = i;
26aee9ed   Pavel Govyadinov   changed circle cl...
188
  					i = min+(max-min)/2;
10654a1f   Pavel Govyadinov   added the necessa...
189
  				}
26aee9ed   Pavel Govyadinov   changed circle cl...
190
  				else if(L[i] <= l && L[i+1] >= l)
10654a1f   Pavel Govyadinov   added the necessa...
191
192
193
194
195
  				{
  					break;
  				}
  				else
  				{
26aee9ed   Pavel Govyadinov   changed circle cl...
196
  					min = i;
26aee9ed   Pavel Govyadinov   changed circle cl...
197
  					i = min+(max-min)/2;
10654a1f   Pavel Govyadinov   added the necessa...
198
199
200
201
  				}
  			}
  			return i;
  		}
5b6c317a   Pavel Govyadinov   implemented the c...
202
  
9c97e126   David Mayerich   added an axis-ali...
203
204
  	public:
  		///default constructor
26aee9ed   Pavel Govyadinov   changed circle cl...
205
  		cylinder()
0311ab81   Pavel Govyadinov   fixed some issues...
206
  		// : centerline<T>()
26aee9ed   Pavel Govyadinov   changed circle cl...
207
208
209
  		{
  
  		}
9c97e126   David Mayerich   added an axis-ali...
210
  
5b6c317a   Pavel Govyadinov   implemented the c...
211
  		///constructor to create a cylinder from a set of points, radii, and the number of sides for the cylinder.
7d3162a2   Pavel Govyadinov   fixed majority of...
212
  		///@param inP:  Vector of stim vec3 composing the points of the centerline.
5b6c317a   Pavel Govyadinov   implemented the c...
213
  		///@param inM:  Vector of stim vecs composing the radii of the centerline.
0311ab81   Pavel Govyadinov   fixed some issues...
214
215
216
  		cylinder(std::vector<stim::vec3<T> > inP, std::vector<stim::vec<T> > inM)
  			: centerline<T>(inP)
  		{
5b6c317a   Pavel Govyadinov   implemented the c...
217
218
219
  			init(inP, inM);
  		}
  
09049866   Pavel Govyadinov   fixed a drawing b...
220
221
222
223
224
225
226
  		///constructor to create a cylinder from a set of points, radii, and the number of sides for the cylinder.
  		///@param inP:  Vector of stim vec3 composing the points of the centerline.
  		///@param inM:  Vector of stim vecs composing the radii of the centerline.
  		cylinder(std::vector<stim::vec3<T> > inP, std::vector< T > inM)
  			: centerline<T>(inP)
  		{
  			std::vector<stim::vec<T> > temp;
a36c3850   Pavel Govyadinov   fixed the bug tha...
227
  			stim::vec<T> zero(0.0,0.0);
09049866   Pavel Govyadinov   fixed a drawing b...
228
  			temp.resize(inM.size(), zero);
47fe6300   Pavel Govyadinov   fixed an accident...
229
230
  			for(int i = 0; i < inM.size(); i++)
  				temp[i][0] = inM[i];
09049866   Pavel Govyadinov   fixed a drawing b...
231
232
233
  			init(inP, temp);
  		}
  
7d3162a2   Pavel Govyadinov   fixed majority of...
234
  
58ee2b21   David Mayerich   incorporated stim...
235
  		///Constructor defines a cylinder with centerline inP and magnitudes of zero
7d3162a2   Pavel Govyadinov   fixed majority of...
236
  		///@param inP: Vector of stim vec3 composing the points of the centerline
0311ab81   Pavel Govyadinov   fixed some issues...
237
238
239
  		cylinder(std::vector< stim::vec3<T> > inP)
  			: centerline<T>(inP)
  		{
96e8ab1f   David Mayerich   fixed stim::cylin...
240
  			std::vector< stim::vec<T> > inM;						//create an array of arbitrary magnitudes
9c97e126   David Mayerich   added an axis-ali...
241
242
243
244
245
  
  			stim::vec<T> zero;
  			zero.push_back(0);
  
  			inM.resize(inP.size(), zero);								//initialize the magnitude values to zero
58ee2b21   David Mayerich   incorporated stim...
246
247
248
  			init(inP, inM);
  		}
  
58ee2b21   David Mayerich   incorporated stim...
249
250
251
  		///Returns the number of points on the cylinder centerline
  
  		unsigned int size(){
0311ab81   Pavel Govyadinov   fixed some issues...
252
  			return N;
58ee2b21   David Mayerich   incorporated stim...
253
254
  		}
  
10654a1f   Pavel Govyadinov   added the necessa...
255
256
  
  		///Returns a position vector at the given p-value (p value ranges from 0 to 1).
8495a970   Pavel Govyadinov   added comments to...
257
258
  		///interpolates the position along the line.
  		///@param pvalue: the location of the in the cylinder, from 0 (beginning to 1).
308a743c   David Mayerich   fixed class compa...
259
  		stim::vec3<T>
26aee9ed   Pavel Govyadinov   changed circle cl...
260
261
  		p(T pvalue)
  		{
bf23ee36   Pavel Govyadinov   more minor bug fi...
262
  			if(pvalue < 0.0 || pvalue > 1.0)
26aee9ed   Pavel Govyadinov   changed circle cl...
263
  			{
308a743c   David Mayerich   fixed class compa...
264
  				return stim::vec3<float>(-1,-1,-1);
26aee9ed   Pavel Govyadinov   changed circle cl...
265
  			}
10654a1f   Pavel Govyadinov   added the necessa...
266
267
  			T l = pvalue*L[L.size()-1];
  			int idx = findIdx(l);
0311ab81   Pavel Govyadinov   fixed some issues...
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
  			return (p(l,idx));
  /*				T rat = (l-L[idx])/(L[idx+1]-L[idx]);
  				stim::vec3<T> v1(
  						c[idx][0],	
  						c[idx][1],	
  						c[idx][2]
  						);	
  						
  				stim::vec3<T> v2(
  						c[idx+1][0],	
  						c[idx+1][1],	
  						c[idx+1][2]
  						);
  
  //			return(	e[idx].P + (e[idx+1].P-e[idx].P)*rat);
  			return( v1 + (v2 - v1)*rat);
  */		}
10654a1f   Pavel Govyadinov   added the necessa...
285
  
8495a970   Pavel Govyadinov   added comments to...
286
287
288
289
  		///Returns a position vector at the given length into the fiber (based on the pvalue).
  		///Interpolates the radius along the line.
  		///@param l: the location of the in the cylinder.
  		///@param idx: integer location of the point closest to l but prior to it.
308a743c   David Mayerich   fixed class compa...
290
  		stim::vec3<T>
26aee9ed   Pavel Govyadinov   changed circle cl...
291
292
293
  		p(T l, int idx)
  		{
  				T rat = (l-L[idx])/(L[idx+1]-L[idx]);
0311ab81   Pavel Govyadinov   fixed some issues...
294
295
296
297
298
299
300
301
302
303
304
305
306
  				stim::vec3<T> v1(
  						c[idx][0],	
  						c[idx][1],	
  						c[idx][2]
  						);	
  						
  				stim::vec3<T> v2(
  						c[idx+1][0],	
  						c[idx+1][1],	
  						c[idx+1][2]
  						);
  //			return(	e[idx].P + (e[idx+1].P-e[idx].P)*rat);
  			return(	v1 + (v2-v1)*rat);
26aee9ed   Pavel Govyadinov   changed circle cl...
307
308
  //			return(
  //			return (pos[idx] + (pos[idx+1]-pos[idx])*((l-L[idx])/(L[idx+1]- L[idx])));
10654a1f   Pavel Govyadinov   added the necessa...
309
310
311
  		}
  
  		///Returns a radius at the given p-value (p value ranges from 0 to 1).
8495a970   Pavel Govyadinov   added comments to...
312
313
  		///interpolates the radius along the line.
  		///@param pvalue: the location of the in the cylinder, from 0 (beginning to 1).
10654a1f   Pavel Govyadinov   added the necessa...
314
  		T
26aee9ed   Pavel Govyadinov   changed circle cl...
315
316
  		r(T pvalue)
  		{
98eecaa9   David Mayerich   VS and win32 updates
317
318
319
320
  			if(pvalue < 0.0 || pvalue > 1.0){
  				std::cerr<<"Error, value "<<pvalue<<" is outside of [0 1]."<<std::endl;
  				exit(1);
  			}
10654a1f   Pavel Govyadinov   added the necessa...
321
322
  			T l = pvalue*L[L.size()-1];
  			int idx = findIdx(l);
0311ab81   Pavel Govyadinov   fixed some issues...
323
324
325
326
327
  			return (r(l,idx));
  /*			T rat = (l-L[idx])/(L[idx+1]-L[idx]);
  //			return (mags[idx][0] + (mags[idx+1][0]-mags[idx][0])*rat);
  			return (e[idx].U.len() + (e[idx+1].U.len() - e[idx].U.len())*rat);
  */		}
10654a1f   Pavel Govyadinov   added the necessa...
328
  
8495a970   Pavel Govyadinov   added comments to...
329
330
331
332
  		///Returns a radius at the given length into the fiber (based on the pvalue).
  		///Interpolates the position along the line.
  		///@param l: the location of the in the cylinder.
  		///@param idx: integer location of the point closest to l but prior to it.
10654a1f   Pavel Govyadinov   added the necessa...
333
  		T
26aee9ed   Pavel Govyadinov   changed circle cl...
334
335
336
  		r(T l, int idx)
  		{
  				T rat = (l-L[idx])/(L[idx+1]-L[idx]);
0311ab81   Pavel Govyadinov   fixed some issues...
337
338
339
340
341
342
343
344
  			T v1 = (e[idx].U.len() + (e[idx+1].U.len() - e[idx].U.len())*rat);
  			T v3 = (Us[idx].len() + (Us[idx+1].len() - Us[idx].len())*rat);
  			T v2 = (mags[idx][0] + (mags[idx+1][0]-mags[idx][0])*rat);
  //			std::cout << (float)v1 = (float) v2 << std::endl;
  			if(abs(v3 - v1) >= 10e-6)
  			{
  				std::cout << "-------------------------" << std::endl;
  				std::cout << e[idx].str() << std::endl << std::endl;
b50c840e   David Mayerich   eliminated ANN fr...
345
  				std::cout << Us[idx].str() << std::endl;
0311ab81   Pavel Govyadinov   fixed some issues...
346
347
348
349
350
  				std::cout << (float)v1 - (float) v2 << std::endl;
  				std::cout << "failed" << std::endl;
  			}
  //			std::cout << e[idx].U.len() << " " << mags[idx][0] << std::endl;
  //			std::cout << v2 << std::endl;
24dee661   Pavel Govyadinov   finished the debu...
351
  			return(v2);
0311ab81   Pavel Govyadinov   fixed some issues...
352
353
  //			return (mags[idx][0] + (mags[idx+1][0]-mags[idx][0])*rat);
  	//	(
66fe63f3   Pavel Govyadinov   fixed minor typo
354
  		}
10654a1f   Pavel Govyadinov   added the necessa...
355
  
9c97e126   David Mayerich   added an axis-ali...
356
357
358
359
360
361
362
363
364
365
  		///	Returns the magnitude at the given index
  		///	@param i is the index of the desired point
  		/// @param m is the index of the magnitude value
  		T ri(unsigned i, unsigned m = 0){
  			return mags[i][m];
  		}
  
  		/// Adds a new magnitude value to all points
  		/// @param m is the starting value for the new magnitude
  		void add_mag(T m = 0){
0311ab81   Pavel Govyadinov   fixed some issues...
366
  			for(unsigned int p = 0; p < N; p++)
9c97e126   David Mayerich   added an axis-ali...
367
368
369
370
371
372
373
374
375
376
377
  				mags[p].push_back(m);
  		}
  
  		/// Sets a magnitude value
  		/// @param val is the new value for the magnitude
  		/// @param p is the point index for the magnitude to be set
  		/// @param m is the index for the magnitude
  		void set_mag(T val, unsigned p, unsigned m = 0){
  			mags[p][m] = val;
  		}
  
b3a38641   David Mayerich   added the ability...
378
379
380
381
382
  		/// Returns the number of magnitude values at each point
  		unsigned nmags(){
  			return mags[0].size();
  		}
  
10654a1f   Pavel Govyadinov   added the necessa...
383
  		///returns the position of the point with a given pvalue and theta on the surface
8495a970   Pavel Govyadinov   added comments to...
384
385
386
  		///in x, y, z coordinates. Theta is in degrees from 0 to 360.
  		///@param pvalue: the location of the in the cylinder, from 0 (beginning to 1).
  		///@param theta: the angle to the point of a circle.
308a743c   David Mayerich   fixed class compa...
387
  		stim::vec3<T>
10654a1f   Pavel Govyadinov   added the necessa...
388
389
  		surf(T pvalue, T theta)
  		{
bf23ee36   Pavel Govyadinov   more minor bug fi...
390
  			if(pvalue < 0.0 || pvalue > 1.0)
26aee9ed   Pavel Govyadinov   changed circle cl...
391
  			{
308a743c   David Mayerich   fixed class compa...
392
  				return stim::vec3<float>(-1,-1,-1);
26aee9ed   Pavel Govyadinov   changed circle cl...
393
  			} else {
10654a1f   Pavel Govyadinov   added the necessa...
394
395
  			T l = pvalue*L[L.size()-1];
  			int idx = findIdx(l);
308a743c   David Mayerich   fixed class compa...
396
  			stim::vec3<T> ps = p(l, idx); 
10654a1f   Pavel Govyadinov   added the necessa...
397
  			T m = r(l, idx);
8c4f5d84   Pavel Govyadinov   fixed the issue w...
398
399
400
401
  			s = e[idx];
  			s.center(ps);
  			s.normal(d(l, idx));
  			s.scale(m/e[idx].U.len());
10654a1f   Pavel Govyadinov   added the necessa...
402
  			return(s.p(theta));
26aee9ed   Pavel Govyadinov   changed circle cl...
403
  			}
10654a1f   Pavel Govyadinov   added the necessa...
404
405
  		}
  
8495a970   Pavel Govyadinov   added comments to...
406
  		///returns a vector of points necessary to create a circle at every position in the fiber.
26aee9ed   Pavel Govyadinov   changed circle cl...
407
  		///@param sides: the number of sides of each circle.	
308a743c   David Mayerich   fixed class compa...
408
  		std::vector<std::vector<vec3<T> > >
5b6c317a   Pavel Govyadinov   implemented the c...
409
410
  		getPoints(int sides)
  		{
308a743c   David Mayerich   fixed class compa...
411
  			std::vector<std::vector <vec3<T> > > points;
0311ab81   Pavel Govyadinov   fixed some issues...
412
413
  			points.resize(N);
  			for(int i = 0; i < N; i++)
5b6c317a   Pavel Govyadinov   implemented the c...
414
  			{
8c4f5d84   Pavel Govyadinov   fixed the issue w...
415
  				points[i] = e[i].getPoints(sides);
5b6c317a   Pavel Govyadinov   implemented the c...
416
  			}
8c4f5d84   Pavel Govyadinov   fixed the issue w...
417
  			return points;
5b6c317a   Pavel Govyadinov   implemented the c...
418
  		}
58ee2b21   David Mayerich   incorporated stim...
419
  
8c4f5d84   Pavel Govyadinov   fixed the issue w...
420
421
422
423
424
425
  		///returns the total length of the line at index j.
  		T
  		getl(int j)
  		{
  			return (L[j]);
  		}
58ee2b21   David Mayerich   incorporated stim...
426
427
  		/// Allows a point on the centerline to be accessed using bracket notation
  
308a743c   David Mayerich   fixed class compa...
428
  		vec3<T> operator[](unsigned int i){
3e5d3ad3   Pavel Govyadinov   merged the change...
429
  			return e[i].P;
58ee2b21   David Mayerich   incorporated stim...
430
431
432
433
434
435
436
  		}
  
  		/// Returns the total length of the cylinder centerline
  		T length(){
  			return L.back();
  		}
  
9c97e126   David Mayerich   added an axis-ali...
437
438
439
440
441
442
443
  		/// Integrates a magnitude value along the cylinder.
  		/// @param m is the magnitude value to be integrated (this is usually the radius)
  		T integrate(unsigned m = 0){
  
  			T M = 0;						//initialize the integral to zero
  			T m0, m1;						//allocate space for both magnitudes in a single segment
  
308a743c   David Mayerich   fixed class compa...
444
  			//vec3<T> p0, p1;					//allocate space for both points in a single segment
9c97e126   David Mayerich   added an axis-ali...
445
446
447
448
449
450
451
  
  			m0 = mags[0][m];				//initialize the first point and magnitude to the first point in the cylinder
  			//p0 = pos[0];
  
  			T len = L[0];						//allocate space for the segment length
  
  			//for every consecutive point in the cylinder
0311ab81   Pavel Govyadinov   fixed some issues...
452
  			for(unsigned p = 1; p < N; p++){
9c97e126   David Mayerich   added an axis-ali...
453
454
455
456
457
458
459
  
  				//p1 = pos[p];							//get the position and magnitude for the next point
  				m1 = mags[p][m];
  
  				if(p > 1) len = (L[p-1] - L[p-2]);		//calculate the segment length using the L array
  
  				//add the average magnitude, weighted by the segment length
308a743c   David Mayerich   fixed class compa...
460
  				M += (m0 + m1)/(T)2.0 * len;
9c97e126   David Mayerich   added an axis-ali...
461
462
463
464
465
466
467
468
469
470
471
472
473
474
  
  				m0 = m1;								//move to the next segment by shifting points
  			}
  			return M;			//return the integral
  		}
  
  		/// Averages a magnitude value across the cylinder
  		/// @param m is the magnitude value to be averaged (this is usually the radius)
  		T average(unsigned m = 0){			
  
  			//return the average magnitude
  			return integrate(m) / L.back();
  		}
  
58ee2b21   David Mayerich   incorporated stim...
475
476
477
478
479
  		/// Resamples the cylinder to provide a maximum distance of "spacing" between centerline points. All current
  		///		centerline points are guaranteed to exist in the new cylinder
  		/// @param spacing is the maximum spacing allowed between sample points
  		cylinder<T> resample(T spacing){
  
308a743c   David Mayerich   fixed class compa...
480
  			std::vector< vec3<T> > result;
9c97e126   David Mayerich   added an axis-ali...
481
  
1b2858a2   David Mayerich   fixed some commen...
482
  			vec3<T> p0 = e[0].P;									//initialize p0 to the first point on the centerline
308a743c   David Mayerich   fixed class compa...
483
  			vec3<T> p1;
1b2858a2   David Mayerich   fixed some commen...
484
  			unsigned N = size();									//number of points in the current centerline
58ee2b21   David Mayerich   incorporated stim...
485
486
487
  
  			//for each line segment on the centerline
  			for(unsigned int i = 1; i < N; i++){
1b2858a2   David Mayerich   fixed some commen...
488
  				p1 = e[i].P;										//get the second point in the line segment
58ee2b21   David Mayerich   incorporated stim...
489
  
1b2858a2   David Mayerich   fixed some commen...
490
491
  				vec3<T> v = p1 - p0;								//calculate the vector between these two points
  				T d = v.len();										//calculate the distance between these two points (length of the line segment)
58ee2b21   David Mayerich   incorporated stim...
492
  
308a743c   David Mayerich   fixed class compa...
493
  				size_t nsteps = (size_t)std::ceil(d / spacing);		//calculate the number of steps to take along the segment to meet the spacing criteria
1b2858a2   David Mayerich   fixed some commen...
494
  				T stepsize = (T)1.0 / nsteps;						//calculate the parametric step size between new centerline points
58ee2b21   David Mayerich   incorporated stim...
495
496
497
  
  				//for each step along the line segment
  				for(unsigned s = 0; s < nsteps; s++){
1b2858a2   David Mayerich   fixed some commen...
498
499
  					T alpha = stepsize * s;							//calculate the fraction of the distance along the line segment covered
  					result.push_back(p0 + alpha * v);				//push the point at alpha position along the line segment
58ee2b21   David Mayerich   incorporated stim...
500
501
  				}
  
1b2858a2   David Mayerich   fixed some commen...
502
  				p0 = p1;											//shift the points to move to the next line segment
58ee2b21   David Mayerich   incorporated stim...
503
504
  			}
  
1b2858a2   David Mayerich   fixed some commen...
505
  			result.push_back(e[size() - 1].P);						//push the last point in the centerline
9c97e126   David Mayerich   added an axis-ali...
506
  
58ee2b21   David Mayerich   incorporated stim...
507
508
509
  			return cylinder<T>(result);
  
  		}
9c97e126   David Mayerich   added an axis-ali...
510
  
26aee9ed   Pavel Govyadinov   changed circle cl...
511
  		
5b6c317a   Pavel Govyadinov   implemented the c...
512
513
514
515
  };
  
  }
  #endif