⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lambert.c

📁 This is code tutorial for image processing include:histogram,sketon....
💻 C
字号:

       /**********************************************
       *
       *   file lambert.c
       *
       *   Functions: This file contains
       *
       *   Purpose:
       *      These functions perform the lambert
       *      operations.
       *
       *   External Calls:
       *      none
       *
       *   Modifications:
       *      26 November 1999 - created
       *
       ************************************************/
      

       /******************************************
       *
       *   The k constants are for diffuse and
       *   specular reflectivity.  They are 
       *   constants for a surface between 0 and 1.
       *
       *   eta is a factor for the reflectance
       *   of the object.  A large eta is for 
       *   a shiny object that approaches a perfect
       *   mirror.  A small eta is for a dull 
       *   surface.
       *
       ******************************************/

#include "cips.h"

#undef NEVER

#define SOURCE         100
#define AMBIENT        200
#define DEGREESRADIANS 57.29577951
#define NINETYDEGREES  1.570796327
#define ONEEIGHTY      3.141592654


lambert(the_image, out_image,
        k_diffuse, k_specular, eta,
        L,
        rows, cols)

   float  eta, k_diffuse, k_specular, *L;
   short  **the_image,
          **out_image;
   long   cols, rows;
{
   char   response[80];
   float  theta1, theta2, theta3, theta4;
   float  diffuse_term, specular_term;
   float  max_diffuse_term, max_specular_term;
   float  nl, vr;
   float  N[3], R[3], V[3], v1[3], v2[3];
   float  l, n, r, v;
   int    i, j;

   char line[100];
   FILE *log_file;


/****** log file ********************************/
   if((
   log_file = fopen("logfile", "wt")) == NULL){
      printf("\ntoc: Error opening paged file\n");
      exit(4);
   }

   max_diffuse_term  = 0.0;
   max_specular_term = 0.0;


      /******************************************
      *
      *   V, the viewer, is straight up
      *   v1 is the vector down one row
      *   v2 is the vector right one column
      *
      ******************************************/

   V[0] =  0.0;
   V[1] =  0.0;
   V[2] = -1.0;



   for(i=1; i<rows-1; i++){
      for(j=1; j<cols-1; j++){

            /*************************************
            *
            *   Calculate the vector N that is
            *   normal to the triangle whose 
            *   corners are
            *   [i][j]    [i][j+1]
            *   [i+1][j]
            *
            *************************************/

         /*****************
         v1[0] = 0.0;
         v1[1] = 1.0;
         v1[2] = (float)(the_image[i+1][j] - the_image[i][j]);
         v2[0] = 1.0;
         v2[1] = 0.0;
         v2[2] = (float)(the_image[i][j+1] - the_image[i][j]);
         ****************/

         v1[0] = 0.0;
         v1[1] = 1.0;
         v1[2] = (float)(the_image[i][j] - the_image[i+1][j]);
         v2[0] = 1.0;
         v2[1] = 0.0;
         v2[2] = (float)(the_image[i][j] - the_image[i][j+1]);

         cross_product(v1, v2, N);

            /*************************************
            *
            *   Calculate the dot product of 
            *   N and V.  N and V are both unit
            *   vectors (their magnitudes are 1).
            *   The dot product becomes the cosine
            *   of the angle between them.
            *
            *************************************/


            /*************************************
            *
            *   If theta1 > 90 degrees, the
            *   specular term will be zero.
            *   This is because there is no
            *   reflectance.
            *
            *   I am calculating vr the simple 
            *   way so I don't need to find
            *   the values of R(x,y,z).
            *
            *   theta1 = angle between L and N
            *   theta2 = angle between N and V
            *   theta3 = angle between L and V
            *   theta4 = angle between V and R
            *
            *************************************/

         angle_between(L, N, &theta1);
         theta1 = ONEEIGHTY - theta1;
         angle_between(N, V, &theta2);
         angle_between(L, V, &theta3);
         theta3 = ONEEIGHTY - theta3;
         if(theta3 >= theta1)
            theta4 = theta1 - theta2;
         else
            theta4 = theta1 + theta2;

/************************
if( (i%20==0)  && (j%20==0) ){
printf("\ni=%d j=%d t1=%f t2=%f t3=%f t4=%f vector N is",
 i,j,theta1,theta2,theta3,theta4);
print_vector(N);
gets(response);
}
**************************/


         vr = cos(theta4);
         if(vr <= 0.0)
            vr = 0.0;
         vr = pow(vr, eta);
         specular_term = k_specular*vr;

         /****nl = dot_product(N, L);***/
         magnitude_of(N, &n);
         magnitude_of(L, &l);
         /*nl = cos(theta1)*n*l;*/
         nl = cos(theta1);
         diffuse_term = k_diffuse*nl;

            /* If the surface is in the shadow
               of the light, the diffuse and
               specular terms are zero. */
         if(theta1 >= NINETYDEGREES){
/*************
printf("\ntheta1=%5.2f i=%d j=%d and the normal vector is:",theta1,i,j);
print_vector(N);
*************/
            diffuse_term  = 0.0;
            specular_term = 0.0;
         }  /* ends if */


            /* Write to logfile */
         if((i%50) == 0){
         sprintf(line,"\nAMBIENT SOURCE   i   j   vr specterm nl    diffterm  T1  T4");
         fputs(line,log_file);
         sprintf(line,"\n%d      %d     %d  %d %4.2f %5.2f    %4.2f %5.2f  %5.2f  %5.2f",
                 AMBIENT, SOURCE, i, j, vr, specular_term, nl, diffuse_term, theta1, theta4);
         fputs(line,log_file);
         }


         if(specular_term > max_specular_term)
            max_specular_term = specular_term;
         if(diffuse_term > max_diffuse_term)
            max_diffuse_term = diffuse_term;

         out_image[i][j] = k_diffuse*AMBIENT + 
                           SOURCE*(specular_term+diffuse_term);
         if(out_image[i][j] < 0) 
            out_image[i][j] = 0;
         if(out_image[i][j] > GRAY_LEVELS-1)
            out_image[i][j] = GRAY_LEVELS-1;

/*******************
if( i==j && (i%20) == 0 ){
printf("\nPress Enter to continue");
printf("\nAMBIENT=%d SOURCE=%d kdiffuse=%f kspecular=%f",
      AMBIENT,SOURCE,k_diffuse, k_specular);
printf("\nSpecular=%f  Diffuse=%f  (nl=%f) out[%d][%d]=%d",
      specular_term, diffuse_term, nl, i, j, out_image[i][j]);
gets(response);
}
*******************/

/**************************
if( i==j && (i%20) == 0 ){
printf("\ni=%d j=%d image[%d][%d]=%d image[%d][%d]=%d image[%d][%d]=%d",
      i, j, i, j, the_image[i][j], i+1, j, the_image[i+1][j],
      i, j+1, the_image[i][j+1]);
printf("\nv1[2] should be %d-%d=%d, it is %f",
         the_image[i+1][j],the_image[i][j], 
         the_image[i+1][j] - the_image[i][j], v1[2]);
printf("\nv2[2] should be %d-%d=%d, it is %f",
         the_image[i][j+1],the_image[i][j],
         the_image[i][j+1] - the_image[i][j], v2[2]);

printf("\ntheta1=%f theta2=%f theta3=%f",theta1,theta2,theta3);
printf("\nVector v1");
print_vector(v1);
printf("\nVector v2");
print_vector(v2);
printf("\nVector Normal");
print_vector(N);
printf("\nSpecular=%f  Diffuse=%f  out[%d][%d]=%d",
      specular_term, diffuse_term, i, j, out_image[i][j]);
printf("\nPress Enter to continue");
gets(response);
}
********************************/

      }  /* ends loop over j */
   }  /* ends loop over i */


      /* fix the edges of the output image */
   for(i=0; i<rows; i++){
      for(j=1; j>0; j--){
       out_image[i][j-1] = out_image[i][j];
       out_image[i][cols-j] = out_image[i][cols-j-1];
      }
   }

   for(j=0; j<cols; j++){
      for(i=1; i>0; i--){
       out_image[i-1][j] = out_image[i][j];
       out_image[rows-i][j] = out_image[rows-i-1][j];
      }
   }

      /* close the log file */
   fclose(log_file);

printf("\n\nmax_specular=%f    max_diffuse=%f",
max_specular_term, max_diffuse_term);

}  /* ends lambert */





     /*******************************************
     *
     *   magnitude_of(...
     *
     *
     *******************************************/

