Blame view

stim/visualization/cylinder.h 4.73 KB
5b6c317a   Pavel Govyadinov   implemented the c...
1
2
3
4
5
6
7
8
9
10
11
12
13
  #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:
8495a970   Pavel Govyadinov   added comments to...
14
15
16
17
  		stim::circle<T> s;			//an arbitrary circle
  		std::vector< stim::vec<T> > pos;	//positions of the cylinder.
  		std::vector< stim::vec<T> > mags;	//radii at each position
  		std::vector< T > L;			//length of the cylinder at each position.
5b6c317a   Pavel Govyadinov   implemented the c...
18
  	
8495a970   Pavel Govyadinov   added comments to...
19
  		///default init	
5b6c317a   Pavel Govyadinov   implemented the c...
20
21
22
  		void
  		init()
  		{
10654a1f   Pavel Govyadinov   added the necessa...
23
  
5b6c317a   Pavel Govyadinov   implemented the c...
24
25
  		}
  
8495a970   Pavel Govyadinov   added comments to...
26
  		///inits the cylinder from a list of points (inP) and radii (inM)
5b6c317a   Pavel Govyadinov   implemented the c...
27
  		void
10654a1f   Pavel Govyadinov   added the necessa...
28
  		init(std::vector<stim::vec<T> > inP, std::vector<stim::vec<T> > inM)
5b6c317a   Pavel Govyadinov   implemented the c...
29
30
31
  		{
  			pos = inP;
  			mags = inM;
8495a970   Pavel Govyadinov   added comments to...
32
33
  
  			//calculate each L.
10654a1f   Pavel Govyadinov   added the necessa...
34
  			L.resize(pos.size()-1);
bf23ee36   Pavel Govyadinov   more minor bug fi...
35
36
  			T temp = (T)0;
  			for(int i = 0; i < L.size()-1; i++)
10654a1f   Pavel Govyadinov   added the necessa...
37
  			{
bf23ee36   Pavel Govyadinov   more minor bug fi...
38
39
  				temp += (pos[i] - pos[i+1]).len();
  				L[i] = temp;
10654a1f   Pavel Govyadinov   added the necessa...
40
  			}
5b6c317a   Pavel Govyadinov   implemented the c...
41
42
  		}
  		
8495a970   Pavel Govyadinov   added comments to...
43
  		///returns the direction vector at point idx.
10654a1f   Pavel Govyadinov   added the necessa...
44
45
46
47
48
49
50
  		stim::vec<T>
  		d(int idx)
  		{
  			return (pos[idx] - pos[idx+1]).norm();
  			
  		}
  
8495a970   Pavel Govyadinov   added comments to...
51
  		///returns the total length of the line at index j.
10654a1f   Pavel Govyadinov   added the necessa...
52
53
54
55
56
  		T
  		getl(int j)
  		{
  			for(int i = 0; i < j-1; ++i)
  			{
bf23ee36   Pavel Govyadinov   more minor bug fi...
57
58
  				temp += (pos[i] - pos[i+1]).len();
  				L[i] = temp;
10654a1f   Pavel Govyadinov   added the necessa...
59
60
61
  			}
  		}
  
8495a970   Pavel Govyadinov   added comments to...
62
63
  		///finds the index of the point closest to the length l on the lower bound.
  		///binary search.
10654a1f   Pavel Govyadinov   added the necessa...
64
65
66
67
  		int
  		findIdx(T l)
  		{
  			int i = pos.size()/2;
bf23ee36   Pavel Govyadinov   more minor bug fi...
68
  			while(i > 0 && i < pos.size())
10654a1f   Pavel Govyadinov   added the necessa...
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
  			{
  				if(L[i] < l)
  				{
  					i = i/2;
  				}
  				else if(L[i] < l && L[i+1] > l)
  				{
  					break;
  				}
  				else
  				{
  					i = i+i/2;
  				}
  			}
  			return i;
  		}
5b6c317a   Pavel Govyadinov   implemented the c...
85
86
  
  	public:
8495a970   Pavel Govyadinov   added comments to...
87
  		///default constructor
5b6c317a   Pavel Govyadinov   implemented the c...
88
89
90
91
92
93
  		cylinder()
  		{
  
  		}
  
  		///constructor to create a cylinder from a set of points, radii, and the number of sides for the cylinder.
5b6c317a   Pavel Govyadinov   implemented the c...
94
95
  		///@param inP:  Vector of stim vecs composing the points of the centerline.
  		///@param inM:  Vector of stim vecs composing the radii of the centerline.
10654a1f   Pavel Govyadinov   added the necessa...
96
  		cylinder(std::vector<stim::vec<T> > inP, std::vector<stim::vec<T> > inM)
5b6c317a   Pavel Govyadinov   implemented the c...
97
98
99
100
  		{
  			init(inP, inM);
  		}
  
