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 #include "stdafx.h"
00026
00027 #include <iostream>
00028
00029 #include "gul_types.h"
00030 #include "gul_vector.h"
00031 #include "guma_lineq.h"
00032 #include "gunu_revolve.h"
00033
00034 namespace gunu {
00035
00036 using gul::Ptr;
00037 using gul::rtr;
00038 using gul::point;
00039 using gul::hpoint;
00040 using gul::point2;
00041 using gul::hpoint2;
00042 using gul::ProjectToLine;
00043 using guma::SVDIntersectLines;
00044 using gul::weight;
00045 using gul::euclid;
00046 using gul::normalize;
00047 using gul::cross_product;
00048
00049
00050
00051
00052 template< class T >
00053 void Circle(
00054 point<T> O,
00055 point<T> X,
00056 point<T> Y,
00057 T r,
00058 T theta_start,
00059 T theta_end,
00060 int *ret_n,
00061 int *ret_p,
00062 Ptr<T> *retU,
00063 Ptr< hpoint<T> > *retPw )
00064 {
00065 Ptr< hpoint<T> > Pw;
00066 point<T> P0, T0, P1, P2, T2;
00067 T ths,the,theta,dtheta, w1, angle, dummy;
00068 Ptr<T> U;
00069 int narcs, n, index, i, j;
00070
00071 ths = theta_start;
00072 the = theta_end;
00073
00074 if( the < ths ) the += rtr<T>::pi() * (T)2;
00075
00076 theta = the - ths;
00077
00078 if( theta <= rtr<T>::pi() / (T)2 ) narcs = 1;
00079 else if( theta <= rtr<T>::pi() ) narcs = 2;
00080 else if( theta <= (T)1.5 * rtr<T>::pi() ) narcs = 3;
00081 else narcs = 4;
00082
00083 dtheta = theta / ((T)narcs);
00084
00085 n = 2 * narcs;
00086
00087 Pw.reserve_pool(n+1);
00088 U.reserve_pool(n+4);
00089
00090 w1 = rtr<T>::cos( dtheta/(T)2 );
00091
00092 P0.x = O.x + r*rtr<T>::cos(ths)*X.x + r*rtr<T>::sin(ths)*Y.x;
00093 P0.y = O.y + r*rtr<T>::cos(ths)*X.y + r*rtr<T>::sin(ths)*Y.y;
00094 P0.z = O.z + r*rtr<T>::cos(ths)*X.z + r*rtr<T>::sin(ths)*Y.z;
00095
00096 T0.x = -rtr<T>::sin(ths)*X.x + rtr<T>::cos(ths)*Y.x;
00097 T0.y = -rtr<T>::sin(ths)*X.y + rtr<T>::cos(ths)*Y.y;
00098 T0.z = -rtr<T>::sin(ths)*X.z + rtr<T>::cos(ths)*Y.z;
00099
00100 Pw[0].x = P0.x;
00101 Pw[0].y = P0.y;
00102 Pw[0].z = P0.z;
00103 Pw[0].w = (T)1;
00104
00105 index = 0;
00106 angle = ths;
00107
00108 for( i = 1; i <= narcs; i++ )
00109 {
00110 angle += dtheta;
00111
00112 P2.x = O.x + r*rtr<T>::cos(angle)*X.x + r*rtr<T>::sin(angle)*Y.x;
00113 P2.y = O.y + r*rtr<T>::cos(angle)*X.y + r*rtr<T>::sin(angle)*Y.y;
00114 P2.z = O.z + r*rtr<T>::cos(angle)*X.z + r*rtr<T>::sin(angle)*Y.z;
00115
00116 Pw[index+2].x = P2.x;
00117 Pw[index+2].y = P2.y;
00118 Pw[index+2].z = P2.z;
00119 Pw[index+2].w = (T)1;
00120
00121 T2.x = -rtr<T>::sin(angle)*X.x + rtr<T>::cos(angle)*Y.x;
00122 T2.y = -rtr<T>::sin(angle)*X.y + rtr<T>::cos(angle)*Y.y;
00123 T2.z = -rtr<T>::sin(angle)*X.z + rtr<T>::cos(angle)*Y.z;
00124
00125 SVDIntersectLines( P0, T0, P2, T2, &dummy, &dummy, &P1 );
00126
00127 Pw[index+1].x = w1 * P1.x;
00128 Pw[index+1].y = w1 * P1.y;
00129 Pw[index+1].z = w1 * P1.z;
00130 Pw[index+1].w = w1;
00131
00132 index += 2;
00133
00134 if( i < narcs )
00135 {
00136 P0 = P2;
00137 T0 = T2;
00138 }
00139 }
00140 j = 2 * narcs + 1;
00141
00142 for( i = 0; i < 3; i++ )
00143 {
00144 U[i] = (T)0;
00145 U[i+j] = (T)1;
00146 }
00147 switch( narcs )
00148 {
00149 case 2:
00150 U[3] = U[4] = (T)0.5;
00151 break;
00152 case 3:
00153 U[3] = U[4] = (T)1 / (T)3;
00154 U[5] = U[6] = (T)2 / (T)3;
00155 break;
00156 case 4:
00157 U[3] = U[4] = (T)0.25;
00158 U[5] = U[6] = (T)0.5;
00159 U[7] = U[8] = (T)0.75;
00160 break;
00161 }
00162 *ret_n = n;
00163 *ret_p = 2;
00164 *retPw = Pw;
00165 *retU = U;
00166 }
00167 template void Circle(
00168 point<float> O,
00169 point<float> X,
00170 point<float> Y,
00171 float r,
00172 float theta_start,
00173 float theta_end,
00174 int *ret_n,
00175 int *ret_p,
00176 Ptr<float> *retU,
00177 Ptr< hpoint<float> > *retPw );
00178 template void Circle(
00179 point<double> O,
00180 point<double> X,
00181 point<double> Y,
00182 double r,
00183 double theta_start,
00184 double theta_end,
00185 int *ret_n,
00186 int *ret_p,
00187 Ptr<double> *retU,
00188 Ptr< hpoint<double> > *retPw );
00189
00190
00191
00192
00193
00194
00195 template< class T, class CHP >
00196 void GULAPI Revolution(
00197 point<T> S,
00198 point<T> A,
00199 T theta,
00200 int m,
00201 Ptr< CHP >& Pwj,
00202 int *ret_nu,
00203 int *ret_pu,
00204 Ptr<T> *retU,
00205 Ptr< Ptr< hpoint<T> > >*retPw)
00206 {
00207 Ptr<T> U;
00208 T dtheta, wm, wj, angle, sines[5], cosines[5], r, dummy;
00209 int narcs, i, j, n, index;
00210 point<T> P0, T0, P1, P2, T2, X, Y, O;
00211 Ptr< Ptr< hpoint<T> > > Pwij;
00212
00213 if( theta <= rtr<T>::pi() / 2.0 ) narcs = 1;
00214 else if( theta <= rtr<T>::pi() ) narcs = 2;
00215 else if( theta <= (T)1.5 * rtr<T>::pi() ) narcs = 3;
00216 else narcs = 4;
00217
00218 dtheta = theta / ((T)narcs);
00219
00220 n = 2 * narcs;
00221
00222 U.reserve_pool(n+4);
00223
00224 Pwij.reserve_pool(m+1);
00225 for( i = 0; i <= m; i++ )
00226 Pwij[i].reserve_pool(n+1);
00227
00228 wm = rtr<T>::cos( dtheta / (T)2 );
00229
00230 angle = (T)0;
00231
00232 for( i = 1; i <= narcs; i++ )
00233 {
00234 angle += dtheta;
00235 cosines[i] = rtr<T>::cos(angle);
00236 sines[i] = rtr<T>::sin(angle);
00237 }
00238 for( j = 0; j <= m; j++ )
00239 {
00240 wj = weight(Pwj[j]);
00241 P0 = euclid(Pwj[j]);
00242
00243 O = ProjectToLine( S, A, P0 );
00244
00245 X.x = P0.x - O.x;
00246 X.y = P0.y - O.y;
00247 X.z = P0.z - O.z;
00248
00249 r = normalize( &X, X );
00250 Y = cross_product( A, X );
00251
00252 Pwij[j][0] = Pwj[j];
00253
00254 T0 = Y;
00255 index = 0;
00256 angle = (T)0;
00257
00258 for( i = 1; i <= narcs; i++ )
00259 {
00260 P2.x = O.x + r*cosines[i]*X.x + r*sines[i]*Y.x;
00261 P2.y = O.y + r*cosines[i]*X.y + r*sines[i]*Y.y;
00262 P2.z = O.z + r*cosines[i]*X.z + r*sines[i]*Y.z;
00263
00264 Pwij[j][index+2].x = wj * P2.x;
00265 Pwij[j][index+2].y = wj * P2.y;
00266 Pwij[j][index+2].z = wj * P2.z;
00267 Pwij[j][index+2].w = wj;
00268
00269 T2.x = -sines[i]*X.x + cosines[i]*Y.x;
00270 T2.y = -sines[i]*X.y + cosines[i]*Y.y;
00271 T2.z = -sines[i]*X.z + cosines[i]*Y.z;
00272
00273 SVDIntersectLines( P0, T0, P2, T2, &dummy, &dummy, &P1 );
00274
00275 Pwij[j][index+1].x = wm*wj*P1.x;
00276 Pwij[j][index+1].y = wm*wj*P1.y;
00277 Pwij[j][index+1].z = wm*wj*P1.z;
00278 Pwij[j][index+1].w = wm*wj;
00279
00280 index += 2;
00281
00282 if( i < narcs )
00283 {
00284 P0 = P2;
00285 T0 = T2;
00286 }
00287 }
00288 }
00289
00290
00291 j = 2 * narcs + 1;
00292
00293 for( i = 0; i < 3; i++ )
00294 {
00295 U[i] = (T)0;
00296 U[i+j] = (T)1;
00297 }
00298 switch( narcs )
00299 {
00300 case 2:
00301 U[3] = U[4] = (T)0.5;
00302 break;
00303
00304 case 3:
00305 U[3] = U[4] = (T)1 / (T)3;
00306 U[5] = U[6] = (T)2 / (T)3;
00307 break;
00308
00309 case 4:
00310 U[3] = U[4] = (T)0.25;
00311 U[5] = U[6] = (T)0.5;
00312 U[7] = U[8] = (T)0.75;
00313 break;
00314 }
00315 *ret_nu = n;
00316 *ret_pu = 2;
00317 *retU = U;
00318 *retPw = Pwij;
00319 }
00320 template GULAPI void Revolution(
00321 point<float> S,
00322 point<float> A,
00323 float theta,
00324 int m,
00325 Ptr< hpoint<float> >& Pwj,
00326 int *ret_nu,
00327 int *ret_pu,
00328 Ptr<float> *retU,
00329 Ptr< Ptr< hpoint<float> > >*retPw);
00330 template GULAPI void Revolution(
00331 point<double> S,
00332 point<double> A,
00333 double theta,
00334 int m,
00335 Ptr< hpoint<double> >& Pwj,
00336 int *ret_nu,
00337 int *ret_pu,
00338 Ptr<double> *retU,
00339 Ptr< Ptr< hpoint<double> > >*retPw);
00340 template GULAPI void Revolution(
00341 point<float> S,
00342 point<float> A,
00343 float theta,
00344 int m,
00345 Ptr< point<float> >& Pwj,
00346 int *ret_nu,
00347 int *ret_pu,
00348 Ptr<float> *retU,
00349 Ptr< Ptr< hpoint<float> > >*retPw);
00350 template GULAPI void Revolution(
00351 point<double> S,
00352 point<double> A,
00353 double theta,
00354 int m,
00355 Ptr< point<double> >& Pwj,
00356 int *ret_nu,
00357 int *ret_pu,
00358 Ptr<double> *retU,
00359 Ptr< Ptr< hpoint<double> > >*retPw);
00360
00361 template GULAPI void Revolution(
00362 point<float> S,
00363 point<float> A,
00364 float theta,
00365 int m,
00366 Ptr< hpoint2<float> >& Pwj,
00367 int *ret_nu,
00368 int *ret_pu,
00369 Ptr<float> *retU,
00370 Ptr< Ptr< hpoint<float> > >*retPw);
00371 template GULAPI void Revolution(
00372 point<double> S,
00373 point<double> A,
00374 double theta,
00375 int m,
00376 Ptr< hpoint2<double> >& Pwj,
00377 int *ret_nu,
00378 int *ret_pu,
00379 Ptr<double> *retU,
00380 Ptr< Ptr< hpoint<double> > >*retPw);
00381 template GULAPI void Revolution(
00382 point<float> S,
00383 point<float> A,
00384 float theta,
00385 int m,
00386 Ptr< point2<float> >& Pwj,
00387 int *ret_nu,
00388 int *ret_pu,
00389 Ptr<float> *retU,
00390 Ptr< Ptr< hpoint<float> > >*retPw);
00391 template GULAPI void Revolution(
00392 point<double> S,
00393 point<double> A,
00394 double theta,
00395 int m,
00396 Ptr< point2<double> >& Pwj,
00397 int *ret_nu,
00398 int *ret_pu,
00399 Ptr<double> *retU,
00400 Ptr< Ptr< hpoint<double> > >*retPw);
00401
00402
00403
00404
00405
00406
00407 template< class T >
00408 GULAPI void UnitSphere(
00409 int *ret_nu, int *ret_pu, Ptr<T> *retU,
00410 int *ret_nv, int *ret_pv, Ptr<T> *retV,
00411 Ptr< Ptr< hpoint<T> > > *retPw )
00412 {
00413 point<T> O,X,Y,S,A;
00414 T r;
00415 Ptr<T> U,V;
00416 Ptr< hpoint<T> > Cw;
00417 Ptr< Ptr< hpoint<T> > > Pw;
00418 int nu,nv,pu,pv;
00419
00420 O.x = (T)0.0; O.y = (T)0.0; O.z = (T)0.0;
00421 Y.x = (T)0.0; Y.y = (T)1.0; Y.z = (T)0.0;
00422 X.x = (T)1.0; X.y = (T)0.0; X.z = (T)0.0;
00423 r = (T)1.0;
00424
00425 Circle( O, X, Y, r, (T)0, rtr<T>::pi(), &nv, &pv, &V, &Cw );
00426
00427
00428 S.x = (T)0.0; S.y = (T)0.0; S.z = (T)0.0;
00429 A.x = (T)1.0; A.y = (T)0.0; A.z = (T)0.0;
00430
00431 Revolution( S, A, (T)2*rtr<T>::pi(), nv, Cw, &nu, &pu, &U, &Pw );
00432
00433 *ret_nu = nu;
00434 *ret_pu = pu;
00435 *retU = U;
00436 *ret_nv = nv;
00437 *ret_pv = pv;
00438 *retV = V;
00439 *retPw = Pw;
00440 }
00441 template GULAPI void UnitSphere(
00442 int *ret_nu, int *ret_pu, Ptr<float> *retU,
00443 int *ret_nv, int *ret_pv, Ptr<float> *retV,
00444 Ptr< Ptr< hpoint<float> > > *retPw );
00445 template GULAPI void UnitSphere(
00446 int *ret_nu, int *ret_pu, Ptr<double> *retU,
00447 int *ret_nv, int *ret_pv, Ptr<double> *retV,
00448 Ptr< Ptr< hpoint<double> > > *retPw );
00449
00450 }
00451
00452