00001 // this : 00002 #include <SoUtils/SbProjector.h> 00003 00004 #include <math.h> 00005 00006 bool arctan(double aX,double aY,double& aValue) { 00007 if((aX==0)&&(aY==0)) { 00008 aValue = 0; 00009 return false; 00010 } else { 00011 aValue = ::atan2(aX,aY); // return value in [-PI,PI] 00012 return true; 00013 } 00014 } 00015 00017 SoUtils::SbProjector::SbProjector( 00018 const SbString& aProjection 00019 ) 00020 :fProjection(0) 00023 { 00024 if(aProjection=="RZ") fProjection = 1; 00025 else if(aProjection=="PHIZ") fProjection = 2; 00026 else if(aProjection=="ZR") fProjection = 3; 00027 else if(aProjection=="ZPHI") fProjection = 4; 00028 else if(aProjection=="-ZR") fProjection = 5; 00029 else if(aProjection=="PHIETA") fProjection = 6; 00030 00031 } 00033 SoUtils::SbProjector::SbProjector( 00034 const SoUtils::SbProjector& aProjector 00035 ) 00036 :fProjection(aProjector.fProjection) 00039 { 00040 } 00042 SoUtils::SbProjector::~SbProjector( 00043 ) 00046 { 00047 } 00049 bool SoUtils::SbProjector::isRZ( 00050 ) const 00053 { 00054 return (fProjection==1 ? true : false); 00055 } 00057 bool SoUtils::SbProjector::isZR( 00058 ) const 00061 { 00062 return (fProjection==3 || fProjection==5 ? true : false); 00063 } 00065 bool SoUtils::SbProjector::project( 00066 int aNumber 00067 ,SbVec3f* aPoints 00068 ) const 00071 { 00072 if(fProjection==1) 00073 return projectRZ(aNumber,aPoints); 00074 else if(fProjection==2) 00075 return projectPHIZ(aNumber,aPoints); 00076 else if(fProjection==3) 00077 return projectZR(aNumber,aPoints); 00078 else if(fProjection==4) 00079 return projectZPHI(aNumber,aPoints); 00080 else if(fProjection==5) 00081 return projectNZR(aNumber,aPoints); 00082 else 00083 return true; // Do nothing. It is ok. 00084 } 00086 bool SoUtils::SbProjector::projectRZ( 00087 int aNumber 00088 ,SbVec3f* aPoints 00089 ) const 00092 { 00093 for(int index=0;index<aNumber;index++) { 00094 SbVec3f& point = aPoints[index]; 00095 float x = point[0]; 00096 float y = point[1]; 00097 float z = point[2]; 00098 float r = (float)::sqrt(x*x+y*y); 00099 //printf("debug : SbProjector::projectRZ : %d (%d) : %g %g\n", 00100 // index,aNumber,r,z); 00101 point[0] = r; 00102 point[1] = z; 00103 point[2] = 0; 00104 } 00105 return true; 00106 } 00108 bool SoUtils::SbProjector::projectPHIZ( 00109 int aNumber 00110 ,SbVec3f* aPoints 00111 ) const 00114 { 00115 for(int index=0;index<aNumber;index++) { 00116 SbVec3f& point = aPoints[index]; 00117 float x = point[0]; 00118 float y = point[1]; 00119 float z = point[2]; 00120 double v; 00121 if(!arctan(y,x,v)) return false; 00122 point[0] = (float)v; 00123 point[1] = z; 00124 point[2] = 0; 00125 } 00126 return true; 00127 } 00129 bool SoUtils::SbProjector::projectZR( 00130 int aNumber 00131 ,SbVec3f* aPoints 00132 ) const 00135 { 00136 for(int index=0;index<aNumber;index++) { 00137 SbVec3f& point = aPoints[index]; 00138 float x = point[0]; 00139 float y = point[1]; 00140 float z = point[2]; 00141 float r = (float)::sqrt(x*x+y*y); 00142 //printf("debug : SbProjector::projectRZ : %d (%d) : %g %g\n", 00143 // index,aNumber,r,z); 00144 point[0] = z; 00145 point[1] = r; 00146 point[2] = 0; 00147 } 00148 return true; 00149 } 00151 bool SoUtils::SbProjector::projectNZR( 00152 int aNumber 00153 ,SbVec3f* aPoints 00154 ) const 00157 { 00158 for(int index=0;index<aNumber;index++) { 00159 SbVec3f& point = aPoints[index]; 00160 float x = point[0]; 00161 float y = point[1]; 00162 float z = point[2]; 00163 float r = (float)::sqrt(x*x+y*y); 00164 if (x<0) {r=-r;} 00165 point[0] = z; 00166 point[1] = r; 00167 point[2] = 0; 00168 } 00169 return true; 00170 } 00172 bool SoUtils::SbProjector::projectPHIETA( 00173 int aNumber 00174 ,SbVec3f* aPoints 00175 ) const 00178 { 00179 for(int index=0;index<aNumber;index++) { 00180 SbVec3f& point = aPoints[index]; 00181 float x = point[0]; 00182 float y = point[1]; 00183 float eta = (float)::tan(x*x+y*y); 00184 double phi; 00185 if(!arctan(y,x,phi)) return false; 00186 //printf("debug : SbProjector::projectPHIETA : %d (%d) : %g %g\n", 00187 // index,aNumber,eta,phi); 00188 point[0] = eta; 00189 point[1] = (float)phi; 00190 point[2] = 0; 00191 } 00192 return true; 00193 } 00195 bool SoUtils::SbProjector::projectZPHI( 00196 int aNumber 00197 ,SbVec3f* aPoints 00198 ) const 00201 { 00202 for(int index=0;index<aNumber;index++) { 00203 SbVec3f& point = aPoints[index]; 00204 float x = point[0]; 00205 float y = point[1]; 00206 float z = point[2]; 00207 double v; 00208 if(!arctan(y,x,v)) return false; 00209 point[0] = z; 00210 point[1] = (float)v; 00211 point[2] = 0; 00212 } 00213 return true; 00214 } 00215 /* 00217 bool SoUtils::SbProjector::projectRHOZ( 00218 const SbVec3f& aIn 00219 ,SbVec3f& aOut 00220 ) 00223 { 00224 aOut.clear(); 00225 if(!aIn.size()) return true; 00226 else if( (This->specialProjection.specialProjection==OSpecialProjectionRHOZ) && 00227 (ONodeGetProjected(a_node)==1) ) 00228 { 00229 double phi1from, phi1to; 00230 phi1from = This->specialProjection.rhoz_phi1 / 180. * M_PI; 00231 phi1to = phi1from + M_PI; 00232 if(AllocatePoints(a_number)==0) return 0; 00233 for (index=0;index<a_number;index++) 00234 { 00235 double r,x,y,phi; 00236 x = a_xs[index]; 00237 y = a_ys[index]; 00238 r = sqrt ( x * x + y * y); 00239 Class.ys[index] = r / (1 + This->specialProjection.fisheye_a * r); 00240 Class.xs[index] = a_zs[index] / This->specialProjection.xcompress; 00241 phi = CMathGetArcTangent (y,x); 00242 if(phi < 0) phi = M_PI - phi; 00243 if(phi < phi1from || phi >= phi1to) Class.ys[index] *= -1; 00244 Class.zs[index] = 0.; 00245 } 00246 if(a_pxs!=NULL) *a_pxs = Class.xs; 00247 if(a_pys!=NULL) *a_pys = Class.ys; 00248 if(a_pzs!=NULL) *a_pzs = Class.zs; 00249 return a_number; 00250 } 00252 bool SoUtils::SbProjector::projectTHETAPHI( 00253 const SbVec3f& aIn 00254 ,SbVec3f& aOut 00255 ) 00258 { 00259 aOut.clear(); 00260 if(!aIn.size()) return true; 00261 else if( (This->specialProjection.specialProjection==OSpecialProjectionTHETAPHI) && 00262 (ONodeGetProjected(a_node)==1) ) 00263 { 00264 if(AllocatePoints(a_number)==0) return 0; 00265 for (index=0;index<a_number;index++) 00266 { 00267 double x,y,z; 00268 x = a_xs[index]; 00269 y = a_ys[index]; 00270 z = a_zs[index]; 00271 Class.xs[index] = CMathGetArcTangent (y, sqrt( x * x + z * z)); 00272 Class.ys[index] = CMathGetArcTangent (y,x); 00273 Class.zs[index] = 0.; 00274 } 00275 if(a_pxs!=NULL) *a_pxs = Class.xs; 00276 if(a_pys!=NULL) *a_pys = Class.ys; 00277 if(a_pzs!=NULL) *a_pzs = Class.zs; 00278 return a_number; 00279 } 00281 bool SoUtils::SbProjector::projectPHITHETA( 00282 const SbVec3f& aIn 00283 ,SbVec3f& aOut 00284 ) 00287 { 00288 else if( (This->specialProjection.specialProjection==OSpecialProjectionPHITHETA) && 00289 (ONodeGetProjected(a_node)==1) ) 00290 { 00291 double r_scale, z_scale; 00292 if(AllocatePoints(a_number)==0) return 0; 00293 r_scale = 1. + This->specialProjection.v_rho_max * This->specialProjection.fisheye_a; 00294 z_scale = 1. + This->specialProjection.v_z_max * This->specialProjection.fisheye_a; 00295 for (index=0;index<a_number;index++) 00296 { 00297 double x,y,z,r,phi; 00298 x = a_xs[index]; 00299 y = a_ys[index]; 00300 z = a_zs[index]; 00301 if (This->specialProjection.fisheye_a > 0.0) 00302 { 00303 r = sqrt ( x * x + y * y); 00304 r /= 1 + This->specialProjection.fisheye_a * r; 00305 r *= r_scale; 00306 phi = CMathGetArcTangent (y,x); 00307 Class.xs[index] = r * sin(phi) / This->specialProjection.xcompress; 00308 Class.ys[index] = r * cos(phi); 00309 Class.zs[index] = z / (1 + This->specialProjection.fisheye_a * z) * z_scale; 00310 } 00311 else 00312 { 00313 Class.xs[index] = x / This->specialProjection.xcompress; 00314 Class.ys[index] = y; 00315 } 00316 Class.zs[index] = z; 00317 } 00318 if(a_pxs!=NULL) *a_pxs = Class.xs; 00319 if(a_pys!=NULL) *a_pys = Class.ys; 00320 if(a_pzs!=NULL) *a_pzs = Class.zs; 00321 return a_number; 00322 } 00324 bool SoUtils::SbProjector::projectPHIR( 00325 const SbVec3f& aIn 00326 ,SbVec3f& aOut 00327 ) 00330 { 00331 else if( (This->specialProjection.specialProjection==OSpecialProjectionPHIR) && 00332 (ONodeGetProjected(a_node)==1) ) 00333 { 00334 double v_left,v_right,v_top,v_bottom, scale; 00335 if(AllocatePoints(a_number)==0) return 0; 00336 OCameraGetViewLimits(This,&v_left,&v_right,&v_top,&v_bottom); 00337 scale = 0.9 * (v_top - v_bottom) / M_PI / 2; 00338 for (index=0;index<a_number;index++) 00339 { 00340 double x,y,z; 00341 x = a_xs[index]; 00342 y = a_ys[index]; 00343 z = a_zs[index]; 00344 Class.ys[index] = CMathGetArcTangent (y,x) * scale; 00345 Class.xs[index] = sqrt ( x*x + y*y + z*z ) / This->specialProjection.xcompress; 00346 Class.zs[index] = 0.; 00347 } 00348 if(a_pxs!=NULL) *a_pxs = Class.xs; 00349 if(a_pys!=NULL) *a_pys = Class.ys; 00350 if(a_pzs!=NULL) *a_pzs = Class.zs; 00351 return a_number; 00352 } 00354 bool SoUtils::SbProjector::projectPHIRHO( 00355 const SbVec3f& aIn 00356 ,SbVec3f& aOut 00357 ) 00360 { 00361 else if( (This->specialProjection.specialProjection==OSpecialProjectionPHIRHO) && 00362 (ONodeGetProjected(a_node)==1) ) 00363 { 00364 double v_left,v_right,v_top,v_bottom, scale; 00365 if(AllocatePoints(a_number)==0) return 0; 00366 OCameraGetViewLimits(This,&v_left,&v_right,&v_top,&v_bottom); 00367 scale = 0.9 * (v_top - v_bottom) / M_PI / 2; 00368 for (index=0;index<a_number;index++) 00369 { 00370 double x,y; 00371 x = a_xs[index]; 00372 y = a_ys[index]; 00373 Class.ys[index] = CMathGetArcTangent (y,x) * scale; 00374 Class.xs[index] = sqrt (x * x + y * y) / This->specialProjection.xcompress; 00375 Class.zs[index] = 0.; 00376 } 00377 if(a_pxs!=NULL) *a_pxs = Class.xs; 00378 if(a_pys!=NULL) *a_pys = Class.ys; 00379 if(a_pzs!=NULL) *a_pzs = Class.zs; 00380 return a_number; 00381 } 00383 bool SoUtils::SbProjector::projectVPLOT( 00384 const SbVec3f& aIn 00385 ,SbVec3f& aOut 00386 ) 00389 { 00390 else if( (This->specialProjection.specialProjection==OSpecialProjectionVPLOT) && 00391 (ONodeGetProjected(a_node)==1) ) 00392 { 00393 double v_left,v_right,v_top,v_bottom, scale; 00394 00395 if(AllocatePoints(2*a_number)==0) return 0; 00396 OCameraGetViewLimits(This,&v_left,&v_right,&v_top,&v_bottom); 00397 scale = 0.9 * (v_top - v_bottom) / M_PI / 2; 00398 for (index=0;index<a_number;index++) 00399 { 00400 double r,x,y,z,phi,theta,rmax,d_k; 00401 x = a_xs[index]; 00402 y = a_ys[index]; 00403 z = a_zs[index]; 00404 r = sqrt (x * x + y * y); 00405 phi = CMathGetArcTangent (y,x); 00406 theta = CMathGetArcTangent (r,z); 00407 rmax = MINIMUM(This->specialProjection.v_rho_max/sin(theta), 00408 This->specialProjection.v_z_max/fabs(cos(theta))); 00409 d_k = This->specialProjection.v_k * (rmax - r); 00410 Class.xs[index] = (theta + d_k) * scale; 00411 Class.ys[index] = phi * scale; 00412 Class.zs[index] = 0.; 00413 Class.xs[index+a_number] = (theta - d_k) * scale; 00414 Class.ys[index+a_number] = Class.ys[index]; 00415 Class.zs[index+a_number] = Class.zs[index]; 00416 } 00417 if(a_pxs!=NULL) *a_pxs = Class.xs; 00418 if(a_pys!=NULL) *a_pys = Class.ys; 00419 if(a_pzs!=NULL) *a_pzs = Class.zs; 00420 return 2*a_number; 00421 } 00423 bool SoUtils::SbProjector::projectFISHEYE( 00424 const SbVec3f& aIn 00425 ,SbVec3f& aOut 00426 ) 00429 { 00430 else if( (This->specialProjection.specialProjection==OSpecialProjectionFISHEYE) && 00431 (ONodeGetProjected(a_node)==1) ) 00432 { 00433 double r_scale, z_scale; 00434 if(AllocatePoints(a_number)==0) return 0; 00435 r_scale = 1. + This->specialProjection.v_rho_max * This->specialProjection.fisheye_a; 00436 z_scale = 1. + This->specialProjection.v_z_max * This->specialProjection.fisheye_a; 00437 for (index=0;index<a_number;index++) 00438 { 00439 double x,y,z,r,phi; 00440 x = a_xs[index]; 00441 y = a_ys[index]; 00442 z = a_zs[index]; 00443 if (This->specialProjection.fisheye_a > 0.0) 00444 { 00445 r = sqrt ( x * x + y * y); 00446 r /= 1 + This->specialProjection.fisheye_a * r; 00447 r *= r_scale; 00448 phi = CMathGetArcTangent (y,x); 00449 Class.xs[index] = r * sin(phi) / This->specialProjection.xcompress; 00450 Class.ys[index] = r * cos(phi); 00451 Class.zs[index] = z / (1 + This->specialProjection.fisheye_a * z) * z_scale; 00452 } 00453 else 00454 { 00455 Class.xs[index] = x / This->specialProjection.xcompress; 00456 Class.ys[index] = y; 00457 } 00458 Class.zs[index] = z; 00459 } 00460 if(a_pxs!=NULL) *a_pxs = Class.xs; 00461 if(a_pys!=NULL) *a_pys = Class.ys; 00462 if(a_pzs!=NULL) *a_pzs = Class.zs; 00463 return a_number; 00464 } 00465 else 00466 { 00467 if(a_pxs!=NULL) *a_pxs = a_xs; 00468 if(a_pys!=NULL) *a_pys = a_ys; 00469 if(a_pzs!=NULL) *a_pzs = a_zs; 00470 return a_number; 00471 } 00472 } 00473 */