10654a1f   Pavel Govyadinov   added the necessa...
101
102
  
  		///Returns a position vector at the given p-value (p value ranges from 0 to 1).
8495a970   Pavel Govyadinov   added comments to...
103
104
  		///interpolates the position along the line.
  		///@param pvalue: the location of the in the cylinder, from 0 (beginning to 1).
10654a1f   Pavel Govyadinov   added the necessa...
105
106
107
  		stim::vec<T>
  		p(T pvalue)
  		{
bf23ee36   Pavel Govyadinov   more minor bug fi...
108
109
  			if(pvalue < 0.0 || pvalue > 1.0)
  				return;
10654a1f   Pavel Govyadinov   added the necessa...
110
111
  			T l = pvalue*L[L.size()-1];
  			int idx = findIdx(l);
66fe63f3   Pavel Govyadinov   fixed minor typo
112
  			return (pos[idx] + (pos[idx+1]-pos[idx])*((l-L[idx])/(L[idx+1]- L[idx])));
10654a1f   Pavel Govyadinov   added the necessa...
113
114
  		}
  
8495a970   Pavel Govyadinov   added comments to...
115
116
117
118
  		///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.
10654a1f   Pavel Govyadinov   added the necessa...
119
120
121
  		stim::vec<T>
  		p(T l, int idx)
  		{
66fe63f3   Pavel Govyadinov   fixed minor typo
122
  			return (pos[idx] + (pos[idx+1]-pos[idx])*((l-L[idx])/(L[idx+1]- L[idx])));
10654a1f   Pavel Govyadinov   added the necessa...
123
124
125
  		}
  
  		///Returns a radius at the given p-value (p value ranges from 0 to 1).
8495a970   Pavel Govyadinov   added comments to...
126
127
  		///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...
128
129
130
  		T
  		r(T pvalue)
  		{
bf23ee36   Pavel Govyadinov   more minor bug fi...
131
132
  			if(pvalue < 0.0 || pvalue > 1.0)
  				return;
10654a1f   Pavel Govyadinov   added the necessa...
133
134
  			T l = pvalue*L[L.size()-1];
  			int idx = findIdx(l);
66fe63f3   Pavel Govyadinov   fixed minor typo
135
136
  			return (mags[idx] + (mags[idx+1]-mags[idx])*((l-L[idx])/(L[idx+1]- L[idx])));
  		}
10654a1f   Pavel Govyadinov   added the necessa...
137
  
8495a970   Pavel Govyadinov   added comments to...
138
139
140
141
  		///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...
142
143
144
  		T
  		r(T l, int idx)
  		{
66fe63f3   Pavel Govyadinov   fixed minor typo
145
146
  			return (mags[idx] + (mags[idx+1]-mags[idx])*((l-L[idx])/(L[idx+1]- L[idx])));
  		}
10654a1f   Pavel Govyadinov   added the necessa...
147
148
149
  
  
  		///returns the position of the point with a given pvalue and theta on the surface
8495a970   Pavel Govyadinov   added comments to...
150
151
152
  		///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.
10654a1f   Pavel Govyadinov   added the necessa...
153
154
155
  		stim::vec<T>
  		surf(T pvalue, T theta)
  		{
bf23ee36   Pavel Govyadinov   more minor bug fi...
156
157
  			if(pvalue < 0.0 || pvalue > 1.0)
  				return;
10654a1f   Pavel Govyadinov   added the necessa...
158
159
160
161
162
163
164
165
166
  			T l = pvalue*L[L.size()-1];
  			int idx = findIdx(l);
  			stim::vec<T> ps = p(l, idx); 
  			T m = r(l, idx);
  			stim::vec<T> dr = d(idx);
  			s = stim::circle<T>(ps, m, dr);
  			return(s.p(theta));
  		}
  
8495a970   Pavel Govyadinov   added comments to...
167
168
  		///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.	
5b6c317a   Pavel Govyadinov   implemented the c...
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
  		std::vector<std::vector<vec<T> > >
  		getPoints(int sides)
  		{
  			if(pos.size() < 2)
  			{
  				return;
  			} else {
  				std::vector<std::vector <vec<T> > > points;
  				points.resize(pos.size());
  				stim::vec<T> d = (pos[0] - pos[1]).norm();
  				s = stim::circle<T>(pos[0], mags[0][0], d);
  				points[0] = s.getPoints(sides);
  				for(int i = 1; i < pos.size(); i++)
  				{
  					d = (pos[i] - pos[i-1]).norm();
  					s.center(pos[i]);
  					s.normal(d);
  					s.scale(mags[i][0]/mags[i-1][0], mags[i][0]/mags[i-1][0]);
  					points[i] = s.getPoints(sides);
  				}
  				return points;
  			}
  		}
  		
  };
  
  }
  #endif