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

# User Rev Content
1 yangyong 1.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