Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

gunu_revolve.cpp

Go to the documentation of this file.
00001 /* LIBGUL - Geometry Utility Library
00002  * Copyright (C) 1998-1999 Norbert Irmer
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Library General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Library General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Library General Public
00015  * License along with this library; if not, write to the
00016  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017  * Boston, MA 02111-1307, USA.
00018  */
00019 
00020 
00021 /************************************************************************
00022   CIRCLE, SURFACES OF REVOLUTION, SPHERE
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   Create a circle as a NURBS curve (see "The NURBS book")                 */
00051 /*------------------------------------------------------------------------*/  
00052 template< class T >
00053 void Circle(
00054             point<T> O,  /* center (origin of local coordinate system) */
00055             point<T> X,  /* X-axis of loc.-coord.-syst., |X| = |Y| = 1 */
00056             point<T> Y,  /* Y-axis of loc.-coord.-syst., perpendicular to X */
00057             T r,           /* radius */
00058             T theta_start, /* start angle (in radians)(in regard to X) */
00059             T theta_end,   /* end angle (in radians)(in regard to X) */
00060             int    *ret_n, /* => number of controlpoints - 1 */
00061             int *ret_p,    /* => degree */
00062             Ptr<T> *retU,             /* => knot vector */
00063             Ptr< hpoint<T> > *retPw   /* => control points */  )  
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;      /* n = number of control points - 1 */
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,  /* center (origin of local coordinate system) */
00169             point<float> X,  /* X-axis of loc.-coord.-syst., |X| = |Y| = 1 */
00170             point<float> Y,  /* Y-axis of loc.-coord.-syst., perpendicular to X */
00171             float r,           /* radius */
00172             float theta_start, /* start angle (in regard to X) */
00173             float theta_end,   /* end angle (in regard to X) */
00174             int    *ret_n, /* => number of controlpoints - 1 */
00175             int *ret_p,    /* => degree */
00176             Ptr<float> *retU,             /* => knot vector */
00177             Ptr< hpoint<float> > *retPw   /* => control points */  );
00178 template  void Circle(
00179             point<double> O,  /* center (origin of local coordinate system) */
00180             point<double> X,  /* X-axis of loc.-coord.-syst., |X| = |Y| = 1 */
00181             point<double> Y,/* Y-axis of loc.-coord.-syst., perpendicular to X*/
00182             double r,           /* radius */
00183             double theta_start, /* start angle (in regard to X) */
00184             double theta_end,   /* end angle (in regard to X) */
00185             int    *ret_n, /* => number of controlpoints - 1 */
00186             int *ret_p,    /* => degree */
00187             Ptr<double> *retU,             /* => knot vector */
00188             Ptr< hpoint<double> > *retPw   /* => control points */  );
00189 
00190 
00191 
00192 /*----------------------------------------------------------------------*//**
00193   Creates a surface of revolution                                          */
00194 /*-------------------------------------------------------------------------*/  
00195 template< class T, class CHP >
00196 void GULAPI Revolution(
00197            point<T> S,  /* point on rotation axis */
00198            point<T> A,  /* direction of axis, |A| = 1 */
00199            T theta,     /* rotation angle (in radians) */
00200            int m,       /* number of control points -1 of rotated curve */
00201            Ptr< CHP >& Pwj,  /* control points of rotated curve */
00202            int *ret_nu, /* number of control points -1  per row of the surface*/
00203            int *ret_pu,  /* degree of surface of revolution (for rows) */
00204            Ptr<T> *retU, /* knotvector of surface of revolution (for rows)*/
00205            Ptr< Ptr< hpoint<T> > >*retPw) /*control points of surface of rev. */
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;              /* number of control points per row */
00221                               /* (rows = circles) */
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 ); /* medium weight for circle segment */
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++ )       /* calc rows */  
00239   {
00240     wj = weight(Pwj[j]);  /* j. control point of curve to P0 */
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];        /* first control point of row */
00253 
00254     T0 = Y;
00255     index = 0;
00256     angle = (T)0;
00257     
00258     for( i = 1; i <= narcs; i++ )  /* remaining  control points of row */     
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   /* --- construct knot vector for rows ---------------------------- */
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,  /* point on rotation axis */
00322         point<float> A,  /* direction of axis, |A| = 1 */
00323         float theta,     /* rotation angle (in radians) */
00324         int m,       /* number of control points -1 of rotated curve */
00325         Ptr< hpoint<float> >& Pwj,   /* control points of rotated curve */
00326         int *ret_nu, /* number of control points -1  per row of the surface*/
00327         int *ret_pu,  /* degree of surface of revolution (for rows) */
00328         Ptr<float> *retU, /* knotvector of surface of revolution (for rows)*/
00329         Ptr< Ptr< hpoint<float> > >*retPw);/*control points of surface of rev.*/
00330 template GULAPI void Revolution(
00331        point<double> S,  /* point on rotation axis */
00332        point<double> A,  /* direction of axis, |A| = 1 */
00333        double theta,     /* rotation angle (in radians) */
00334        int m,       /* number of control points -1 of rotated curve */
00335        Ptr< hpoint<double> >& Pwj,   /* control points of rotated curve */
00336        int *ret_nu, /* number of control points -1  per row of the surface*/
00337        int *ret_pu,  /* degree of surface of revolution (for rows) */
00338        Ptr<double> *retU, /* knotvector of surface of revolution (for rows)*/
00339        Ptr< Ptr< hpoint<double> > >*retPw);/*control points of surface of rev.*/
00340 template GULAPI void Revolution(
00341         point<float> S,  /* point on rotation axis */
00342         point<float> A,  /* direction of axis, |A| = 1 */
00343         float theta,     /* rotation angle (in radians) */
00344         int m,       /* number of control points -1 of rotated curve */
00345         Ptr< point<float> >& Pwj,   /* control points of rotated curve */
00346         int *ret_nu, /* number of control points -1  per row of the surface*/
00347         int *ret_pu,  /* degree of surface of revolution (for rows) */
00348         Ptr<float> *retU, /* knotvector of surface of revolution (for rows)*/
00349         Ptr< Ptr< hpoint<float> > >*retPw);/*control points of surface of rev.*/
00350 template GULAPI void Revolution(
00351        point<double> S,  /* point on rotation axis */
00352        point<double> A,  /* direction of axis, |A| = 1 */
00353        double theta,     /* rotation angle (in radians) */
00354        int m,       /* number of control points -1 of rotated curve */
00355        Ptr< point<double> >& Pwj,   /* control points of rotated curve */
00356        int *ret_nu, /* number of control points -1  per row of the surface*/
00357        int *ret_pu,  /* degree of surface of revolution (for rows) */
00358        Ptr<double> *retU, /* knotvector of surface of revolution (for rows)*/
00359        Ptr< Ptr< hpoint<double> > >*retPw);/*control points of surface of rev.*/
00360 
00361 template GULAPI void Revolution(
00362         point<float> S,  /* point on rotation axis */
00363         point<float> A,  /* direction of axis, |A| = 1 */
00364         float theta,     /* rotation angle (in radians) */
00365         int m,       /* number of control points -1 of rotated curve */
00366         Ptr< hpoint2<float> >& Pwj,   /* control points of rotated curve */
00367         int *ret_nu, /* number of control points -1  per row of the surface*/
00368         int *ret_pu,  /* degree of surface of revolution (for rows) */
00369         Ptr<float> *retU, /* knotvector of surface of revolution (for rows)*/
00370         Ptr< Ptr< hpoint<float> > >*retPw);/*control points of surface of rev.*/
00371 template GULAPI void Revolution(
00372        point<double> S,  /* point on rotation axis */
00373        point<double> A,  /* direction of axis, |A| = 1 */
00374        double theta,     /* rotation angle (in radians) */
00375        int m,       /* number of control points -1 of rotated curve */
00376        Ptr< hpoint2<double> >& Pwj,   /* control points of rotated curve */
00377        int *ret_nu, /* number of control points -1  per row of the surface*/
00378        int *ret_pu,  /* degree of surface of revolution (for rows) */
00379        Ptr<double> *retU, /* knotvector of surface of revolution (for rows)*/
00380        Ptr< Ptr< hpoint<double> > >*retPw);/*control points of surface of rev.*/
00381 template GULAPI void Revolution(
00382         point<float> S,  /* point on rotation axis */
00383         point<float> A,  /* direction of axis, |A| = 1 */
00384         float theta,     /* rotation angle (in radians) */
00385         int m,       /* number of control points -1 of rotated curve */
00386         Ptr< point2<float> >& Pwj,   /* control points of rotated curve */
00387         int *ret_nu, /* number of control points -1  per row of the surface*/
00388         int *ret_pu,  /* degree of surface of revolution (for rows) */
00389         Ptr<float> *retU, /* knotvector of surface of revolution (for rows)*/
00390         Ptr< Ptr< hpoint<float> > >*retPw);/*control points of surface of rev.*/
00391 template GULAPI void Revolution(
00392        point<double> S,  /* point on rotation axis */
00393        point<double> A,  /* direction of axis, |A| = 1 */
00394        double theta,     /* rotation angle (in radians) */
00395        int m,       /* number of control points -1 of rotated curve */
00396        Ptr< point2<double> >& Pwj,   /* control points of rotated curve */
00397        int *ret_nu, /* number of control points -1  per row of the surface*/
00398        int *ret_pu,  /* degree of surface of revolution (for rows) */
00399        Ptr<double> *retU, /* knotvector of surface of revolution (for rows)*/
00400        Ptr< Ptr< hpoint<double> > >*retPw);/*control points of surface of rev.*/
00401 
00402 
00403 
00404 /*-----------------------------------------------------------------------*//**
00405   Creates a unit sphere (centered at origin)                                */
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   /* create rotation surface: */
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 

Generated on Mon Jan 21 04:17:42 2002 for GUL 0.6 - Geometry Utility Library by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001