ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/gendaymtx.c
(Generate patch)

Comparing ray/src/gen/gendaymtx.c (file contents):
Revision 2.18 by greg, Sun Oct 26 17:37:34 2014 UTC vs.
Revision 2.42 by greg, Thu Feb 27 19:00:00 2025 UTC

# Line 81 | Line 81 | static const char RCSid[] = "$Id$";
81  
82   /* Include files */
83   #define _USE_MATH_DEFINES
84 #include <stdio.h>
84   #include <stdlib.h>
86 #include <string.h>
85   #include <ctype.h>
88 #include "rtmath.h"
86   #include "platform.h"
87 + #include "rtmath.h"
88 + #include "rtio.h"
89   #include "color.h"
90 < #include "resolu.h"
90 > #include "sun.h"
91 > #include "loadEPW.h"
92  
93 < char *progname;                                                         /* Program name */
94 < char errmsg[128];                                                       /* Error message buffer */
93 > char *progname;                                 /* Program name */
94   const double DC_SolarConstantE = 1367.0;        /* Solar constant W/m^2 */
95   const double DC_SolarConstantL = 127.5;         /* Solar constant klux */
96  
# Line 130 | Line 129 | extern void CalcPerezParam( double, double, double, in
129   extern void CalcSkyPatchLumin( float *parr );
130   extern void ComputeSky( float *parr );
131  
132 +
133 + extern double  solar_sunset(int month, int day);
134 + extern double  solar_sunrise(int month, int day);
135 +
136   /* Degrees into radians */
137   #define DegToRad(deg)   ((deg)*(PI/180.))
138  
139   /* Radiuans into degrees */
140   #define RadToDeg(rad)   ((rad)*(180./PI))
141  
139
142   /* Perez sky model coefficients */
143  
144   /* Reference:   Perez, R., R. Seals, and J. Michalsky, 1993. "All- */
# Line 253 | Line 255 | static const ModelCoeff DirectLumEff[8] =
255   #define NSUNPATCH       4               /* max. # patches to spread sun into */
256   #endif
257  
258 < extern int jdate(int month, int day);
257 < extern double stadj(int  jd);
258 < extern double sdec(int  jd);
259 < extern double salt(double sd, double st);
260 < extern double sazi(double sd, double st);
261 <                                        /* sun calculation constants */
262 < extern double  s_latitude;
263 < extern double  s_longitude;
264 < extern double  s_meridian;
258 > #define SUN_ANG_DEG     0.533           /* sun full-angle in degrees */
259  
260   int             nsuns = NSUNPATCH;      /* number of sun patches to use */
261   double          fixed_sun_sa = -1;      /* fixed solid angle per sun? */
# Line 281 | Line 275 | float          *rh_palt;               /* sky patch altitudes (radians) */
275   float           *rh_pazi;               /* sky patch azimuths (radians) */
276   float           *rh_dom;                /* sky patch solid angle (sr) */
277  
278 < #define         vector(v,alt,azi)       (       (v)[1] = tcos(alt), \
279 <                                                (v)[0] = (v)[1]*tsin(azi), \
280 <                                                (v)[1] *= tcos(azi), \
281 <                                                (v)[2] = tsin(alt) )
278 > #define         vector(v,alt,azi)       (       (v)[1] = cos(alt), \
279 >                                                (v)[0] = (v)[1]*sin(azi), \
280 >                                                (v)[1] *= cos(azi), \
281 >                                                (v)[2] = sin(alt) )
282  
283   #define         rh_vector(v,i)          vector(v,rh_palt[i],rh_pazi[i])
284  
285   #define         rh_cos(i)               tsin(rh_palt[i])
286  
287 + #define         solar_minute(jd,hr)     ((24*60)*((jd)-1)+(int)((hr)*60.+.5))
288 +
289   extern int      rh_init(void);
290   extern float *  resize_dmatrix(float *mtx_data, int nsteps, int npatch);
291 + extern void     OutputSun(int id, int goodsun, FILE *fp, FILE *mfp);
292   extern void     AddDirect(float *parr);
293  
294  
# Line 313 | Line 310 | getfmtname(int fmt)
310   int
311   main(int argc, char *argv[])
312   {
313 <        char    buf[256];
313 >        EPWheader       *epw = NULL;    /* EPW/WEA input file */
314 >        EPWrecord       erec;           /* current EPW/WEA input record */
315 >        float   dpthist[2];             /* previous dew point temps */
316 >        double  dir, dif;
317          int     doheader = 1;           /* output header? */
318          double  rotation = 0;           /* site rotation (degrees) */
319          double  elevation;              /* site elevation (meters) */
320 +        int     leap_day = 0;           /* add leap day? */
321 +        int     sun_hours_only = 0;     /* only output sun hours? */
322          int     dir_is_horiz;           /* direct is meas. on horizontal? */
323 +        FILE    *sunsfp = NULL;         /* output file for individual suns */
324 +        FILE    *modsfp = NULL;         /* modifier output file */
325          float   *mtx_data = NULL;       /* our matrix data */
326 <        int     ntsteps = 0;            /* number of rows in matrix */
327 <        int     step_alloc = 0;
326 >        int     avgSky = 0;             /* compute average sky r.t. matrix? */
327 >        int     ntsteps = 0;            /* number of time steps */
328 >        int     tstorage = 0;           /* number of allocated time steps */
329 >        int     nstored = 0;            /* number of time steps in matrix */
330          int     last_monthly = 0;       /* month of last report */
325        int     mo, da;                 /* month (1-12) and day (1-31) */
326        double  hr;                     /* hour (local standard time) */
327        double  dir, dif;               /* direct and diffuse values */
331          int     mtx_offset;
332          int     i, j;
333 +        double  timeinterval = 0;
334  
335          progname = argv[0];
336                                          /* get options */
# Line 376 | Line 380 | main(int argc, char *argv[])
380                          skycolor[1] = atof(argv[++i]);
381                          skycolor[2] = atof(argv[++i]);
382                          break;
383 +                case 'D':                       /* output suns to file */
384 +                        if (strcmp(argv[++i], "-")) {
385 +                                sunsfp = fopen(argv[i], "w");
386 +                                if (sunsfp == NULL) {
387 +                                        fprintf(stderr,
388 +                                        "%s: cannot open '%s' for output\n",
389 +                                                        progname, argv[i]);
390 +                                        exit(1);
391 +                                }
392 +                                break;          /* still may output matrix */
393 +                        }
394 +                        sunsfp = stdout;        /* sending to stdout, so... */
395 +                        /* fall through */
396 +                case 'n':                       /* no matrix output */
397 +                        avgSky = -1;
398 +                        rhsubdiv = 1;
399 +                        /* fall through */
400                  case 'd':                       /* solar (direct) only */
401                          skycolor[0] = skycolor[1] = skycolor[2] = 0;
402 <                        if (suncolor[1] <= 1e-4)
382 <                                suncolor[0] = suncolor[1] = suncolor[2] = 1;
402 >                        grefl[0] = grefl[1] = grefl[2] = 0;
403                          break;
404 +                case 'M':                       /* send sun modifiers to file */
405 +                        if ((modsfp = fopen(argv[++i], "w")) == NULL) {
406 +                                fprintf(stderr, "%s: cannot open '%s' for output\n",
407 +                                                progname, argv[i]);
408 +                                exit(1);
409 +                        }
410 +                        break;
411                  case 's':                       /* sky only (no direct) */
412                          suncolor[0] = suncolor[1] = suncolor[2] = 0;
386                        if (skycolor[1] <= 1e-4)
387                                skycolor[0] = skycolor[1] = skycolor[2] = 1;
413                          break;
414 +                case 'u':                       /* solar hours only */
415 +                        sun_hours_only = 1;
416 +                        break;
417                  case 'r':                       /* rotate distribution */
418                          if (argv[i][2] && argv[i][2] != 'z')
419                                  goto userr;
# Line 393 | Line 421 | main(int argc, char *argv[])
421                          break;
422                  case '5':                       /* 5-phase calculation */
423                          nsuns = 1;
424 <                        fixed_sun_sa = 6.797e-05;
424 >                        fixed_sun_sa = PI/360.*atof(argv[++i]);
425 >                        if (fixed_sun_sa <= 0) {
426 >                                fprintf(stderr, "%s: missing solar disk size argument for '-5' option\n",
427 >                                                progname);
428 >                                exit(1);
429 >                        }
430 >                        fixed_sun_sa *= fixed_sun_sa*PI;
431                          break;
432 +                case 'A':                       /* compute average sky */
433 +                        avgSky = 1;
434 +                        break;
435 +                case 'i':
436 +                        timeinterval = atof(argv[++i]);
437 +                        break;
438                  default:
439                          goto userr;
440                  }
441 <        if (i < argc-1)
441 >        if ((i < argc-1) | (i > argc))
442                  goto userr;
443 <        if (i == argc-1 && freopen(argv[i], "r", stdin) == NULL) {
444 <                fprintf(stderr, "%s: cannot open '%s' for input\n",
405 <                                progname, argv[i]);
443 >        epw = EPWopen(argv[i]);
444 >        if (epw == NULL)
445                  exit(1);
446 <        }
446 >        if ((modsfp != NULL) & (sunsfp == NULL))
447 >                fprintf(stderr, "%s: warning -M output will be empty without -D\n",
448 >                                progname);
449          if (verbose) {
450                  if (i == argc-1)
451                          fprintf(stderr, "%s: reading weather tape '%s'\n",
# Line 414 | Line 455 | main(int argc, char *argv[])
455                                          progname);
456          }
457                                          /* read weather tape header */
458 <        if (scanf("place %[^\r\n] ", buf) != 1)
459 <                goto fmterr;
460 <        if (scanf("latitude %lf\n", &s_latitude) != 1)
461 <                goto fmterr;
462 <        if (scanf("longitude %lf\n", &s_longitude) != 1)
463 <                goto fmterr;
464 <        if (scanf("time_zone %lf\n", &s_meridian) != 1)
424 <                goto fmterr;
425 <        if (scanf("site_elevation %lf\n", &elevation) != 1)
426 <                goto fmterr;
427 <        if (scanf("weather_data_file_units %d\n", &input) != 1)
428 <                goto fmterr;
429 <        switch (input) {                /* translate units */
430 <        case 1:
458 >        s_latitude = epw->loc.latitude;
459 >        s_longitude = -epw->loc.longitude;
460 >        s_meridian = -15.*epw->loc.timezone;
461 >        elevation = epw->loc.elevation;
462 >        switch (epw->isWEA) {           /* translate units */
463 >        case WEAnot:
464 >        case WEAradnorm:
465                  input = 1;              /* radiometric quantities */
466                  dir_is_horiz = 0;       /* direct is perpendicular meas. */
467                  break;
468 <        case 2:
468 >        case WEAradhoriz:
469                  input = 1;              /* radiometric quantities */
470                  dir_is_horiz = 1;       /* solar measured horizontally */
471                  break;
472 <        case 3:
472 >        case WEAphotnorm:
473                  input = 2;              /* photometric quantities */
474                  dir_is_horiz = 0;       /* direct is perpendicular meas. */
475                  break;
# Line 444 | Line 478 | main(int argc, char *argv[])
478          }
479          rh_init();                      /* initialize sky patches */
480          if (verbose) {
481 <                fprintf(stderr, "%s: location '%s'\n", progname, buf);
481 >                fprintf(stderr, "%s: location '%s, %s'\n", progname,
482 >                                epw->loc.city, epw->loc.country);
483                  fprintf(stderr, "%s: (lat,long)=(%.1f,%.1f) degrees north, west\n",
484                                  progname, s_latitude, s_longitude);
485 <                fprintf(stderr, "%s: %d sky patches per time step\n",
486 <                                progname, nskypatch);
485 >                if (avgSky >= 0)
486 >                        fprintf(stderr, "%s: %d sky patches\n",
487 >                                        progname, nskypatch);
488 >                if (sunsfp)
489 >                        fprintf(stderr, "%s: outputting suns to %s\n",
490 >                                        progname, sunsfp==stdout ? "stdout" : "file");
491                  if (rotation != 0)
492                          fprintf(stderr, "%s: rotating output %.0f degrees\n",
493                                          progname, rotation);
# Line 457 | Line 496 | main(int argc, char *argv[])
496          s_latitude = DegToRad(s_latitude);
497          s_longitude = DegToRad(s_longitude);
498          s_meridian = DegToRad(s_meridian);
499 +                                        /* initial allocation */
500 +        mtx_data = resize_dmatrix(mtx_data, tstorage=2, nskypatch);
501 +        dpthist[0] = -100;
502                                          /* process each time step in tape */
503 <        while (scanf("%d %d %lf %lf %lf\n", &mo, &da, &hr, &dir, &dif) == 5) {
504 <                double          sda, sta;
505 <                                        /* make space for next time step */
506 <                mtx_offset = 3*nskypatch*ntsteps++;
507 <                if (ntsteps > step_alloc) {
508 <                        step_alloc += (step_alloc>>1) + ntsteps + 7;
509 <                        mtx_data = resize_dmatrix(mtx_data, step_alloc, nskypatch);
510 <                }
511 <                if (dif <= 1e-4) {
512 <                        memset(mtx_data+mtx_offset, 0, sizeof(float)*3*nskypatch);
513 <                        continue;
514 <                }
515 <                if (verbose && mo != last_monthly)
516 <                        fprintf(stderr, "%s: stepping through month %d...\n",
475 <                                                progname, last_monthly=mo);
503 >        while ((j = EPWread(epw, &erec)) > 0) {
504 >                const int       mo = erec.date.month+1;
505 >                const int       da = erec.date.day;
506 >                const double    hr = erec.date.hour;
507 >                double          sda, sta, st;
508 >                int             sun_in_sky;
509 >                                        /* 3-hour dew point temp */
510 >                if (EPWisset(&erec,dptemp)) {
511 >                        if (dpthist[0] < -99)
512 >                                dpthist[0] = dpthist[1] = erec.dptemp;
513 >                        dew_point = (1./3.)*(dpthist[0] + dpthist[1] + erec.dptemp);
514 >                        dpthist[0] = dpthist[1]; dpthist[1] = erec.dptemp;
515 >                } else
516 >                        dpthist[0] = -100;
517                                          /* compute solar position */
518 <                julian_date = jdate(mo, da);
518 >                if ((mo == 2) & (da == 29)) {
519 >                        julian_date = 60;
520 >                        leap_day = 1;
521 >                } else
522 >                        julian_date = jdate(mo, da) + leap_day;
523                  sda = sdec(julian_date);
524                  sta = stadj(julian_date);
525 <                altitude = salt(sda, hr+sta);
526 <                azimuth = sazi(sda, hr+sta) + PI - DegToRad(rotation);
525 >                st = hr + sta;
526 >                
527 >                if (timeinterval > 0) {
528 >                        if (fabs(solar_sunrise(mo, da) - st) <= timeinterval/120)
529 >                                st = (st + timeinterval/120 + solar_sunrise(mo, da))/2;
530 >                        else if (fabs(solar_sunset(mo, da) - st) < timeinterval/120)
531 >                                st = (st - timeinterval/120 + solar_sunset(mo, da))/2;
532 >                }
533 >                altitude = salt(sda, st);
534 >                sun_in_sky = (altitude > -DegToRad(SUN_ANG_DEG/2.));
535 >                if (sun_hours_only & !sun_in_sky)
536 >                        continue;       /* skipping nighttime points */
537 >                azimuth = sazi(sda, st) + PI - DegToRad(rotation);
538 >
539 >                switch (epw->isWEA) {           /* translate units */
540 >                case WEAnot:
541 >                case WEAradnorm:
542 >                        if (!EPWisset(&erec,dirirrad) |
543 >                                        !EPWisset(&erec,horizdiffirrad)) {
544 >                                fprintf(stderr, "%s: missing required irradiances at line %d\n",
545 >                                                progname, epw->lino);
546 >                                exit(1);
547 >                        }
548 >                        dir = erec.dirirrad;
549 >                        dif = erec.horizdiffirrad;
550 >                        break;
551 >                case WEAradhoriz:
552 >                        dir = erec.globhorizirrad - erec.horizdiffirrad;
553 >                        dif = erec.horizdiffirrad;
554 >                        break;
555 >                case WEAphotnorm:
556 >                        dir = erec.dirillum;
557 >                        dif = erec.diffillum;
558 >                        break;
559 >                }
560 >                mtx_offset = 3*nskypatch*nstored;
561 >                nstored += !avgSky | !nstored;
562 >                                        /* make space for next row */
563 >                if (nstored > tstorage) {
564 >                        tstorage += (tstorage>>1) + nstored + 7;
565 >                        mtx_data = resize_dmatrix(mtx_data, tstorage, nskypatch);
566 >                }
567 >                ntsteps++;              /* keep count of time steps */
568 >
569 >                if (dir+dif <= 1e-4) {  /* effectively nighttime? */
570 >                        if (!avgSky | !mtx_offset)
571 >                                memset(mtx_data+mtx_offset, 0,
572 >                                                sizeof(float)*3*nskypatch);
573 >                                        /* output black sun? */
574 >                        if (sunsfp && sun_in_sky)
575 >                                OutputSun(solar_minute(julian_date,hr), 0,
576 >                                                        sunsfp, modsfp);
577 >                        continue;
578 >                }
579 >                if (!sun_in_sky && dir > (input==1 ? 20. : 20.*WHTEFFICACY))
580 >                        fprintf(stderr,
581 >                                "%s: warning - unusually bright at %.1f on %d-%d\n",
582 >                                        progname, hr, mo, da);
583                                          /* convert measured values */
584 <                if (dir_is_horiz && altitude > 0.)
584 >                if (dir_is_horiz && altitude > FTINY)
585                          dir /= sin(altitude);
586                  if (input == 1) {
587                          dir_irrad = dir;
# Line 491 | Line 592 | main(int argc, char *argv[])
592                  }
593                                          /* compute sky patch values */
594                  ComputeSky(mtx_data+mtx_offset);
595 +                                        /* output sun if requested */
596 +                if (sunsfp && sun_in_sky)
597 +                        OutputSun(solar_minute(julian_date,hr), 1,
598 +                                                sunsfp, modsfp);
599 +
600 +                if (avgSky < 0)         /* no matrix? */
601 +                        continue;
602 +
603                  AddDirect(mtx_data+mtx_offset);
604 +                                        /* update cumulative sky? */
605 +                for (i = 3*nskypatch*(avgSky&(ntsteps>1)); i--; )
606 +                        mtx_data[i] += mtx_data[mtx_offset+i];
607 +                                        /* monthly reporting */
608 +                if (verbose && mo != last_monthly)
609 +                        fprintf(stderr, "%s: stepping through month %d...\n",
610 +                                                progname, last_monthly=mo);
611 +                                        /* note whether leap-day was given */
612          }
613 <                                        /* check for junk at end */
614 <        while ((i = fgetc(stdin)) != EOF)
615 <                if (!isspace(i)) {
616 <                        fprintf(stderr, "%s: warning - unexpected data past EOT: ",
617 <                                        progname);
618 <                        buf[0] = i; buf[1] = '\0';
619 <                        fgets(buf+1, sizeof(buf)-1, stdin);
620 <                        fputs(buf, stderr); fputc('\n', stderr);
621 <                        break;
622 <                }
613 >        if (j != EOF) {
614 >                fprintf(stderr, "%s: error on input\n", progname);
615 >                exit(1);
616 >        }
617 >        EPWclose(epw); epw = NULL;
618 >        if (!ntsteps) {
619 >                fprintf(stderr, "%s: no valid time steps on input\n", progname);
620 >                exit(1);
621 >        }
622 >        if (avgSky < 0)                 /* no matrix output? */
623 >                goto alldone;
624 >
625 >        dif = 1./(double)ntsteps;       /* average sky? */
626 >        for (i = 3*nskypatch*(avgSky&(ntsteps>1)); i--; )
627 >                mtx_data[i] *= dif;
628                                          /* write out matrix */
629          if (outfmt != 'a')
630                  SET_FILE_BINARY(stdout);
# Line 511 | Line 633 | main(int argc, char *argv[])
633   #endif
634          if (verbose)
635                  fprintf(stderr, "%s: writing %smatrix with %d time steps...\n",
636 <                                progname, outfmt=='a' ? "" : "binary ", ntsteps);
636 >                                progname, outfmt=='a' ? "" : "binary ", nstored);
637          if (doheader) {
638                  newheader("RADIANCE", stdout);
639                  printargs(argc, argv, stdout);
640                  printf("LATLONG= %.8f %.8f\n", RadToDeg(s_latitude),
641                                          -RadToDeg(s_longitude));
642                  printf("NROWS=%d\n", nskypatch);
643 <                printf("NCOLS=%d\n", ntsteps);
643 >                printf("NCOLS=%d\n", nstored);
644                  printf("NCOMP=3\n");
645 +                if ((outfmt == 'f') | (outfmt == 'd'))
646 +                        fputendian(stdout);
647                  fputformat((char *)getfmtname(outfmt), stdout);
648                  putchar('\n');
649          }
# Line 528 | Line 652 | main(int argc, char *argv[])
652                  mtx_offset = 3*i;
653                  switch (outfmt) {
654                  case 'a':
655 <                        for (j = 0; j < ntsteps; j++) {
655 >                        for (j = 0; j < nstored; j++) {
656                                  printf("%.3g %.3g %.3g\n", mtx_data[mtx_offset],
657                                                  mtx_data[mtx_offset+1],
658                                                  mtx_data[mtx_offset+2]);
659                                  mtx_offset += 3*nskypatch;
660                          }
661 <                        if (ntsteps > 1)
661 >                        if (nstored > 1)
662                                  fputc('\n', stdout);
663                          break;
664                  case 'f':
665 <                        for (j = 0; j < ntsteps; j++) {
666 <                                fwrite(mtx_data+mtx_offset, sizeof(float), 3,
665 >                        for (j = 0; j < nstored; j++) {
666 >                                putbinary(mtx_data+mtx_offset, sizeof(float), 3,
667                                                  stdout);
668                                  mtx_offset += 3*nskypatch;
669                          }
670                          break;
671                  case 'd':
672 <                        for (j = 0; j < ntsteps; j++) {
672 >                        for (j = 0; j < nstored; j++) {
673                                  double  ment[3];
674                                  ment[0] = mtx_data[mtx_offset];
675                                  ment[1] = mtx_data[mtx_offset+1];
676                                  ment[2] = mtx_data[mtx_offset+2];
677 <                                fwrite(ment, sizeof(double), 3, stdout);
677 >                                putbinary(ment, sizeof(double), 3, stdout);
678                                  mtx_offset += 3*nskypatch;
679                          }
680                          break;
# Line 558 | Line 682 | main(int argc, char *argv[])
682                  if (ferror(stdout))
683                          goto writerr;
684          }
685 <        if (fflush(stdout) == EOF)
685 > alldone:
686 >        if (fflush(NULL) == EOF)
687                  goto writerr;
688          if (verbose)
689                  fprintf(stderr, "%s: done.\n", progname);
690          exit(0);
691   userr:
692 <        fprintf(stderr, "Usage: %s [-v][-h][-d|-s][-r deg][-m N][-g r g b][-c r g b][-o{f|d}][-O{0|1}] [tape.wea]\n",
692 >        fprintf(stderr, "Usage: %s [-v][-h][-A][-d|-s|-n][-u][-D file [-M modfile]][-r deg][-m N][-g r g b][-c r g b][-o{f|d}][-O{0|1}] [tape.wea]\n",
693                          progname);
694          exit(1);
695   fmterr:
696 <        fprintf(stderr, "%s: input weather tape format error\n", progname);
696 >        fprintf(stderr, "%s: weather tape format error in header\n", progname);
697          exit(1);
698   writerr:
699          fprintf(stderr, "%s: write error on output\n", progname);
700          exit(1);
701   }
702  
703 +
704   /* Return maximum of two doubles */
705   double dmax( double a, double b )
706   { return (a > b) ? a : b; }
# Line 586 | Line 712 | ComputeSky(float *parr)
712          int index;                      /* Category index */
713          double norm_diff_illum;         /* Normalized diffuse illuimnance */
714          int i;
715 <        
715 >
716          /* Calculate atmospheric precipitable water content */
717          apwc = CalcPrecipWater(dew_point);
718  
# Line 620 | Line 746 | ComputeSky(float *parr)
746                  /* Limit sky clearness */
747                  if (sky_clearness > 11.9)
748                          sky_clearness = 11.9;
749 +                else if (sky_clearness < 1.0)
750 +                        sky_clearness = 1.0;
751  
752                  /* Limit sky brightness */
753                  if (sky_brightness < 0.01)
754                          sky_brightness = 0.01;
755 +                else if (sky_brightness > 0.6)
756 +                        sky_brightness = 0.6;
757  
758                  /* Calculate illuminance */
759                  index = GetCategoryIndex();
# Line 640 | Line 770 | ComputeSky(float *parr)
770                  diff_illum = diff_irrad * WHTEFFICACY;
771                  dir_illum = dir_irrad * WHTEFFICACY;
772          }
643
644        if (bright(skycolor) <= 1e-4) {                 /* 0 sky component? */
645                memset(parr, 0, sizeof(float)*3*nskypatch);
646                return;
647        }
773          /* Compute ground radiance (include solar contribution if any) */
774          parr[0] = diff_illum;
775          if (altitude > 0)
# Line 652 | Line 777 | ComputeSky(float *parr)
777          parr[2] = parr[1] = parr[0] *= (1./PI/WHTEFFICACY);
778          multcolor(parr, grefl);
779  
780 +        if (bright(skycolor) <= 1e-4) {                 /* 0 sky component? */
781 +                memset(parr+3, 0, sizeof(float)*3*(nskypatch-1));
782 +                return;
783 +        }
784          /* Calculate Perez sky model parameters */
785          CalcPerezParam(sun_zenith, sky_clearness, sky_brightness, index);
786  
# Line 677 | Line 806 | ComputeSky(float *parr)
806          }
807   }
808  
809 +
810 + double
811 + solar_sunset(int month, int day)
812 + {
813 +        float W;
814 +        W = -1 * (tan(s_latitude) * tan(sdec(jdate(month, day))));
815 +        return(12 + (M_PI / 2 - atan2(W, sqrt(1 - W * W))) * 180 / (M_PI * 15));
816 + }
817 +
818 +
819 + double
820 + solar_sunrise(int month, int day)
821 + {
822 +        float W;
823 +        W = -1 * (tan(s_latitude) * tan(sdec(jdate(month, day))));
824 +        return(12 - (M_PI / 2 - atan2(W, sqrt(1 - W * W))) * 180 / (M_PI * 15));
825 + }
826 +
827 +
828   /* Add in solar direct to nearest sky patches (GW) */
829   void
830   AddDirect(float *parr)
# Line 729 | Line 877 | AddDirect(float *parr)
877          }
878   }
879  
880 + /* Output a sun to indicated file if appropriate for this time step */
881 + void
882 + OutputSun(int id, int goodsun, FILE *fp, FILE *mfp)
883 + {
884 +        double  srad;
885 +        FVECT   sv;
886 +
887 +        srad = DegToRad(SUN_ANG_DEG/2.);
888 +        srad = goodsun ? dir_illum/(WHTEFFICACY * PI*srad*srad) : 0;
889 +        vector(sv, altitude, azimuth);
890 +        fprintf(fp, "\nvoid light solar%d\n0\n0\n", id);
891 +        fprintf(fp, "3 %.3e %.3e %.3e\n", srad*suncolor[0],
892 +                        srad*suncolor[1], srad*suncolor[2]);
893 +        fprintf(fp, "\nsolar%d source sun%d\n0\n0\n", id, id);
894 +        fprintf(fp, "4 %.6f %.6f %.6f %.4f\n", sv[0], sv[1], sv[2], SUN_ANG_DEG);
895 +        
896 +        if (mfp != NULL)                /* saving modifier IDs? */
897 +                fprintf(mfp, "solar%d\n", id);
898 + }
899 +
900   /* Initialize Reinhart sky patch positions (GW) */
901   int
902   rh_init(void)
# Line 926 | Line 1094 | int CalcSkyParamFromIllum()
1094          if (sky_brightness < 0.01)
1095                          sky_brightness = 0.01;
1096  
1097 +        if (sky_clearness < 1.0000)
1098 +        {
1099 +                sky_clearness = 1.0000;
1100 +        }
1101 +
1102 +        if (sky_brightness > 0.6)
1103 +        {
1104 +                sky_brightness = 0.6;
1105 +        }
1106 +
1107          while (((fabs(diff_irrad - test1) > 10.0) ||
1108                          (fabs(dir_irrad - test2) > 10.0)) && !(counter == 5))
1109          {
# Line 936 | Line 1114 | int CalcSkyParamFromIllum()
1114                  /* Convert illuminance to irradiance */
1115                  index = GetCategoryIndex();
1116                  diff_irrad = diff_illum / CalcDiffuseIllumRatio(index);
1117 <                dir_irrad = dir_illum / CalcDirectIllumRatio(index);
1117 >                dir_irrad = CalcDirectIllumRatio(index);
1118 >                if (dir_irrad > 0.1)
1119 >                        dir_irrad = dir_illum / dir_irrad;
1120          
1121                  /* Calculate sky brightness and clearness */
1122                  sky_brightness = CalcSkyBrightness();
# Line 949 | Line 1129 | int CalcSkyParamFromIllum()
1129                  /* Limit sky brightness */
1130                  if (sky_brightness < 0.01)
1131                          sky_brightness = 0.01;
1132 +
1133 +                if (sky_clearness < 1.0000)
1134 +                {
1135 +                        sky_clearness = 1.0000;
1136 +                }
1137 +
1138 +                if (sky_brightness > 0.6)
1139 +                {
1140 +                        sky_brightness = 0.6;
1141 +                }
1142          }
1143  
1144          return GetCategoryIndex();

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines