ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/yangyong/ECALG4SIM/analysis/planes.cc
Revision: 1.1
Committed: Thu Apr 4 08:29:22 2013 UTC (12 years, 1 month ago) by yangyong
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Log Message:
*** empty log message ***

File Contents

# Content
1
2 //plane : ax + by + cz + d = 0;
3
4
5
6 // compute the plane equation from a set of 3 points.
7 // returns false if any of the points are co-incident and do not form a plane.
8 // A = point 1
9 // B = point 2
10 // C = point 3
11 // plane = destination for plane equation A,B,C,D
12 bool computePlane(const double A[],const double B[],const double C[],double plane[])
13 {
14 bool ret = false;
15
16 double vx = (B[0] - C[0]);
17 double vy = (B[1] - C[1]);
18 double vz = (B[2] - C[2]);
19
20 double wx = (A[0] - B[0]);
21 double wy = (A[1] - B[1]);
22 double wz = (A[2] - B[2]);
23
24 double vw_x = vy * wz - vz * wy;
25 double vw_y = vz * wx - vx * wz;
26 double vw_z = vx * wy - vy * wx;
27
28 double mag = sqrtf((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z));
29
30 if ( mag > 0 )
31 {
32
33 mag = 1.0/mag; // compute the recipricol distance
34
35 ret = true;
36
37 plane[0] = vw_x * mag;
38 plane[1] = vw_y * mag;
39 plane[2] = vw_z * mag;
40 plane[3] = 0.0 - ((plane[0]*A[0])+(plane[1]*A[1])+(plane[2]*A[2]));
41
42 }
43 return ret;
44 }
45
46
47 // inertesect a line semgent with a plane, return false if they don't intersect.
48 // otherwise computes and returns the intesection point 'split'
49 // p1 = 3d point of the start of the line semgent.
50 // p2 = 3d point of the end of the line segment.
51 // split = address to store the intersection location x,y,z.
52 // plane = the plane equation as four doubles A,B,C,D.
53
54 bool intersectLinePlane(const double p1[],const double p2[],double split[],const double plane[])
55 {
56
57 double dp1 = p1[0]*plane[0] + p1[1]*plane[1] + p1[2]*plane[2] + plane[3];
58 double dp2 = p2[0]*plane[0] + p2[1]*plane[1] + p2[2]*plane[2] + plane[3];
59
60 if ( dp1 > 0 && dp2 > 0 ) return false;
61 if ( dp1 < 0 && dp2 < 0 ) return false;
62
63 double dir[3];
64
65 dir[0] = p2[0] - p1[0];
66 dir[1] = p2[1] - p1[1];
67 dir[2] = p2[2] - p1[2];
68
69 double dot1 = dir[0]*plane[0] + dir[1]*plane[1] + dir[2]*plane[2];
70 double dot2 = dp1 - plane[3];
71
72 double t = -(plane[3] + dot2 ) / dot1;
73
74 split[0] = (dir[0]*t)+p1[0];
75 split[1] = (dir[1]*t)+p1[1];
76 split[2] = (dir[2]*t)+p1[2];
77
78 return true;
79 }
80
81
82 bool intersectLinePlane_tolerance(const double p1[],const double p2[],double split[],const double plane[], double epsilon = 1E-4)
83 {
84
85 double dp1 = p1[0]*plane[0] + p1[1]*plane[1] + p1[2]*plane[2] + plane[3];
86 double dp2 = p2[0]*plane[0] + p2[1]*plane[1] + p2[2]*plane[2] + plane[3];
87
88 if( fabs(dp1)> epsilon && fabs(dp2) > epsilon){ //within the tolereance, that means point is on the plane
89
90 if ( dp1 > 0 && dp2 > 0 ) return false;
91 if ( dp1 < 0 && dp2 < 0 ) return false;
92
93 }
94
95
96 double dir[3];
97
98 dir[0] = p2[0] - p1[0];
99 dir[1] = p2[1] - p1[1];
100 dir[2] = p2[2] - p1[2];
101
102 double dot1 = dir[0]*plane[0] + dir[1]*plane[1] + dir[2]*plane[2];
103 double dot2 = dp1 - plane[3];
104
105 double t = -(plane[3] + dot2 ) / dot1;
106
107 split[0] = (dir[0]*t)+p1[0];
108 split[1] = (dir[1]*t)+p1[1];
109 split[2] = (dir[2]*t)+p1[2];
110
111 return true;
112 }
113
114
115
116 // compute the distance between a 3d point and a plane
117 double distToPlaneOLD(const double p[],const double plane[])
118 {
119 return p[0]*plane[0] + p[1]*plane[1] + p[2]*plane[2] + plane[3];
120 }
121
122
123
124 // compute the distance between a 3d point and a plane
125 double distToPlane(const double p[],const double plane[])
126 {
127 double dist = p[0]*plane[0] + p[1]*plane[1] + p[2]*plane[2] + plane[3];
128 return dist / sqrt( plane[0] * plane[0] + plane[1] * plane[1] + plane[2] * plane[2]);
129 }
130
131
132 double distTwoPoints(const double p1[],const double p2[]){
133
134 return sqrt( pow(p1[0]-p2[0],2) + pow(p1[1]-p2[1],2) + pow(p1[2]-p2[2],2) );
135
136 }
137
138
139 double check4PointsInAplane(double p1[],double p2[],double p3[],double p4[]){
140 double p[4];
141 computePlane(p1,p2,p3,p);
142 double y = p[0] * p4[0] + p[1] * p4[1] + p[2]*p4[2] + p[3];
143 return y;
144
145 }
146
147
148 int pnpoly(int nvert, double vertx[], double verty[], double testx, double testy){
149 int i, j, c = 0;
150 for (i = 0, j = nvert-1; i < nvert; j = i++) {
151 if ( ((verty[i]>testy) != (verty[j]>testy)) &&
152 (testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) )
153 c = !c;
154 }
155 return c;
156 }
157
158 // area2D_Polygon(): compute the area of a 2D polygon
159 // Input: int n = the number of vertices in the polygon
160 // Point* V = an array of n+2 vertices with V[n]=V[0]
161 // Return: the (float) area of the polygon
162 double area2D_Polygon( int n, double X[],double Y[]){
163 double area = 0;
164 int i, j, k; // indices
165
166 if (n < 3) return 0; // a degenerate polygon
167
168 for (i=1, j=2, k=0; i<n; i++, j++, k++) {
169 //double tmp = j<n? Y[j]: Y[0];
170 area += X[i] * (Y[j] - Y[k]);
171 }
172
173 area += X[0] * (Y[1] - Y[n-1]); // wrap-around term
174 return area / 2.0;
175 }
176
177 double AreaofPolygon(int nvert,double X[], double Y[]){
178
179 double area=0. ;
180 int i, j=nvert-1 ;
181
182 for (i=0; i<nvert; i++) {
183 area+=(X[j]+X[i])*(Y[j]-Y[i]);
184 j=i;
185 }
186
187 return area*.5;
188
189 }
190
191 void distPreStepPointAllSides(double pos[],double pre[],int ieta, int iphi, float res[], int iz= 0, int inEB=1){
192
193 if( inEB && !( ieta>=0 && ieta<=169 && iphi>=0 && iphi<=369)){
194 cout<<"input ieta/iphi "<< ieta<<" "<<iphi<<endl;
195 exit(1);
196 }
197
198 double p[4];
199 double ct[3];
200
201 if(inEB==1){
202 ct[0] = xctEBAll[ieta][iphi];
203 ct[1] = yctEBAll[ieta][iphi];
204 ct[2] = zctEBAll[ieta][iphi];
205 }else{
206 ct[0] = xctEEAll[iz][ieta][iphi];
207 ct[1] = yctEEAll[iz][ieta][iphi];
208 ct[2] = zctEEAll[iz][ieta][iphi];
209
210 if(iz!=1 && iz!=0){
211 cout<<"wrong iz "<< iz <<endl;
212 exit(1);
213 }
214
215 }
216
217 double split[3];
218 bool intersets[6];
219 int inpolygon[6];
220
221 double dist_ct[6];
222 double dist_pre[6];
223 double distpremin = 1E9;
224 int ind_distpremin = -1;
225
226 double split_new_all[6][2];
227 for(int j=0; j<6;j++){
228 for(int k=0; k<2; k++){
229 split_new_all[j][k] = -9;
230 }
231 }
232
233 for(int pl = 0; pl<=5; pl++){
234 for(int j1=0; j1<4; j1++){
235
236 if(inEB==1){
237 p[j1] = map_planes_eb[ieta][iphi][4*pl+j1];
238 }else{
239 p[j1] = map_planes_ee[iz][ieta][iphi][4*pl+j1];
240 }
241 }
242
243 double dd1 = distToPlane(pre,p);
244 double dd0 = distToPlane(ct,p);
245
246 if(distpremin>fabs(dd1)){
247 distpremin = fabs(dd1);
248 ind_distpremin = pl;
249 }
250
251 dist_ct[pl] = dd0;
252 dist_pre[pl] = dd1;
253
254 //bool interset_strict = intersectLinePlane(pos,pre,split,p);
255 bool interset = intersectLinePlane_tolerance(pos,pre,split,p);
256
257 intersets[pl] = interset;
258 inpolygon[pl] = 0;
259
260 if(interset){//check the split if inside the area
261 double points[4][3];
262
263 double points_new[4][2];
264 points_new[0][0] =0;
265 points_new[0][1] =0;
266
267 for(int l=0; l<4; l++){ // 4 lines
268 int ind1 = coindall[pl][l];
269
270 if(inEB==1){
271 points[l][0] = coxEBAll[ieta][iphi][ind1];
272 points[l][1] = coyEBAll[ieta][iphi][ind1];
273 points[l][2] = cozEBAll[ieta][iphi][ind1];
274 }else{
275 points[l][0] = coxEEAll[iz][ieta][iphi][ind1];
276 points[l][1] = coyEEAll[iz][ieta][iphi][ind1];
277 points[l][2] = cozEEAll[iz][ieta][iphi][ind1];
278 }
279
280 }
281 points_new[1][0] = distTwoPoints(points[1],points[0]);
282 points_new[1][1] = 0;
283 TVector3 v12(points[1][0]-points[0][0],points[1][1]-points[0][1],points[1][2]-points[0][2] );
284 TVector3 v13(points[2][0]-points[0][0],points[2][1]-points[0][1],points[2][2]-points[0][2] );
285 TVector3 v14(points[3][0]-points[0][0],points[3][1]-points[0][1],points[3][2]-points[0][2] );
286 double theta = v12.Angle(v13);
287 double d13 = distTwoPoints(points[0],points[2]);
288
289 if( fabs(d13*cos(theta)-v12.Dot(v13)/v12.Mag() ) > 1E-10 ){
290 cout<<"check1 "<< d13*cos(theta) <<" "<< v12.Dot(v13)/v12.Mag() <<" "<< d13*cos(theta) - v12.Dot(v13)/v12.Mag() <<endl;
291 exit(1);
292 }
293 TVector3 v = v12.Cross(v13);
294 if( v.z() ==0){
295 cout<<"wrong v12Xv13 ?? "<< v.z()<<endl;
296 exit(1);
297 }
298
299 if( fabs( v.Mag()/v12.Mag() - d13 * sin(theta)) > 1E-10 ){
300 cout<<"check2 "<< v.Mag()/v12.Mag() <<" "<< d13 * sin(theta) <<" "<< v.Mag()/v12.Mag() - d13 * sin(theta) <<endl;
301 exit(1);
302 }
303
304 points_new[2][0] = v12.Dot(v13)/v12.Mag();
305 points_new[2][1] = v.z()/fabs(v.z()) * v.Mag()/v12.Mag();
306 theta = v12.Angle(v14);
307 v = v12.Cross(v14);
308 if( v.z() ==0){
309 cout<<"wrong v12Xv14 ?? "<< v.z()<<endl;
310 exit(1);
311 }
312
313 points_new[3][0] = v12.Dot(v14)/v12.Mag();
314 points_new[3][1] = v.z()/fabs(v.z()) * v.Mag()/v12.Mag();
315
316 //now check if the split
317 double split_new[2];
318
319 TVector3 v1s(split[0]-points[0][0],split[1]-points[0][1],split[2]-points[0][2]);
320 v = v12.Cross(v1s);
321 split_new[0] = v12.Dot(v1s)/v12.Mag();
322 if(v.z()==0){
323 split_new[1] = 0 ;
324 } else{
325 split_new[1] = v.z()/fabs(v.z()) * v.Mag()/v12.Mag();
326 }
327
328 //now check split_new inside
329 double vx[4];
330 double vy[4];
331
332 for(int n=0; n<4; n++){
333 vx[n] = points_new[n][0];
334 vy[n] = points_new[n][1];
335 }
336 int c = pnpoly(4,vx,vy,split_new[0],split_new[1]);
337 inpolygon[pl] = c;
338
339
340 split_new_all[pl][0] = split_new[0];
341 split_new_all[pl][1] = split_new[1];
342
343
344 }///if interset
345
346
347 }//all 6 planes
348
349 //first find intersets and inside area
350 vector<int> pl;
351 for(int j=0; j<6; j++){
352 if( intersets[j] && inpolygon[j] ){
353 pl.push_back(j);
354 }
355 }
356
357 int ind;
358 if(pl.size()>1){
359
360 double premin = 1E9;
361 ind = pl[0];
362 for(int j=0;j<int(pl.size());j++){
363 if(premin> fabs(dist_pre[pl[j]])){
364 premin = fabs(dist_pre[pl[j]]);
365 ind = pl[j];
366 }
367 }
368
369 }else if(pl.size()==1){
370 ind = pl[0];
371
372
373 }else{
374 ind = ind_distpremin;
375 }
376 res[0] = dist_pre[ind] * dist_ct[ind]>0 ? fabs(dist_pre[ind]) : -fabs(dist_pre[ind]); //postive means inside
377
378 res[1] = ind;
379 res[2] = split_new_all[ind][0];
380 res[3] = split_new_all[ind][1];
381
382
383 }
384