nurb_c2.c

Go to the documentation of this file.
00001 /*                       N U R B _ C 2 . C
00002  * BRL-CAD
00003  *
00004  * Copyright (c) 1990-2006 United States Government as represented by
00005  * the U.S. Army Research Laboratory.
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License
00009  * as published by the Free Software Foundation; either version 2 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Library General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this file; see the file named COPYING for more
00019  * information.
00020  */
00021 
00022 /** @addtogroup nurb */
00023 /*@{*/
00024 /** @file nurb_c2.c
00025  *      Given parametric u,v values, return the curvature of the
00026  *      surface.
00027  *
00028  *  Author -
00029  *      Paul Randal Stay
00030  *
00031  *  Source -
00032  *      SECAD/VLD Computing Consortium, Bldg 394
00033  *      The U.S. Army Ballistic Research Laboratory
00034  *      Aberdeen Proving Ground, Maryland 21005
00035  *
00036  */
00037 /*@}*/
00038 
00039 #include "common.h"
00040 
00041 
00042 
00043 #include <stdio.h>
00044 #include <math.h>
00045 
00046 #include "machine.h"
00047 #include "vmath.h"
00048 #include "raytrace.h"
00049 #include "nurb.h"
00050 
00051 void
00052 rt_nurb_curvature(struct curvature *cvp, const struct face_g_snurb *srf, fastf_t u, fastf_t v)
00053 {
00054         struct face_g_snurb * us, *vs, * uus, * vvs, *uvs;
00055         fastf_t ue[4], ve[4], uue[4], vve[4], uve[4], se[4];
00056         fastf_t         E, F, G;                /* First Fundamental Form */
00057         fastf_t         L, M, N;                /* Second Fundamental form */
00058         fastf_t         denom;
00059         fastf_t         wein[4];                /*Weingarten matrix */
00060         fastf_t         evec[3];
00061         fastf_t         mean, gauss, discrim;
00062         vect_t          norm;
00063         int             i;
00064 
00065         us = rt_nurb_s_diff(srf, RT_NURB_SPLIT_ROW);
00066         vs = rt_nurb_s_diff(srf, RT_NURB_SPLIT_COL);
00067         uus = rt_nurb_s_diff(us, RT_NURB_SPLIT_ROW);
00068         vvs = rt_nurb_s_diff(vs, RT_NURB_SPLIT_COL);
00069         uvs = rt_nurb_s_diff(vs, RT_NURB_SPLIT_ROW);
00070 
00071         rt_nurb_s_eval(srf, u, v, se);
00072         rt_nurb_s_eval(us, u,v, ue);
00073         rt_nurb_s_eval(vs, u,v, ve);
00074         rt_nurb_s_eval(uus, u,v, uue);
00075         rt_nurb_s_eval(vvs, u,v, vve);
00076         rt_nurb_s_eval(uvs, u,v, uve);
00077 
00078         rt_nurb_free_snurb( us, (struct resource *)NULL);
00079         rt_nurb_free_snurb( vs, (struct resource *)NULL);
00080         rt_nurb_free_snurb( uus, (struct resource *)NULL);
00081         rt_nurb_free_snurb( vvs, (struct resource *)NULL);
00082         rt_nurb_free_snurb( uvs, (struct resource *)NULL);
00083 
00084         if( RT_NURB_IS_PT_RATIONAL( srf->pt_type ))
00085         {
00086                 for( i = 0; i < 3; i++)
00087                 {
00088                         ue[i] = (1.0 / se[3] * ue[i]) -
00089                                 (ue[3]/se[3]) * se[0]/se[3];
00090                         ve[i] = (1.0 / se[3] * ve[i]) -
00091                                 (ve[3]/se[3]) * se[0]/se[3];
00092                 }
00093                 VCROSS(norm, ue, ve);
00094                 VUNITIZE(norm);
00095                 E = VDOT( ue, ue);
00096                 F = VDOT( ue, ve);
00097                 G = VDOT( ve, ve);
00098 
00099                 for( i = 0; i < 3; i++)
00100                 {
00101                         uue[i] = (1.0 / se[3] * uue[i]) -
00102                                 2 * (uue[3]/se[3]) * uue[i] -
00103                                 uue[3]/se[3] * (se[i]/se[3]);
00104 
00105                         vve[i] = (1.0 / se[3] * vve[i]) -
00106                                 2 * (vve[3]/se[3]) * vve[i] -
00107                                 vve[3]/se[3] * (se[i]/se[3]);
00108 
00109                          uve[i] = 1.0 / se[3] * uve[i] +
00110                                 (-1.0 / (se[3] * se[3])) *
00111                                 (ve[3] * ue[i] + ue[3] * ve[i] +
00112                                  uve[3] * se[i]) +
00113                                 (-2.0 / (se[3] * se[3] * se[3])) *
00114                                 (ve[3] * ue[3] * se[i]);
00115                 }
00116 
00117                 L = VDOT( norm, uue);
00118                 M = VDOT( norm, uve);
00119                 N = VDOT( norm, vve);
00120 
00121         } else
00122         {
00123                 VCROSS( norm, ue, ve);
00124                 VUNITIZE( norm );
00125                 E = VDOT( ue, ue);
00126                 F = VDOT( ue, ve);
00127                 G = VDOT( ve, ve);
00128 
00129                 L = VDOT( norm, uue);
00130                 M = VDOT( norm, uve);
00131                 N = VDOT( norm, vve);
00132         }
00133 
00134         if( srf->order[0] <= 2 && srf->order[1] <= 2)
00135         {
00136                 cvp->crv_c1 = cvp->crv_c2 = 0;
00137                 bn_vec_ortho(cvp->crv_pdir, norm);
00138                 return;
00139         }
00140 
00141         denom = ( (E*G) - (F*F) );
00142         gauss = (L * N - M *M)/denom;
00143         mean = (G * L + E * N - 2 * F * M) / (2 * denom);
00144         discrim = sqrt( mean * mean - gauss);
00145 
00146         cvp->crv_c1 = mean - discrim;
00147         cvp->crv_c2 = mean + discrim;
00148 
00149         if( fabs( E*G - F*F) < 0.0001 )         /* XXX */
00150         {
00151                 bu_log("rt_nurb_curvature: first fundamental form is singular E = %g F= %g G = %g\n",
00152                         E,F,G);
00153                 bn_vec_ortho(cvp->crv_pdir, norm);      /* sanity */
00154                 return;
00155         }
00156 
00157         wein[0] = ( (G * L) - (F * M))/ (denom);
00158         wein[1] = ( (G * M) - (F * N))/ (denom);
00159         wein[2] = ( (E * M) - (F * L))/ (denom);
00160         wein[3] = ( (E * N) - (F * M))/ (denom);
00161 
00162         if( fabs(wein[1]) < 0.0001 && fabs( wein[3] - cvp->crv_c1 ) < 0.0001 )
00163         {
00164                 evec[0] = 0.0; evec[1] = 1.0;
00165         } else
00166         {
00167                 evec[0] = 1.0;
00168                 if( fabs( wein[1] ) > fabs( wein[3] - cvp->crv_c1) )
00169                 {
00170                         evec[1] = (cvp->crv_c1 - wein[0]) / wein[1];
00171                 } else
00172                 {
00173                         evec[1] = wein[2] / ( cvp->crv_c1 - wein[3] );
00174                 }
00175         }
00176 
00177         cvp->crv_pdir[0] = evec[0] * ue[0] + evec[1] * ve[0];
00178         cvp->crv_pdir[1] = evec[0] * ue[1] + evec[1] * ve[1];
00179         cvp->crv_pdir[2] = evec[0] * ue[2] + evec[1] * ve[2];
00180         VUNITIZE( cvp->crv_pdir);
00181 }
00182 
00183 /*
00184  * Local Variables:
00185  * mode: C
00186  * tab-width: 8
00187  * c-basic-offset: 4
00188  * indent-tabs-mode: t
00189  * End:
00190  * ex: shiftwidth=4 tabstop=8
00191  */

Generated on Mon Sep 18 01:24:55 2006 for BRL-CAD by  doxygen 1.4.6