Allink  v0.1
MatematicaPlane.cpp
00001 #include "../include/Matematica.h"
00002 
00003 Piano::Piano(Vettore *P1e,Vettore *P2e,Vettore *P3e){
00004   P1.Copy(P1e);
00005   P2.Copy(P2e);
00006   P3.Copy(P3e);
00007   Dir21 = P2 - P1;
00008   Dir31 = P3 - P1;
00009   Dir23 = P2 - P3;
00010   for(int d=0;d<3;d++){
00011     Dir21[d] = P2[d] - P1[d];
00012     Dir31[d] = P3[d] - P1[d];
00013     Dir23[d] = P2[d] - P3[d];
00014   }
00015   Vettore P4e = P1 + Dir21 + Dir31;
00016   P4.Copy(&P4e);
00017   Norm = Dir21 ^ Dir31;
00018   Norm[0] = Dir21.x[1]*Dir31.x[2] - Dir21.x[2]*Dir31.x[1];
00019   Norm[1] = Dir21.x[2]*Dir31.x[0] - Dir21.x[0]*Dir31.x[2];
00020   Norm[2] = Dir21.x[0]*Dir31.x[1] - Dir21.x[1]*Dir31.x[0];
00021   Norm.Normalize();
00022   // printf("------\n");
00023   // P1.Print();
00024   // P2.Print();
00025   // Dir21.Print();
00026   // Norm.Print();
00027   for(int d=0;d<3;d++){
00028     if( fabs(Norm[d]) > 0.){
00029       InvNorm[d] = 1./Norm[d];
00030       IsInf[d] = 0;
00031     }
00032     else{
00033       InvNorm[d] = 0.;
00034       IsInf[d] = 1;
00035     }
00036   }
00037   for(int d=0;d<3;d++){
00038     Bound[d*2    ] = MIN(P1[d],MIN(P2[d],P3[d]));
00039     //Bound[d*2    ] = MIN(P1[d],MIN(P2[d],MIN(P3[d],P4[d])));
00040     Bound[d*2+1] = MAX(P1[d],MAX(P2[d],P3[d]));
00041     //Bound[d*2+1] = MAX(P1[d],MAX(P2[d],MAX(P3[d],P4[d])));
00042   }
00043   dPar = - P1[0]*Norm[0] - P1[1]*Norm[1] - P1[2]*Norm[2];
00044   mxy[0] = (P1[1] - P2[1])*Inv(P1[0] - P2[0]);
00045   qxy[0] = P1[1] - mxy[0]*P1[0];
00046   mxz[0] = (P1[2] - P2[2])*Inv(P1[0] - P2[0]);
00047   qxz[0] = P1[2] - mxz[0]*P1[0];
00048   mxy[1] = (P1[1] - P3[1])*Inv(P1[0] - P3[0]);
00049   qxy[1] = P1[1] - mxy[1]*P1[0];
00050   mxz[1] = (P1[2] - P3[2])*Inv(P1[0] - P3[0]);
00051   qxz[1] = P1[2] - mxz[1]*P1[0];
00052   mxy[2] = (P3[1] - P2[1])*Inv(P3[0] - P2[0]);
00053   qxy[2] = P1[1] - mxy[2]*P1[0];
00054   mxz[2] = (P3[2] - P2[2])*Inv(P3[0] - P2[0]);
00055   qxz[2] = P1[2] - mxz[2]*P1[0];
00056   Rad = 1.;
00057 }
00058 Piano::~Piano(){}
00059 //--------------------------------------------------------------
00060 double Piano::Distance(Vettore *Pos) {
00061   double Dist = fabs(Norm.x[0]*Pos->x[0] + Norm.x[1]*Pos->x[1] + Norm.x[2]*Pos->x[2] + dPar);
00062   return Dist;
00063 }
00064 Vettore Piano::ProjOnSurf(Vettore *Pos){
00065   double Dist = Distance(Pos);
00066   Vettore Pos1(Pos->NDim);
00067   double Sign = 0.;
00068   for(int d=0;d<3;d++){
00069     Sign += (P1[d] - Pos->x[d])*Norm[d];
00070   }
00071   if(Sign > 0) Sign = -1.;
00072   else Sign = 1.;
00073   for(int d=0;d<3;d++){
00074     Pos1[d] = Pos->x[d] - Sign*Dist*Norm.x[d];
00075   }
00076   return Pos1;
00077 }
00078 Vettore Piano::ProjOnNorm(Vettore *v){
00079   double Len = 0.;
00080   for(int d=0;d<v->NDim;d++){
00081     Len += v->x[d]*Norm[d];
00082   }
00083   Vettore Scal(Len*Norm[0],Len*Norm[1],Len*Norm[2]);
00084   return Scal;
00085 }
00086 Vettore Piano::Reflect(Vettore *v){
00087   // Vettore v2(v->NDim);
00088   // v2.Copy(v);
00089   Vettore n1 = ProjOnNorm(v);
00090   // Vettore v1 = 2.*(n1 - v2);
00091   Vettore v1(3);
00092   for(int d=0;d<3;d++){
00093     v1[d] = - v->x[d] + 2.*n1[d];
00094   }
00095   return v1;
00096 }
00097 int Piano::Impact(Vettore *Pos,Vettore *Vel) {
00098   double Dist = Distance(Pos);
00099   if(Dist > Rad) return 0;
00100   Vettore PosS = ProjOnSurf(Pos);
00101   if(!IsOnSurf(&PosS)) return 0;
00102   Vettore Vel1 = Reflect(Vel);
00103   Vel->Copy(&Vel1);
00104 }
00105 Vettore Piano::GetVertex(int i) {
00106   if(i == 1) return P1;
00107   if(i == 2) return P2;
00108   if(i == 3) return P3;
00109   if(i == 4) return P4;
00110   return P1;
00111 }
00112 double Piano::Inv(double x){
00113   return x != 0. ? 1./x : 100000000000.;
00114 }
00115 int Piano::IsOnSurf(Vettore *P){
00116   //return IsOnSurf1(P);
00117   return IsOnSurf2(P);
00118 }
00119 int Piano::IsOnSurf1(Vettore *P){
00120   if( SameSide(P,&P1,&P2,&P3) && SameSide(P,&P2,&P1,&P3) && SameSide(P,&P3,&P1,&P2)) return 1;
00121   return 0;
00122 }
00123 int Piano::SameSide(Vettore *P1,Vettore *A1,Vettore *B1,Vettore *C1){
00124   Vettore P(3); P.Copy(P1);
00125   Vettore A(3); A.Copy(A1);
00126   Vettore B(3); B.Copy(B1);
00127   Vettore C(3); C.Copy(C1);
00128   Vettore D1 = (C-B)^(P-B);
00129   Vettore D2 = (C-B)^(A-B);
00130   double Scal = 0.;
00131   for(int d=0;d<3;d++){
00132     int NUno = (d+1)%3;
00133     int NDue = (d+2)%3;
00134     D1[d] = (C[NUno]-B[NUno])*(P[NDue]-B[NDue]) - (C[NDue]-B[NDue])*(P[NUno]-B[NUno]);
00135     D2[d] = (C[NUno]-B[NUno])*(A[NDue]-B[NDue]) - (C[NDue]-B[NDue])*(A[NUno]-B[NUno]);
00136     Scal += D1[d]*D2[d];
00137   }
00138   if( Scal >= 0) return 1;
00139   return 0;
00140   if( D1%D2 >= 0) return 1;
00141   return 0;
00142 }
00143 // TOFIX!!!!
00144 int Piano::IsOnSurf2(Vettore *PA){
00145   Vettore P(3);P.Copy(PA);
00146   Vettore DirP1 = P - P1;
00147   for(int d=0;d<3;d++){
00148     DirP1[d] = P[d] - P1[d];
00149   }
00150   // double Inv = (Dir21%Dir21)*(Dir31%Dir31) - (Dir21%Dir31)*(Dir31%Dir21);
00151   // double v = ( (Dir31%Dir31)*(DirP1%Dir31) - (Dir31%Dir21)*(DirP1%Dir31) )/Inv;
00152   // double u = ( (Dir21%Dir21)*(DirP1%Dir21) - (Dir21%Dir31)*(DirP1%Dir21) )/Inv;
00153   double sq2 = 0.,sq3 = 0.;
00154   double pd32 = 0., pdP3 = 0., pdP2 = 0.;
00155   for(int d=0;d<3;d++){
00156     sq2 += SQR(Dir21[d]);
00157     sq3 += SQR(Dir31[d]);
00158     pd32 += Dir21[d]*Dir31[d];
00159     pdP3 += Dir31[d]*DirP1[d];
00160     pdP2 += Dir21[d]*DirP1[d];
00161   }
00162   double Inv = 1./(sq2*sq3 - SQR(pd32));
00163   double v = (sq3*pdP2 - pd32*pdP3)*Inv;
00164   double u = (sq2*pdP3 - pd32*pdP2)*Inv;
00165   if(u >= 0. && v >= 0. && (u+v) < 1.) return 1;
00166   else return 0;
00167 }