home *** CD-ROM | disk | FTP | other *** search
- /* ****************************************************************
- * G.c
- * ****************************************************************
- * MODULE PURPOSE:
- * This module contains geometric attenuation
- * functions
- *
- * MODULE CONTENTS:
- * D_torrance - function by Torrance and Sparrow
- * D_Sancer - function by Sancer
- */
- #include <math.h>
- #include "geo.h"
-
- #define ROOT_PI 1.7724538509055159
-
- /* ****************************************************************
- * double G_torrance (N, L, V)
- * DIR_VECT *N, *L, *V (in) - N, L, V vectors
- * double dummy (in) - just to make the
- * calls identical
- *
- * Returns geometric attenuation (Torrance and Sparrow
- * 1967), refer to Eq.(\*(eS). The direction vectors
- * N, V, and L are assumed to be oriented to the same
- * side of the surface.
- */
- double G_torrance (N, L, V, dummy)
- DIR_VECT *N, *L, *V;
- double dummy;
- {
- double N_dot_H, V_dot_H;
- double N_dot_V, N_dot_L;
- double g1, g2;
- DIR_VECT *H;
-
- H = geo_H(V,L);
- N_dot_H = geo_dot (N,H);
- V_dot_H = geo_dot (V,H);
- N_dot_V = geo_dot (N,V);
- N_dot_L = geo_dot (N,L);
-
- if ((g1 = (2.0 * N_dot_H * N_dot_V) /
- V_dot_H) > 1.0) g1 = 1.0;
- if ((g2 = (2.0 * N_dot_H * N_dot_L) /
- V_dot_H) < g1) return g2;
- else return g1;
- }
-
-
-
- /* ****************************************************************
- * double G_sancer (N, L, V, m_2)
- * DIR_VECT *N, *L, *V (in) - N, L, V vectors
- * double m_2 (in) - m squared
- *
- * Returns geometric attenuation (Sancer 1969), refer to Eq.(\*(rT).
- * The direction vectors N, V, and L are assumed to be oriented
- * to the same side of the surface.
- *
- * NOTE:
- * > m can be related to beta using D_cook_init()
- * > This implementation assumes slope relates roughness and
- * correlation distance as described by Beckmann. This
- * explains the missing factor of 2 with m_2 when compared
- * to Eq.(\*(rT).
- */
- double G_sancer (N, L, V, m_2)
- DIR_VECT *N, *L, *V;
- double m_2;
- {
- double N_dot_L, N_dot_V;
- double c1, c2, root_c1, root_c2, ci, cr;
-
- if (m_2 <= 0.0) return 1.0;
- if ((N_dot_L = geo_dot(N,L)) <= 0.0) return 0.0;
- c1 = (N_dot_L * N_dot_L) / (m_2 * (1.0 - (N_dot_L * N_dot_L)));
- root_c1 = sqrt(c1);
- ci = (exp(-c1) /
- (2.0 * ROOT_PI * root_c1)) - (erfc(root_c1) / 2.0);
-
- if ((N_dot_V = geo_dot(N,V)) <= 0.0) return 0.0;
- c2 = (N_dot_V * N_dot_V) / (m_2 * (1.0 - (N_dot_V * N_dot_V)));
- root_c2 = sqrt(c2);
- cr = (exp(-c2) /
- (2.0 * ROOT_PI * root_c2)) - (erfc(root_c2) / 2.0);
-
- return 1.0/(1.0 + ci + cr);
- }
- /* ************************************************************* */
-