magnitude_of(v, answer)
   float v[], *answer;
{
   double d, n;
   n  = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
   d  = sqrt(n);
   *answer = d;
}  /* ends dot_product */



     /*******************************************
     *
     *   dot_product(...
     *
     *   The dot product assumes the two
     *   vectors start at the same point.
     *
     *******************************************/

dot_product(v1, v2)
   float v1[], v2[];
{
   float result = 0.0;
   result = v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
   return(result);
}  /* ends dot_product */




     /*******************************************
     *
     *   cross_product(...
     *
     *
     *******************************************/

cross_product(v1, v2, result)
   float v1[], v2[], result[];
{
   result[0] = v1[1]*v2[2] - v2[1]*v1[2];
   result[1] = v1[2]*v2[0] - v2[2]*v1[0];
   result[2] = v1[0]*v2[1] - v2[0]*v1[1];
}  /* ends cross_product */




     /*******************************************
     *
     *   angle_between(...
     *
     *
     *******************************************/

angle_between(v1, v2, angle)
   float *angle, v1[], v2[];
{
   double d, d1, d2, dt, n, result = 0.0, t;
   char   response[80];

/*******************
if(i == 2 && j>127){
   printf("\nangle_between>> i=%d j=%d", i,j);
   print_vector(v1);
   print_vector(v2);
}
printf("\nangle_between>> ");
   printf("\n %f  %f  %f",v1[0],v1[1],v1[2]);
   printf("\n %f  %f  %f",v2[0],v2[1],v2[2]);
*****************/

   n  = v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
   dt = v1[0]*v1[0] + v1[1]*v1[1] + v1[2]*v1[2];
   d1 = sqrt(dt);
   dt = v2[0]*v2[0] + v2[1]*v2[1] + v2[2]*v2[2];
   d2 = sqrt(dt);

   d      = d1*d2;


/**************
if(i == 2 && j>127){
   printf("\n n=%f d1=%f d2=%f d=%f",n,d1,d2,d);
}
if(d < 0.1){
   printf("\nd1=%f d2=%f",d1,d2);
   print_vector(v1);
   print_vector(v2);
   gets(response);
}
*****************/

   t      = n/d;
   if(t <= -1.0) t = -0.999;
   if(t >   1.0) t =  1.0;
   result = acos(t);
   *angle = result;
/**************
   printf("\nangle_between>> result=%f",result);
**************/

}  /* ends angle_between */





