Blame view

stim/visualization/cylinder.h 6.29 KB
26aee9ed   Pavel Govyadinov   changed circle cl...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  #ifndef STIM_CYLINDER_H
  #define STIM_CYLINDER_H
  #include <iostream>
  #include <stim/math/circle.h>
  #include <stim/math/vector.h>
  
  
  namespace stim
  {
  template<typename T>
  class cylinder
  {
  	private:
  		stim::circle<T> s;			//an arbitrary circle
8c4f5d84   Pavel Govyadinov   fixed the issue w...
15
  		std::vector<stim::circle<T> > e;
26aee9ed   Pavel Govyadinov   changed circle cl...
16
17
18
19
20
21
22
23
24
25
26
27
28
  		std::vector< T > L;			//length of the cylinder at each position.
  	
  		///default init	
  		void
  		init()
  		{
  
  		}
  
  		///inits the cylinder from a list of points (inP) and radii (inM)
  		void
  		init(std::vector<stim::vec<T> > inP, std::vector<stim::vec<T> > inM)
  		{
8c4f5d84   Pavel Govyadinov   fixed the issue w...
29
30
31
32
33
34
35
  //			pos = inP;
  //			mags = inM;
  			stim::vec<float> v1;
  			stim::vec<float> v2;
  			e.resize(inP.size());
  			if(inP.size() < 2)
  				return;
26aee9ed   Pavel Govyadinov   changed circle cl...
36
37
  
  			//calculate each L.
8c4f5d84   Pavel Govyadinov   fixed the issue w...
38
  			L.resize(inP.size());
26aee9ed   Pavel Govyadinov   changed circle cl...
39
40
41
42
  			T temp = (T)0;
  			L[0] = 0;
  			for(int i = 1; i < L.size(); i++)
  			{
8c4f5d84   Pavel Govyadinov   fixed the issue w...
43
  				temp += (inP[i-1] - inP[i]).len();
26aee9ed   Pavel Govyadinov   changed circle cl...
44
45
  				L[i] = temp;
  			}
8c4f5d84   Pavel Govyadinov   fixed the issue w...
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
  
  			stim::vec<T> dr = (inP[1] - inP[0]).norm();
  			s = stim::circle<T>(inP[0], inM[0][0], dr, stim::vec<T>(1,0,0));
  			e[0] = s;
  			for(int i = 1; i < inP.size()-1; i++)
  			{
  				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);
  				s.scale(inM[i][0]/inM[i-1][0]);
  				e[i] = s;
  			}
  			
  			int j = inP.size()-1;
  			s.center(inP[j]);
  			dr = (inP[j] - inP[j-1]).norm();
  			s.normal(dr);
  			s.scale(inM[j][0]/inM[j-1][0]);
  			e[j] = s;
26aee9ed   Pavel Govyadinov   changed circle cl...
67
68
69
70
71
72
73
74
  		}
  		
  		///returns the direction vector at point idx.
  		stim::vec<T>
  		d(int idx)
  		{
  			if(idx == 0)
  			{
8c4f5d84   Pavel Govyadinov   fixed the issue w...
75
  				return (e[idx+1].P - e[idx].P).norm();
26aee9ed   Pavel Govyadinov   changed circle cl...
76
  			}
8c4f5d84   Pavel Govyadinov   fixed the issue w...
77
  			else if(idx == e.size()-1)
26aee9ed   Pavel Govyadinov   changed circle cl...
78
  			{
8c4f5d84   Pavel Govyadinov   fixed the issue w...
79
  				return (e[idx].P - e[idx-1].P).norm();
26aee9ed   Pavel Govyadinov   changed circle cl...
80
81
82
  			}
  			else
  			{
8c4f5d84   Pavel Govyadinov   fixed the issue w...
83
84
85
  //				return (e[idx+1].P - e[idx].P).norm();
  				stim::vec<float> v1 = (e[idx].P-e[idx-1].P).norm();
  				stim::vec<float> v2 = (e[idx+1].P-e[idx].P).norm();
26aee9ed   Pavel Govyadinov   changed circle cl...
86
  				return (v1+v2).norm();			
8c4f5d84   Pavel Govyadinov   fixed the issue w...
87
88
89
  			} 
  	//		return e[idx].N;	
  
26aee9ed   Pavel Govyadinov   changed circle cl...
90
91
  		}
  
8c4f5d84   Pavel Govyadinov   fixed the issue w...
92
93
  		stim::vec<T>
  		d(T l, int idx)
26aee9ed   Pavel Govyadinov   changed circle cl...
94
  		{
8c4f5d84   Pavel Govyadinov   fixed the issue w...
95
  			if(idx == 0 || idx == e.size()-1)
26aee9ed   Pavel Govyadinov   changed circle cl...
96
  			{
8c4f5d84   Pavel Govyadinov   fixed the issue w...
97
  				return e[idx].N;
26aee9ed   Pavel Govyadinov   changed circle cl...
98
  			}
8c4f5d84   Pavel Govyadinov   fixed the issue w...
99
100
101
102
103
  			else
  			{
  				T rat = (l-L[idx])/(L[idx+1]-L[idx]);
  				return(	e[idx].N + (e[idx+1].N - e[idx].N)*rat);
  			} 
26aee9ed   Pavel Govyadinov   changed circle cl...
104
105
  		}
  
8c4f5d84   Pavel Govyadinov   fixed the issue w...
106
  
26aee9ed   Pavel Govyadinov   changed circle cl...
107
108
109
110
111
112
113
114
  		///finds the index of the point closest to the length l on the lower bound.
  		///binary search.
  		int
  		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...
115
116
  			while(i > 0 && i < L.size()-1)
  			{
8c4f5d84   Pavel Govyadinov   fixed the issue w...
117
118
  //				std::cerr << "Trying " << i << std::endl;
  //				std::cerr << "l is " << l << ", L[" << i << "]" << L[i] << std::endl;
26aee9ed   Pavel Govyadinov   changed circle cl...
119
120
121
  				if(l < L[i])
  				{
  					max = i;
26aee9ed   Pavel Govyadinov   changed circle cl...
122
123
124
125
  					i = min+(max-min)/2;
  				}
  				else if(L[i] <= l && L[i+1] >= l)
  				{
26aee9ed   Pavel Govyadinov   changed circle cl...
126
127
128
129
130
  					break;
  				}
  				else
  				{
  					min = i;
26aee9ed   Pavel Govyadinov   changed circle cl...
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
  					i = min+(max-min)/2;
  				}
  			}
  			return i;
  		}
  
  	public:
  		///default constructor
  		cylinder()
  		{
  
  		}
  
  		///constructor to create a cylinder from a set of points, radii, and the number of sides for the cylinder.
  		///@param inP:  Vector of stim vecs composing the points of the centerline.
  		///@param inM:  Vector of stim vecs composing the radii of the centerline.
  		cylinder(std::vector<stim::vec<T> > inP, std::vector<stim::vec<T> > inM)
  		{
  			init(inP, inM);
  		}
  
  
  		///Returns a position vector at the given p-value (p value ranges from 0 to 1).
  		///interpolates the position along the line.
  		///@param pvalue: the location of the in the cylinder, from 0 (beginning to 1).
  		stim::vec<T>
  		p(T pvalue)
  		{
  			if(pvalue < 0.0 || pvalue > 1.0)
  			{
  				return stim::vec<float>(-1,-1,-1);
  			}
  			T l = pvalue*L[L.size()-1];
  			int idx = findIdx(l);
  				T rat = (l-L[idx])/(L[idx+1]-L[idx]);
8c4f5d84   Pavel Govyadinov   fixed the issue w...
166
  			return(	e[idx].P + (e[idx+1].P-e[idx].P)*rat);
26aee9ed   Pavel Govyadinov   changed circle cl...
167
168
169
170
171
172
173
174
175
176
  		}
  
  		///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.
  		stim::vec<T>
  		p(T l, int idx)
  		{
  				T rat = (l-L[idx])/(L[idx+1]-L[idx]);
8c4f5d84   Pavel Govyadinov   fixed the issue w...
177
  			return(	e[idx].P + (e[idx+1].P-e[idx].P)*rat);
26aee9ed   Pavel Govyadinov   changed circle cl...
178
179
180
181
182
183
184
185
186
187
188
189
190
191
  //			return(
  //			return (pos[idx] + (pos[idx+1]-pos[idx])*((l-L[idx])/(L[idx+1]- L[idx])));
  		}
  
  		///Returns a radius at the given p-value (p value ranges from 0 to 1).
  		///interpolates the radius along the line.
  		///@param pvalue: the location of the in the cylinder, from 0 (beginning to 1).
  		T
  		r(T pvalue)
  		{
  			if(pvalue < 0.0 || pvalue > 1.0)
  				return;
  			T l = pvalue*L[L.size()-1];
  			int idx = findIdx(l);
8c4f5d84   Pavel Govyadinov   fixed the issue w...
192
  			return (e[idx].U.len() + (e[idx+1].U.len() - e[idx].U.len())*((l-L[idx])/(L[idx+1]- L[idx])));
26aee9ed   Pavel Govyadinov   changed circle cl...
193
194
195
196
197
198
199
200
201
202
  		}
  
  		///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.
  		T
  		r(T l, int idx)
  		{
  				T rat = (l-L[idx])/(L[idx+1]-L[idx]);
8c4f5d84   Pavel Govyadinov   fixed the issue w...
203
  			return(	e[idx].U.len() + (e[idx+1].U.len() - e[idx].U.len())*rat);
26aee9ed   Pavel Govyadinov   changed circle cl...
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
  //			return (mags[idx] + (mags[idx+1]-mags[idx])*((l-L[idx])/(L[idx+1]- L[idx])))[0];
  		}
  
  
  		///returns the position of the point with a given pvalue and theta on the surface
  		///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.
  		stim::vec<T>
  		surf(T pvalue, T theta)
  		{
  			if(pvalue < 0.0 || pvalue > 1.0)
  			{
  				return stim::vec<float>(-1,-1,-1);
  			} else {
  //			std::cout << "AAAAAAAAAAAAAAAAAAAAAAA             " << pvalue*L[L.size()-1] << " " << L[L.size()-1] << std::endl;
  			T l = pvalue*L[L.size()-1];
  //			std::cerr << "The l value is: " << l << std::endl;
  			int idx = findIdx(l);
  //			std::cerr << "Index: " << idx << std::endl;
  			stim::vec<T> ps = p(l, idx); 
  			T m = r(l, idx);
8c4f5d84   Pavel Govyadinov   fixed the issue w...
226
227
228
229
  			s = e[idx];
  			s.center(ps);
  			s.normal(d(l, idx));
  			s.scale(m/e[idx].U.len());
26aee9ed   Pavel Govyadinov   changed circle cl...
230
231
232
233
234
235
236
237
238
  			return(s.p(theta));
  			}
  		}
  
  		///returns a vector of points necessary to create a circle at every position in the fiber.
  		///@param sides: the number of sides of each circle.	
  		std::vector<std::vector<vec<T> > >
  		getPoints(int sides)
  		{
8c4f5d84   Pavel Govyadinov   fixed the issue w...
239
240
241
  			std::vector<std::vector <vec<T> > > points;
  			points.resize(e.size());
  			for(int i = 0; i < e.size(); i++)
26aee9ed   Pavel Govyadinov   changed circle cl...
242
  			{
8c4f5d84   Pavel Govyadinov   fixed the issue w...
243
  				points[i] = e[i].getPoints(sides);
26aee9ed   Pavel Govyadinov   changed circle cl...
244
  			}
8c4f5d84   Pavel Govyadinov   fixed the issue w...
245
  			return points;
26aee9ed   Pavel Govyadinov   changed circle cl...
246
247
248
249
250
251
252
  		}
  
  		void
  		print(int idx)
  		{
  			std::cout << d(idx) << std::endl;
  		}
8c4f5d84   Pavel Govyadinov   fixed the issue w...
253
254
255
256
257
258
259
  
  		///returns the total length of the line at index j.
  		T
  		getl(int j)
  		{
  			return (L[j]);
  		}
26aee9ed   Pavel Govyadinov   changed circle cl...
260
261
262
263
264
  		
  };
  
  }
  #endif