Back to index

radiance  4R0+20100331
lampcolor.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: lampcolor.c,v 2.10 2004/03/18 05:22:00 greg Exp $";
00003 #endif
00004 /*
00005  * Program to convert lamp color from table and compute radiance.
00006  */
00007 
00008 #include <stdio.h>
00009 #include <string.h>
00010 #include <math.h>
00011 
00012 #include "rtmath.h"
00013 #include "rtio.h"
00014 #include "color.h"
00015 
00016                             /* lamp parameters */
00017 #define LTYPE        0
00018 #define LUNIT        1
00019 #define LGEOM        2
00020 #define LOUTP        3
00021 #define NPARAMS             4
00022 
00023 static int typecheck(char *s);
00024 static int unitcheck(char *s);
00025 static int geomcheck(char *s);
00026 static int outpcheck(char *s);
00027 static void compute(void);
00028 static int getpolygon(void), getsphere(void), getcylinder(void), getring(void);
00029 static int getd(char *name, double *dp, char *help);
00030 
00031 
00032 float  *lampcolor;          /* the lamp color (RGB) */
00033 double unit2meter;          /* conversion from units to meters */
00034 double area;                /* radiating area for this geometry */
00035 double lumens;                     /* total lamp lumens */
00036 
00037 struct {
00038        char   *name;
00039        char   value[64];
00040        int    (*check)();
00041        char   *help;
00042 } param[NPARAMS] = {
00043        { "lamp type", "WHITE", typecheck,
00044 "The lamp type is a string which corresponds to one of the types registered\n\
00045 in the lamp table file.  A value of \"WHITE\" means an uncolored source,\n\
00046 which may be preferable because it results in a color balanced image." },
00047        { "length unit", "meter", unitcheck,
00048 "Unit must be one of:  \"meter\", \"centimeter\", \"foot\", or \"inch\".\n\
00049 These may be abbreviated as a single letter." },
00050        { "lamp geometry", "polygon", geomcheck,
00051 "The lamp geometry must be one of:  \"polygon\", \"sphere\", \"cylinder\"\n\
00052 or \"ring\".  These may be abbreviated as a single letter." },
00053        { "total lamp lumens", "0", outpcheck,
00054 "This is the overall light output of the lamp and its fixture.  If you do\n\
00055 not know this value explicitly, you can compute the approximate lumens\n\
00056 by multiplying the input wattage by 14 for incandescent fixtures or 70\n\
00057 for fluorescent fixtures." },
00058 };
00059 
00060 
00061 int
00062 main(
00063        int    argc,
00064        char   *argv[]
00065 )
00066 {
00067        char   *lamptab = "lamp.tab";
00068        char   buf[64];
00069        int    i;
00070 
00071        if (argc > 1) lamptab = argv[1];
00072        if (loadlamps(lamptab) == 0) {
00073               fprintf(stderr, "%s: no such lamp table\n", lamptab);
00074               exit(1);
00075        }
00076        printf("Program to compute lamp radiance.  Enter '?' for help.\n");
00077        for ( ; ; ) {
00078               i = 0;
00079               while (i < NPARAMS) {
00080                      printf("Enter %s [%s]: ", param[i].name,
00081                                    param[i].value);
00082                      if (fgetline(buf, sizeof(buf), stdin) == NULL)
00083                             exit(0);
00084                      if (buf[0] == '?') {
00085                             puts(param[i].help);
00086                             continue;
00087                      }
00088                      if (buf[0])
00089                             strcpy(param[i].value, buf);
00090                      if (!(*param[i].check)(param[i].value)) {
00091                             fprintf(stderr, "%s: bad value for %s\n",
00092                                           param[i].value, param[i].name);
00093                             continue;
00094                      }
00095                      i++;
00096               }
00097               compute();
00098        }
00099 }
00100 
00101 
00102 static int
00103 typecheck(                  /* check lamp type */
00104        char   *s
00105 )
00106 {
00107        lampcolor = matchlamp(s);
00108        return(lampcolor != NULL);
00109 }
00110 
00111 
00112 static int
00113 unitcheck(                  /* compute conversion to meters */
00114        char   *s
00115 )
00116 {
00117        int    len = strlen(s);
00118 
00119        switch (*s) {
00120        case 'm':
00121               if (strncmp(s, "meters", len))
00122                      return(0);
00123               unit2meter = 1.0;
00124               return(1);
00125        case 'c':
00126               if (strncmp(s, "centimeters", len) && strncmp(s, "cms", len))
00127                      return(0);
00128               unit2meter = 0.01;
00129               return(1);
00130        case 'f':
00131               if (strncmp(s, "foot", len) && strncmp(s, "feet", len))
00132                      return(0);
00133               unit2meter = 0.3048;
00134               return(1);
00135        case 'i':
00136               if (strncmp(s, "inches", len))
00137                      return(0);
00138               unit2meter = 0.0254;
00139               return(1);
00140        }
00141        return(0);
00142 }
00143 
00144 
00145 static int
00146 geomcheck(                  /* check/set lamp geometry */
00147        char   *s
00148 )
00149 {
00150        int    len = strlen(s);
00151 
00152        switch (*s) {
00153        case 'p':
00154               if (strncmp(s, "polygonal", len))
00155                      return(0);
00156               return(getpolygon());
00157        case 's':
00158               if (strncmp(s, "sphere", len) && strncmp(s, "spherical", len))
00159                      return(0);
00160               return(getsphere());
00161        case 'c':
00162               if (strncmp(s,"cylinder",len) && strncmp(s,"cylindrical",len))
00163                      return(0);
00164               return(getcylinder());
00165        case 'r':
00166               if (strncmp(s, "ring", len) && strncmp(s, "disk", len))
00167                      return(0);
00168               return(getring());
00169        }
00170        return(0);
00171 }
00172 
00173 
00174 static int
00175 outpcheck(                  /* check lumen output value */
00176        register char *s
00177 )
00178 {
00179        if ((*s < '0' || *s > '9') && *s != '.')
00180               return(0);
00181        lumens = atof(s);
00182        return(1);
00183 }
00184 
00185 
00186 static void
00187 compute(void)               /* compute lamp radiance */
00188 {
00189        double whiteval;
00190 
00191        whiteval = lumens/area/(WHTEFFICACY*PI);
00192 
00193        printf("Lamp color (RGB) = %f %f %f\n",
00194                      lampcolor[0]*whiteval,
00195                      lampcolor[1]*whiteval,
00196                      lampcolor[2]*whiteval);
00197 }
00198 
00199 
00200 static int
00201 getd(         /* get a positive double from stdin */
00202        char   *name,
00203        double *dp,
00204        char   *help
00205 )
00206 {
00207        char   buf[32];
00208 again:
00209        printf("%s [%g]: ", name, *dp);
00210        if (fgets(buf, sizeof(buf), stdin) == NULL)
00211               return(0);
00212        if (buf[0] == '?') {
00213               puts(help);
00214               goto again;
00215        }
00216        if ((buf[0] < '0' || buf[0] > '9') && buf[0] != '.')
00217               return(0);
00218        *dp = atof(buf);
00219        return(1);
00220 }
00221 
00222 
00223 static int
00224 getpolygon(void)                   /* get projected area for a polygon */
00225 {
00226        static double parea = 1.0;
00227 
00228        getd("Polygon area", &parea,
00229               "Enter the total radiating area of the polygon.");
00230        area = unit2meter*unit2meter * parea;
00231        return(1);
00232 }
00233 
00234 
00235 static int
00236 getsphere(void)                    /* get projected area for a sphere */
00237 {
00238        static double radius = 1.0;
00239 
00240        getd("Sphere radius", &radius,
00241               "Enter the distance from the sphere's center to its surface.");
00242        area = 4.*PI*unit2meter*unit2meter * radius*radius;
00243        return(1);
00244 }
00245 
00246 
00247 static int
00248 getcylinder(void)                  /* get projected area for a cylinder */
00249 {
00250        static double length = 1.0, radius = 0.1;
00251 
00252        getd("Cylinder length", &length,
00253               "Enter the length of the cylinder.");
00254        getd("Cylinder radius", &radius,
00255               "Enter the distance from the cylinder's axis to its surface.");
00256        area = 2.*PI*unit2meter*unit2meter * radius*length;
00257        return(1);
00258 }
00259 
00260 
00261 static int
00262 getring(void)               /* get projected area for a ring */
00263 {
00264        static double radius = 1.0;
00265 
00266        getd("Disk radius", &radius,
00267 "Enter the distance from the ring's center to its outer edge.\n\
00268 The inner radius must be zero.");
00269        area = PI*unit2meter*unit2meter * radius*radius;
00270        return(1);
00271 }