print_vector(x)
   float *x;
{
   printf("\n %f  %f  %f",x[0],x[1],x[2]);
}  /* ends print_vector */



#ifdef NEVER


   /* test dot product */
   float result = 0;
   L[0] = 1.0;
   L[1] = 2.0;
   L[2] = 3.0;
   N[0] = 4.0;
   N[1] = 5.0;
   N[2] = 6.0;
   print_vector(L);
   print_vector(N);
   result = dot_product(L, N);
printf("\nresult is %f",result);
   /* ends test dot product */



   /* test cross product */
   float result = 0;
   L[0] = 0.0;
   L[1] = 1.0;
   L[2] =-2.0;
   N[0] = 1.0;
   N[1] = 0.0;
   N[2] = 9.0;
   print_vector(L);
   print_vector(N);
   cross_product(L, N, V);
   print_vector(V);
   /* ends test cross product */


   /* test angle between */
   double result = 0.0;
   L[0] = 0.0;
   L[1] = 1.0;
   L[2] = 0.0;
   N[0] = 1.0;
   N[1] = 1.0;
   N[2] = 0.0;
   print_vector(L);
   print_vector(N);
   angle_between(1, 1, L, N, &vr);
   printf("\nthe angle between is %f", vr);
   /* ends test angle between */


   /* test magnitude of */
   float result = 0.0;
   L[0] = 0.0;
   L[1] = 1.0;
   L[2] = 0.0;
   print_vector(L);
   result = magnitude_of(L);
   printf("\nthe magnitude is %f", result);
   /* ends test magnitude of */

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -