00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <rl_Polarization.h>
00029
00030 #include <cmath>
00031 #include <cfloat>
00032 #include <mathconst/mathconst.h>
00033 #include <iostream>
00034
00035 #include <rl_raylib/rl_ReflectionCoefPOD.h>
00036
00037 using namespace std;
00038
00039
00040 #ifdef CONST_SINGRAZE
00041 static double alpha[] = {51.2, 46.2, 41.2, 36.4, 31.7, 27.0};
00042 #endif
00043
00044 #ifdef POLREFL_DEBUG
00045 static FILE *dbgw;
00046 #endif
00047
00048
00049
00050
00051
00052
00053 static void
00054 make_Triad( dvm3_Vector& x,
00055 dvm3_Vector& y,
00056 dvm3_Vector const& s );
00057
00058
00059 static void
00060 pol_perp_par(
00061 dvm3_Vector& perp,
00062 dvm3_Vector& parv1,
00063 dvm3_Vector& parv2,
00064 dvm3_Vector const& norm,
00065 dvm3_Vector const& v1,
00066 dvm3_Vector const& v2
00067 );
00068
00069
00070
00071
00072
00073
00074
00075 void rl_PolCSPOD::
00076 init( double b_over_a,
00077 double psi
00078 )
00079 {
00080
00081
00082 double cpsi = cos(psi * M_DEG2RAD);
00083 double spsi = sin(psi * M_DEG2RAD);
00084
00085 double sqre = sqrt(1.0 + b_over_a * b_over_a );
00086
00087 c2_[0] = rl_Traits::complex( cpsi / sqre, (double)0.0 );
00088 c2_[1] = rl_Traits::complex( spsi / sqre, (double)0.0 );
00089
00090 rl_Traits::complex ctmp( -spsi / sqre, (double)0.0 );
00091 s2_[0] = b_over_a * ctmp;
00092
00093 ctmp = rl_Traits::complex( cpsi / sqre, (double)0.0 );
00094 s2_[1] = b_over_a * ctmp;
00095 }
00096
00097
00098 double rl_PolCSPOD::
00099 intensity() const
00100 {
00101 rl_Traits::complex crossterms( c2_[0] * conj( s2_[0] )
00102 + c2_[1] * conj( s2_[1] ) );
00103 double rfl = norm(c2_[0]) + norm(s2_[0]) + norm(c2_[1]) + norm(s2_[1])
00104 + 2.0 * crossterms.real();
00105
00106 #ifdef OSAC_WEIGHT_KLUDGE
00107
00108
00109
00110
00111
00112
00113 return 1.e-8 * ((int)(1.0e8 * rfl + 0.5));
00114 #else
00115 return rfl;
00116 #endif
00117 }
00118
00119
00120 void rl_PolCSPOD::
00121 attenuate( double factor )
00122 {
00123 const double fac = sqrt(factor);
00124 c2_[0] *= fac;
00125 c2_[1] *= fac;
00126 s2_[0] *= fac;
00127 s2_[1] *= fac;
00128 }
00129
00130
00131
00132
00133
00134 std::ostream& rl_PolCSPOD::
00135 print_on( std::ostream& os ) const
00136 {
00137 os << "[(" << c2_[0].real() << "," << c2_[0].imag() << ")("
00138 << c2_[1].real() << "," << c2_[1].imag() << ")][("
00139 << s2_[0].real() << "," << s2_[0].imag() << ")("
00140 << s2_[1].real() << "," << s2_[1].imag() << ")]";
00141 return os;
00142 }
00143
00144
00145
00146
00147
00148 void rl_PolCSPOD::
00149 cprint_on( FILE* of ) const
00150 {
00151 fprintf(of, "\nc2: [(%.15e, %.15e)(%.15e, %.15e)]",
00152 c2_[0].real(), c2_[0].imag(),
00153 c2_[1].real(), c2_[1].imag() );
00154 fprintf(of, "\ns2: [(%.15e, %.15e)(%.15e, %.15e)]",
00155 s2_[0].real(), s2_[0].imag(),
00156 s2_[1].real(), s2_[1].imag() );
00157 fprintf(of, "\n%.15e\n", intensity());
00158 }
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 void rl_Polarization::
00171 init( rl_PolCSPOD const& cs, dvm3_Vector const& dir )
00172 {
00173 dvm3_Vector x1;
00174 dvm3_Vector y1;
00175
00176
00177
00178
00179
00180
00181
00182
00183 make_Triad( x1, y1, dir );
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 C_r_.lincomb( cs.c2_[0].real(), x1, cs.c2_[1].real(), y1 );
00198 C_i_.lincomb( cs.c2_[0].imag(), x1, cs.c2_[1].imag(), y1 );
00199 S_r_.lincomb( cs.s2_[0].real(), x1, cs.s2_[1].real(), y1 );
00200 S_i_.lincomb( cs.s2_[0].imag(), x1, cs.s2_[1].imag(), y1 );
00201 }
00202
00203
00204
00205
00206
00207 double rl_Polarization::
00208 intensity() const
00209 {
00210 return dot(C_r_, C_r_) + dot(C_i_, C_i_) + dot(S_r_, S_r_) + dot(S_i_, S_i_)
00211 + 2.0 * ( dot(C_i_, S_r_) - dot(C_r_, S_i_) );
00212 }
00213
00214
00215
00216 void rl_Polarization::
00217 get_PolCSPOD( rl_PolCSPOD& cs, dvm3_Vector const& dir ) const
00218 {
00219
00220
00221
00222
00223 dvm3_Vector x2;
00224 dvm3_Vector y2;
00225 make_Triad( x2, y2, dir );
00226
00227
00228
00229
00230 double d1 = dot( x2, C_r_);
00231 double d2 = dot( x2, C_i_);
00232 cs.c2_[0] = rl_Traits::complex( d1, d2 );
00233 cs.c2_[1] = rl_Traits::complex( dot( y2, C_r_), dot( y2, C_i_) );
00234 cs.s2_[0] = rl_Traits::complex( dot( x2, S_r_), dot( x2, S_i_) );
00235 cs.s2_[1] = rl_Traits::complex( dot( y2, S_r_), dot( y2, S_i_) );
00236 }
00237
00238
00239
00240
00241
00242 void rl_Polarization::
00243 attenuate( double factor )
00244 {
00245 const double fac = sqrt(factor);
00246 C_r_ *= fac;
00247 C_i_ *= fac;
00248 S_r_ *= fac;
00249 S_i_ *= fac;
00250 }
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 void rl_Polarization::
00262 reflect(
00263 dvm3_Vector const& normal,
00264 dvm3_Vector const& dir_in,
00265 dvm3_Vector const& dir_out,
00266 rl_ReflectionCoefPOD const& rflcoef
00267 )
00268 {
00269
00270
00271
00272 #ifdef CONST_SINGRAZE
00273 sg = sin(alpha[CONST_SINGRAZE-1] * 0.0002908882);
00274 #endif
00275
00276
00277
00278
00279
00280
00281
00282
00283 dvm3_Vector perp;
00284 dvm3_Vector parvi;
00285 dvm3_Vector parvo;
00286
00287 pol_perp_par( perp, parvi, parvo, normal,
00288 dir_in, dir_out );
00289
00290
00291
00292
00293
00294
00295
00296
00297 dvm3_Matrix T_prp;
00298 dvm3_Matrix T_par;
00299
00300 T_par.dyad_product( parvo, parvi );
00301 T_prp.dyad_product( perp, perp );
00302
00303
00304
00305 dvm3_Matrix T_re;
00306 dvm3_Matrix T_im;
00307
00308 T_re.lincomb( rflcoef.para().real(), T_par,
00309 rflcoef.perp().real(), T_prp );
00310 T_im.lincomb( rflcoef.para().imag(), T_par,
00311 rflcoef.perp().imag(), T_prp );
00312
00313
00314
00315
00316 dvm3_Vector Tr_Cr; T_re.mvmult( Tr_Cr, C_r_ );
00317 dvm3_Vector Tr_Ci; T_re.mvmult( Tr_Ci, C_i_ );
00318 dvm3_Vector Ti_Cr; T_im.mvmult( Ti_Cr, C_r_ );
00319 dvm3_Vector Ti_Ci; T_im.mvmult( Ti_Ci, C_i_ );
00320
00321 dvm3_Vector Tr_Sr; T_re.mvmult( Tr_Sr, S_r_ );
00322 dvm3_Vector Tr_Si; T_re.mvmult( Tr_Si, S_i_ );
00323 dvm3_Vector Ti_Sr; T_im.mvmult( Ti_Sr, S_r_ );
00324 dvm3_Vector Ti_Si; T_im.mvmult( Ti_Si, S_i_ );
00325
00326
00327
00328 C_r_ = Tr_Cr - Ti_Ci;
00329 C_i_ = Tr_Ci + Ti_Cr;
00330 S_r_ = Tr_Sr - Ti_Si;
00331 S_i_ = Tr_Si + Ti_Sr;
00332 }
00333
00334
00335
00336
00337
00338 std::ostream& rl_Polarization::
00339 print_on( std::ostream& os ) const
00340 {
00341 os << C_r_ << C_i_ << S_r_ << S_i_;
00342 return os;
00343 }
00344
00345
00346
00347
00348
00349 void rl_Polarization::
00350 cprint_on( FILE* of ) const
00351 {
00352 double* vec = new double[3];
00353 C_r_.copy_to_cvec( vec );
00354 fprintf(of, "\nC_r_: [%.15e, %.15e %.15e]\n",
00355 vec[0], vec[1], vec[2]);
00356 C_i_.copy_to_cvec( vec );
00357 fprintf(of, "\nC_i_: [%.15e, %.15e %.15e]\n",
00358 vec[0], vec[1], vec[2]);
00359 S_r_.copy_to_cvec( vec );
00360 fprintf(of, "\nS_r_: [%.15e, %.15e %.15e]\n",
00361 vec[0], vec[1], vec[2]);
00362 S_i_.copy_to_cvec( vec );
00363 fprintf(of, "\nS_i_: [%.15e, %.15e %.15e]\n",
00364 vec[0], vec[1], vec[2]);
00365 delete [] vec;
00366 }
00367
00368 #define TINY_VALUE (100.0 * DBL_EPSILON)
00369
00370
00371
00372
00373
00374
00375 void
00376 pol_perp_par(
00377 dvm3_Vector& perp,
00378 dvm3_Vector& parv1,
00379 dvm3_Vector& parv2,
00380 dvm3_Vector const& norm,
00381 dvm3_Vector const& v1,
00382 dvm3_Vector const& v2
00383 )
00384 {
00385
00386
00387 if ( fabs(dot(v1, v2)) < 0.99999 )
00388 {
00389 perp.cross( v2, v1 );
00390 }
00391 else
00392 {
00393 if ( fabs(dot(norm,v1)) < 0.99999 )
00394 {
00395 perp.cross( norm, v1 );
00396 }
00397 else
00398 {
00399 if ( fabs(1.0 - fabs( norm[0] )) < TINY_VALUE )
00400 {
00401 perp.init( norm[2], 0.0, -norm[0] );
00402 }
00403 else
00404 {
00405 perp.init( 0.0, -norm[2], -norm[1] );
00406 }
00407 }
00408 }
00409 perp.unitize();
00410
00411
00412
00413 parv1.cross( v1, perp );
00414 parv2.cross( v2, perp );
00415 }
00416
00417
00418 void
00419 make_Triad( dvm3_Vector& x,
00420 dvm3_Vector& y,
00421 dvm3_Vector const& s )
00422 {
00423
00424
00425
00426
00427 if ( fabs(1.0 - fabs( s[1] )) > TINY_VALUE )
00428 {
00429 x.init( s[2], 0.0, -s[0] );
00430 }
00431 else
00432 {
00433 x.init( 1.0, 0.0, 0.0 );
00434 }
00435 x.unitize();
00436
00437
00438
00439
00440 y.cross( s, x );
00441
00442
00443 }
00444 #undef TINY_VALUE
00445
00446 #undef CONST_SINGRAZE