/* Copyright (c) 1992 Regents of the University of California */ #ifndef lint static char SCCSid[] = "@(#)gensky.c 2.18 7/18/96 LBL"; #endif /* * gensky.c - program to generate sky functions. * Our zenith is along the Z-axis, the X-axis * points east, and the Y-axis points north. * Radiance is in watts/steradian/sq. meter. * * 3/26/86 */ #include #include #include #include "color.h" extern char *strcpy(), *strcat(), *malloc(); extern double stadj(), sdec(), sazi(), salt(), tz2mer(); #ifndef PI #define PI 3.14159265358979323846 #endif #define DOT(v1,v2) (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2]) #define S_CLEAR 1 #define S_OVER 2 #define S_UNIF 3 #define S_INTER 4 #define overcast (skytype==S_OVER|skytype==S_UNIF) double normsc(); /* sun calculation constants */ extern double s_latitude; extern double s_longitude; extern double s_meridian; #undef toupper #define toupper(c) ((c) & ~0x20) /* ASCII trick to convert case */ /* European and North American zones */ struct { char zname[8]; /* time zone name (all caps) */ float zmer; /* standard meridian */ } tzone[] = { "YST", 135, "YDT", 120, "PST", 120, "PDT", 105, "MST", 105, "MDT", 90, "CST", 90, "CDT", 75, "EST", 75, "EDT", 60, "AST", 60, "ADT", 45, "NST", 52.5, "NDT", 37.5, "GMT", 0, "BST", -15, "WET", -15, "WETDST", -30, "MET", -30, "METDST", -45, "MEZ", -30, "MESZ", -45, "", 0 }; /* required values */ int position; /* planet position, 0 to 359 */ double hour; /* time, using martian 24-hour clock */ int tsolar; /* 0=standard, 1=solar */ double altitude, azimuth; /* or solar angles */ /* default values */ int skytype = S_CLEAR; /* sky type */ int dosun = 1; double zenithbr = 0.0; int u_zenith = 0; /* -1=irradiance, 1=radiance */ double turbidity = 2.75; double gprefl = 0.2; /* computed values */ double sundir[3]; double groundbr; double F2; double solarbr = 0.0; int u_solar = 0; /* -1=irradiance, 1=radiance */ char *progname; char errmsg[128]; main(argc, argv) int argc; char *argv[]; { int i; progname = argv[0]; if (argc == 2 && !strcmp(argv[1], "-defaults")) { printdefaults(); exit(0); } if (argc < 3) userror("arg count"); if (!strcmp(argv[1], "-ang")) { altitude = atof(argv[2]) * (PI/180); azimuth = atof(argv[3]) * (PI/180); position = -1; } else { position = atoi(argv[1]); if (position < 0 || position > 359) userror("bad position, try 0 to 359"); cvthour(argv[2]); } for (i = 3; i < argc; i++) if (argv[i][0] == '-' || argv[i][0] == '+') switch (argv[i][1]) { case 's': skytype = S_CLEAR; dosun = argv[i][0] == '+'; break; case 'r': case 'R': u_solar = argv[i][1]=='R' ? -1 : 1; solarbr = atof(argv[++i]); break; case 'c': skytype = S_OVER; break; case 'u': skytype = S_UNIF; break; case 'i': skytype = S_INTER; dosun = argv[i][0] == '+'; break; case 't': turbidity = atof(argv[++i]); break; case 'b': case 'B': u_zenith = argv[i][1]=='B' ? -1 : 1; zenithbr = atof(argv[++i]); break; case 'g': gprefl = atof(argv[++i]); break; case 'a': s_latitude = atof(argv[++i]) * (PI/180); break; case 'o': s_longitude = atof(argv[++i]) * (PI/180); break; case 'm': s_meridian = atof(argv[++i]) * (PI/180); break; default: sprintf(errmsg, "unknown option: %s", argv[i]); userror(errmsg); } else userror("bad option"); if (fabs(s_meridian-s_longitude) > 45*PI/180) fprintf(stderr, "%s: warning: %.1f hours btwn. standard meridian and longitude\n", progname, (s_longitude-s_meridian)*12/PI); printhead(argc, argv); computesky(); printsky(); exit(0); } computesky() /* compute sky parameters */ { double normfactor; /* compute solar direction */ if (position > -1) { /* from date and time */ int pd; double sd, st; pd = position; /* Position date */ sd = sdec(pd); /* solar declination */ if (tsolar) /* solar time */ s