home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 8 / CDASC08.ISO / NEWS / RADIANCE / SRC / CV / LAMPCOLO.C < prev    next >
C/C++ Source or Header  |  1993-10-07  |  6KB  |  255 lines

  1. /* Copyright (c) 1991 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)lampcolor.c 2.3 1/10/92 LBL";
  5. #endif
  6.  
  7. /*
  8.  * Program to convert lamp color from table and compute radiance.
  9.  */
  10.  
  11. #include <stdio.h>
  12.  
  13. #include "color.h"
  14.  
  15. #define PI    3.14159265358979323846
  16.  
  17. extern char    *gets(), *strcpy();
  18. #ifndef atof
  19. extern double    atof();
  20. #endif
  21. extern float    *matchlamp();
  22.  
  23.                 /* lamp parameters */
  24. #define LTYPE        0
  25. #define LUNIT        1
  26. #define LGEOM        2
  27. #define LOUTP        3
  28. #define NPARAMS        4
  29.  
  30. int    typecheck(), unitcheck(), geomcheck(), outpcheck();
  31.  
  32. float    *lampcolor;        /* the lamp color (RGB) */
  33. double    unit2meter;        /* conversion from units to meters */
  34. double    area;            /* radiating area for this geometry */
  35. double    lumens;            /* total lamp lumens */
  36.  
  37. struct {
  38.     char    *name;
  39.     char    value[64];
  40.     int    (*check)();
  41.     char    *help;
  42. } param[NPARAMS] = {
  43.     { "lamp type", "D65WHITE", typecheck,
  44. "The lamp type is a string which corresponds to one of the types registered\n\
  45. in the lamp table file.  A value of \"D65WHITE\" means an uncolored source,\n\
  46. which may be preferable because it results in a color balanced image." },
  47.     { "length unit", "meter", unitcheck,
  48. "Unit must be one of:  \"meter\", \"centimeter\", \"foot\", or \"inch\".\n\
  49. These may be abbreviated as a single letter." },
  50.     { "lamp geometry", "polygon", geomcheck,
  51. "The lamp geometry must be one of:  \"polygon\", \"sphere\", \"cylinder\"\n\
  52. or \"ring\".  These may be abbreviated as a single letter." },
  53.     { "total lamp lumens", "0", outpcheck,
  54. "This is the overall light output of the lamp and its fixture.  If you do\n\
  55. not know this value explicitly, you can compute the approximate lumens\n\
  56. by multiplying the input wattage by 14 for incandescent fixtures or 70\n\
  57. for fluorescent fixtures." },
  58. };
  59.  
  60.  
  61. main(argc, argv)
  62. int    argc;
  63. char    *argv[];
  64. {
  65.     char    *lamptab = "lamp.tab";
  66.     char    buf[64];
  67.     int    i;
  68.  
  69.     if (argc > 1) lamptab = argv[1];
  70.     if (loadlamps(lamptab) == 0) {
  71.         fprintf(stderr, "%s: no such lamp table\n", lamptab);
  72.         exit(1);
  73.     }
  74.     printf("Program to compute lamp radiance.  Enter '?' for help.\n");
  75.     for ( ; ; ) {
  76.         i = 0;
  77.         while (i < NPARAMS) {
  78.             printf("Enter %s [%s]: ", param[i].name,
  79.                     param[i].value);
  80.             if (gets(buf) == NULL)
  81.                 exit(0);
  82.             if (buf[0] == '?') {
  83.                 puts(param[i].help);
  84.                 continue;
  85.             }
  86.             if (buf[0])
  87.                 strcpy(param[i].value, buf);
  88.             if (!(*param[i].check)(param[i].value)) {
  89.                 fprintf(stderr, "%s: bad value for %s\n",
  90.                         param[i].value, param[i].name);
  91.                 continue;
  92.             }
  93.             i++;
  94.         }
  95.         compute();
  96.     }
  97. }
  98.  
  99.  
  100. typecheck(s)            /* check lamp type */
  101. char    *s;
  102. {
  103.     lampcolor = matchlamp(s);
  104.     return(lampcolor != NULL);
  105. }
  106.  
  107.  
  108. unitcheck(s)            /* compute conversion to meters */
  109. char    *s;
  110. {
  111.     int    len = strlen(s);
  112.  
  113.     switch (*s) {
  114.     case 'm':
  115.         if (strncmp(s, "meters", len))
  116.             return(0);
  117.         unit2meter = 1.0;
  118.         return(1);
  119.     case 'c':
  120.         if (strncmp(s, "centimeters", len) && strncmp(s, "cms", len))
  121.             return(0);
  122.         unit2meter = 0.01;
  123.         return(1);
  124.     case 'f':
  125.         if (strncmp(s, "foot", len) && strncmp(s, "feet", len))
  126.             return(0);
  127.         unit2meter = 0.3048;
  128.         return(1);
  129.     case 'i':
  130.         if (strncmp(s, "inches", len))
  131.             return(0);
  132.         unit2meter = 0.0254;
  133.         return(1);
  134.     }
  135.     return(0);
  136. }
  137.  
  138.  
  139. geomcheck(s)            /* check/set lamp geometry */
  140. char    *s;
  141. {
  142.     int    len = strlen(s);
  143.  
  144.     switch (*s) {
  145.     case 'p':
  146.         if (strncmp(s, "polygonal", len))
  147.             return(0);
  148.         return(getpolygon());
  149.     case 's':
  150.         if (strncmp(s, "sphere", len) && strncmp(s, "spherical", len))
  151.             return(0);
  152.         return(getsphere());
  153.     case 'c':
  154.         if (strncmp(s,"cylinder",len) && strncmp(s,"cylindrical",len))
  155.             return(0);
  156.         return(getcylinder());
  157.     case 'r':
  158.         if (strncmp(s, "ring", len) && strncmp(s, "disk", len))
  159.             return(0);
  160.         return(getring());
  161.     }
  162.     return(0);
  163. }
  164.  
  165.  
  166. outpcheck(s)            /* check lumen output value */
  167. register char    *s;
  168. {
  169.     if ((*s < '0' || *s > '9') && *s != '.')
  170.         return(0);
  171.     lumens = atof(s);
  172.     return(1);
  173. }
  174.  
  175.  
  176. compute()            /* compute lamp radiance */
  177. {
  178.     double    whiteval;
  179.  
  180.     whiteval = lumens/area/(WHTEFFICACY*PI);
  181.  
  182.     printf("Lamp color (RGB) = %f %f %f\n",
  183.             lampcolor[0]*whiteval,
  184.             lampcolor[1]*whiteval,
  185.             lampcolor[2]*whiteval);
  186. }
  187.  
  188.  
  189. getd(name, dp, help)        /* get a positive double from stdin */
  190. char    *name;
  191. double    *dp;
  192. char    *help;
  193. {
  194.     char    buf[32];
  195. again:
  196.     printf("%s [%g]: ", name, *dp);
  197.     if (gets(buf) == NULL)
  198.         return(0);
  199.     if (buf[0] == '?') {
  200.         puts(help);
  201.         goto again;
  202.     }
  203.     if ((buf[0] < '0' || buf[0] > '9') && buf[0] != '.')
  204.         return(0);
  205.     *dp = atof(buf);
  206.     return(1);
  207. }
  208.  
  209.  
  210. getpolygon()            /* get projected area for a polygon */
  211. {
  212.     static double    parea = 1.0;
  213.  
  214.     getd("Polygon area", &parea,
  215.         "Enter the total radiating area of the polygon.");
  216.     area = unit2meter*unit2meter * parea;
  217.     return(1);
  218. }
  219.  
  220.  
  221. getsphere()            /* get projected area for a sphere */
  222. {
  223.     static double    radius = 1.0;
  224.  
  225.     getd("Sphere radius", &radius,
  226.         "Enter the distance from the sphere's center to its surface.");
  227.     area = 4.*PI*unit2meter*unit2meter * radius*radius;
  228.     return(1);
  229. }
  230.  
  231.  
  232. getcylinder()            /* get projected area for a cylinder */
  233. {
  234.     static double    length = 1.0, radius = 0.1;
  235.  
  236.     getd("Cylinder length", &length,
  237.         "Enter the length of the cylinder.");
  238.     getd("Cylinder radius", &radius,
  239.         "Enter the distance from the cylinder's axis to its surface.");
  240.     area = 2.*PI*unit2meter*unit2meter * radius*length;
  241.     return(1);
  242. }
  243.  
  244.  
  245. getring()            /* get projected area for a ring */
  246. {
  247.     static double    radius = 1.0;
  248.  
  249.     getd("Disk radius", &radius,
  250. "Enter the distance from the ring's center to its outer edge.\n\
  251. The inner radius must be zero.");
  252.     area = PI*unit2meter*unit2meter * radius*radius;
  253.     return(1);
  254. }
  255.