home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Raytrace & Morphing / SOS-RAYTRACE.ISO / programm / source / radsrc22 / src / gen / gensky.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-23  |  6.6 KB  |  277 lines

  1. /* Copyright (c) 1986 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)gensky.c 2.8 10/23/92 LBL";
  5. #endif
  6.  
  7. /*
  8.  *  gensky.c - program to generate sky functions.
  9.  *        Our zenith is along the Z-axis, the X-axis
  10.  *        points east, and the Y-axis points north.
  11.  *        Radiance is in watts/steradian/sq. meter.
  12.  *
  13.  *     3/26/86
  14.  */
  15.  
  16. #include  <stdio.h>
  17.  
  18. #include  <math.h>
  19.  
  20. #include  "color.h"
  21.  
  22. #ifndef atof
  23. extern double  atof();
  24. #endif
  25. extern char  *strcpy(), *strcat(), *malloc();
  26. extern double  stadj(), sdec(), sazi(), salt();
  27.  
  28. #define  PI        3.141592654
  29.  
  30. #define  DOT(v1,v2)    (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2])
  31.  
  32. double  normsc();
  33.                     /* sun calculation constants */
  34. extern double  s_latitude;
  35. extern double  s_longitude;
  36. extern double  s_meridian;
  37.                     /* required values */
  38. int  month, day;                /* date */
  39. double  hour;                    /* time */
  40. int  tsolar;                    /* 0=standard, 1=solar */
  41. double  altitude, azimuth;            /* or solar angles */
  42.                     /* default values */
  43. int  cloudy = 0;                /* 1=standard, 2=uniform */
  44. int  dosun = 1;
  45. double  zenithbr = -1.0;
  46. double  turbidity = 2.75;
  47. double  gprefl = 0.2;
  48.                     /* computed values */
  49. double  sundir[3];
  50. double  groundbr;
  51. double  F2;
  52. double  solarbr = -1.0;
  53.  
  54. char  *progname;
  55. char  errmsg[128];
  56.  
  57.  
  58. main(argc, argv)
  59. int  argc;
  60. char  *argv[];
  61. {
  62.     int  i;
  63.  
  64.     progname = argv[0];
  65.     if (argc == 2 && !strcmp(argv[1], "-defaults")) {
  66.         printdefaults();
  67.         exit(0);
  68.     }
  69.     if (argc < 4)
  70.         userror("arg count");
  71.     if (!strcmp(argv[1], "-ang")) {
  72.         altitude = atof(argv[2]) * (PI/180);
  73.         azimuth = atof(argv[3]) * (PI/180);
  74.         month = 0;
  75.     } else {
  76.         month = atoi(argv[1]);
  77.         if (month < 1 || month > 12)
  78.             userror("bad month");
  79.         day = atoi(argv[2]);
  80.         if (day < 1 || day > 31)
  81.             userror("bad day");
  82.         hour = atof(argv[3]);
  83.         if (hour < 0 || hour >= 24)
  84.             userror("bad hour");
  85.         tsolar = argv[3][0] == '+';
  86.     }
  87.     for (i = 4; i < argc; i++)
  88.         if (argv[i][0] == '-' || argv[i][0] == '+')
  89.             switch (argv[i][1]) {
  90.             case 's':
  91.                 cloudy = 0;
  92.                 dosun = argv[i][0] == '+';
  93.                 break;
  94.             case 'r':
  95.                 solarbr = atof(argv[++i]);
  96.                 break;
  97.             case 'c':
  98.                 cloudy = argv[i][0] == '+' ? 2 : 1;
  99.                 dosun = 0;
  100.                 break;
  101.             case 't':
  102.                 turbidity = atof(argv[++i]);
  103.                 break;
  104.             case 'b':
  105.                 zenithbr = atof(argv[++i]);
  106.                 break;
  107.             case 'g':
  108.                 gprefl = atof(argv[++i]);
  109.                 break;
  110.             case 'a':
  111.                 s_latitude = atof(argv[++i]) * (PI/180);
  112.                 break;
  113.             case 'o':
  114.                 s_longitude = atof(argv[++i]) * (PI/180);
  115.                 break;
  116.             case 'm':
  117.                 s_meridian = atof(argv[++i]) * (PI/180);
  118.                 break;
  119.             default:
  120.                 sprintf(errmsg, "unknown option: %s", argv[i]);
  121.                 userror(errmsg);
  122.             }
  123.         else
  124.             userror("bad option");
  125.  
  126.     if (fabs(s_meridian-s_longitude) > 30*PI/180)
  127.         fprintf(stderr,
  128.     "%s: warning: %.1f hours btwn. standard meridian and longitude\n",
  129.             progname, (s_longitude-s_meridian)*12/PI);
  130.  
  131.     printhead(argc, argv);
  132.  
  133.     computesky();
  134.     printsky();
  135. }
  136.  
  137.  
  138. computesky()            /* compute sky parameters */
  139. {
  140.                     /* compute solar direction */
  141.     if (month) {            /* from date and time */
  142.         int  jd;
  143.         double  sd, st;
  144.  
  145.         jd = jdate(month, day);        /* Julian date */
  146.         sd = sdec(jd);            /* solar declination */
  147.         if (tsolar)            /* solar time */
  148.             st = hour;
  149.         else
  150.             st = hour + stadj(jd);
  151.         altitude = salt(sd, st);
  152.         azimuth = sazi(sd, st);
  153.     }
  154.     sundir[0] = -sin(azimuth)*cos(altitude);
  155.     sundir[1] = -cos(azimuth)*cos(altitude);
  156.     sundir[2] = sin(altitude);
  157.  
  158.                     /* Compute zenith brightness */
  159.     if (zenithbr <= 0.0)
  160.         if (cloudy) {
  161.             zenithbr = 8.6*sundir[2] + .123;
  162.             zenithbr *= 1000.0/WHTEFFICACY;
  163.         } else {
  164.             zenithbr = (1.376*turbidity-1.81)*tan(altitude)+0.38;
  165.             zenithbr *= 1000.0/SKYEFFICACY;
  166.         }
  167.     if (zenithbr < 0.0)
  168.         zenithbr = 0.0;
  169.                     /* Compute horizontal radiance */
  170.     if (cloudy) {
  171.         if (cloudy == 2)
  172.             groundbr = zenithbr;
  173.         else
  174.             groundbr = zenithbr*0.777778;
  175.         printf("# Ground ambient level: %f\n", groundbr);
  176.     } else {
  177.         F2 = 0.274*(0.91 + 10.0*exp(-3.0*(PI/2.0-altitude)) +
  178.                 0.45*sundir[2]*sundir[2]);
  179.         groundbr = zenithbr*normsc(altitude)/F2/PI;
  180.         printf("# Ground ambient level: %f\n", groundbr);
  181.         if (sundir[2] > 0.0 && solarbr != 0.0) {
  182.             if (solarbr < 0.0)
  183.                 solarbr = 1.5e9/SUNEFFICACY *
  184.                 (1.147 - .147/(sundir[2]>.16?sundir[2]:.16));
  185.             groundbr += solarbr*6e-5*sundir[2]/PI;
  186.         } else
  187.             dosun = 0;
  188.     }
  189.     groundbr *= gprefl;
  190. }
  191.  
  192.  
  193. printsky()            /* print out sky */
  194. {
  195.     if (dosun) {
  196.         printf("\nvoid light solar\n");
  197.         printf("0\n0\n");
  198.         printf("3 %.2e %.2e %.2e\n", solarbr, solarbr, solarbr);
  199.         printf("\nsolar source sun\n");
  200.         printf("0\n0\n");
  201.         printf("4 %f %f %f 0.5\n", sundir[0], sundir[1], sundir[2]);
  202.     }
  203.     
  204.     printf("\nvoid brightfunc skyfunc\n");
  205.     printf("2 skybright skybright.cal\n");
  206.     printf("0\n");
  207.     if (cloudy)
  208.         printf("3 %d %.2e %.2e\n", cloudy, zenithbr, groundbr);
  209.     else
  210.         printf("7 -1 %.2e %.2e %.2e %f %f %f\n", zenithbr, groundbr,
  211.                 F2, sundir[0], sundir[1], sundir[2]);
  212. }
  213.  
  214.  
  215. printdefaults()            /* print default values */
  216. {
  217.     if (cloudy == 1)
  218.         printf("-c\t\t\t\t# Cloudy sky\n");
  219.     else if (cloudy == 2)
  220.         printf("+c\t\t\t\t# Uniform cloudy sky\n");
  221.     else if (dosun)
  222.         printf("+s\t\t\t\t# Sunny sky with sun\n");
  223.     else
  224.         printf("-s\t\t\t\t# Sunny sky without sun\n");
  225.     printf("-g %f\t\t\t# Ground plane reflectance\n", gprefl);
  226.     if (zenithbr > 0.0)
  227.         printf("-b %f\t\t\t# Zenith radiance (watts/ster/m2\n", zenithbr);
  228.     else
  229.         printf("-t %f\t\t\t# Atmospheric turbidity\n", turbidity);
  230.     printf("-a %f\t\t\t# Site latitude (degrees)\n", s_latitude*(180/PI));
  231.     printf("-o %f\t\t\t# Site longitude (degrees)\n", s_longitude*(180/PI));
  232.     printf("-m %f\t\t\t# Standard meridian (degrees)\n", s_meridian*(180/PI));
  233. }
  234.  
  235.  
  236. userror(msg)            /* print usage error and quit */
  237. char  *msg;
  238. {
  239.     if (msg != NULL)
  240.         fprintf(stderr, "%s: Use error - %s\n", progname, msg);
  241.     fprintf(stderr, "Usage: %s month day hour [options]\n", progname);
  242.     fprintf(stderr, "   Or: %s -ang altitude azimuth [options]\n", progname);
  243.     fprintf(stderr, "   Or: %s -defaults\n", progname);
  244.     exit(1);
  245. }
  246.  
  247.  
  248. double
  249. normsc(theta)            /* compute normalization factor (E0*F2/L0) */
  250. double  theta;
  251. {
  252.     static double  nf[5] = {2.766521, 0.547665,
  253.                 -0.369832, 0.009237, 0.059229};
  254.     double  x, nsc;
  255.     register int  i;
  256.                     /* polynomial approximation */
  257.     x = (theta - PI/4.0)/(PI/4.0);
  258.     nsc = nf[4];
  259.     for (i = 3; i >= 0; i--)
  260.         nsc = nsc*x + nf[i];
  261.  
  262.     return(nsc);
  263. }
  264.  
  265.  
  266. printhead(ac, av)        /* print command header */
  267. register int  ac;
  268. register char  **av;
  269. {
  270.     putchar('#');
  271.     while (ac--) {
  272.         putchar(' ');
  273.         fputs(*av++, stdout);
  274.     }
  275.     putchar('\n');
  276. }
  277.