zoukankan      html  css  js  c++  java
  • 太阳高度角和方位角的计算

      1 function compute () {
      2 
      3     if (CheckInputs ()) {
      4 
      5         var f = document.theForm;
      6         
      7         //常量
      8         
      9         var       degreesToRadians =    3.1416 /  180.0000;
     10         var       radiansToDegrees =  180.0000 /    3.1416;
     11         var           feetToMeters =    1.0000 /    3.2800;
     12         var degreeMinutesToDecimal =    1.0000 /   60.0000;
     13         var degreeSecondsToDecimal =    1.0000 / 3600.0000;                
     14     
     15         // 检索输入的值
     16         /*经度    
     17 120
     18      选择时间制式    
     19 16:56
     20  
     21 纬度    
     22 36
     23      选择时区    
     24 选择日期    月 日    选择基准时间    
     25      年    夏令时    
     26 海拔    
     27 44
     28      零方位角    
     29    计算       
     30 世界时间时区查询换算 
     31 输出结果:
     32 太阳高度角    
     33 - 1.59
     34 偏差    
     35 -23.30
     36 太阳方位角    
     37  62.03
     38 时差    
     39 - 0.02
     40 时钟时间    
     41 1656
     42 日出时间    
     43 2308
     44 太阳时    
     45 1656
     46 日落时间    
     47 3254
     48 时角    
     49  74.00
     50  */
     51      20160926修改
     52         var inputLongitude   = f.inputLongitude.value;
     53         var inputEastWest    = f.inputEastWest.options[f.inputEastWest.selectedIndex].text;
     54         var inputLatitude    = f.inputLatitude.value;
     55         var inputNorthSouth  = f.inputNorthSouth.options[f.inputNorthSouth.selectedIndex].text;
     56         var inputElevation   = f.inputElevation.value;
     57         var inputFeetMeters  = f.inputFeetMeters.options[f.inputFeetMeters.selectedIndex].text;
     58         var inputMonth       = f.inputMonth.options[f.inputMonth.selectedIndex].text;
     59         var inputDate        = f.inputDate.options[f.inputDate.selectedIndex].text - 0;
     60         var inputYear        = f.inputYear.options[f.inputYear.selectedIndex].text - 0;
     61         var inputTime        = f.inputTime.value;
     62         var inputAMPM        = f.inputAMPM.options[f.inputAMPM.selectedIndex].text;
     63         var inputTimeFormat  = f.inputTimeFormat.options[f.inputTimeFormat.selectedIndex].text;
     64         var inputTimeZone    = f.inputTimeZone.options[f.inputTimeZone.selectedIndex].value - 0;
     65         var inputDaylight    = f.inputDaylight.options[f.inputDaylight.selectedIndex].text;
     66         var inputZeroAzimuth = f.inputZeroAzimuth.options[f.inputZeroAzimuth.selectedIndex].value - 0;
     67 
     68         
     69         if (inputLongitude.indexOf("d") != -1) {
     70         
     71             degMarker = inputLongitude.indexOf("d");
     72             minMarker = inputLongitude.indexOf("m");
     73             secMarker = inputLongitude.indexOf("s");
     74     
     75             longitudeDeg = inputLongitude.substr(0,degMarker)                       - 0;
     76             longitudeMin = inputLongitude.substr(degMarker+1,minMarker-degMarker-1) - 0;
     77             longitudeSec = inputLongitude.substr(minMarker+1,secMarker-minMarker-1) - 0;
     78             
     79             inputLongitude = longitudeDeg + (longitudeMin * degreeMinutesToDecimal) + (longitudeSec * degreeSecondsToDecimal);
     80         }
     81         else { inputLongitude -= 0; }
     82         
     83         if (inputLatitude.indexOf("d") != -1) {
     84         
     85             degMarker = inputLatitude.indexOf("d");
     86             minMarker = inputLatitude.indexOf("m");
     87             secMarker = inputLatitude.indexOf("s");
     88     
     89             LatitudeDeg = inputLatitude.substr(0,degMarker)                       - 0;
     90             LatitudeMin = inputLatitude.substr(degMarker+1,minMarker-degMarker-1) - 0;
     91             LatitudeSec = inputLatitude.substr(minMarker+1,secMarker-minMarker-1) - 0;
     92             
     93             inputLatitude = LatitudeDeg + (LatitudeMin * degreeMinutesToDecimal) + (LatitudeSec * degreeSecondsToDecimal);
     94         }
     95         else { inputLatitude -= 0; }
     96         
     97         //检查输入值的有效性
     98         
     99         var validInputTime   = true;
    100     
    101         // 避免由于纬度或经度数学错误 = 0
    102         
    103         if ((inputLatitude  == 0) && (f.inputLatitude.value.length  > 0)) { inputLatitude  = 0.000000001; }
    104         if ((inputLongitude == 0) && (f.inputLongitude.value.length > 0)) { inputLongitude = 0.000000001; }
    105 
    106         //检查输入的字段都由用户填写
    107         
    108         var timeEntered      = (inputTime      != "");
    109         var latitudeEntered  = (inputLatitude  != "");
    110         var longitudeEntered = (inputLongitude != "");
    111         
    112         // 将输入的字符串转换为数字
    113         
    114         inputLatitude  = inputLatitude  - 0;
    115         inputLongitude = inputLongitude - 0;
    116         inputElevation = inputElevation - 0;
    117         
    118         // 确定时间格式
    119     
    120         var clockTimeInputMode = (inputTimeFormat == "Clock time");
    121         var lsotInputMode      = (inputTimeFormat == "Solar time");
    122     
    123         // 
    124         
    125         var doableDeclination = true;
    126         var doableEOT         = true;
    127         var doableClockTime   = ((longitudeEntered || clockTimeInputMode) && timeEntered);
    128         var doableLSOT        = ((longitudeEntered ||      lsotInputMode) && timeEntered);
    129         var doableHourAngle   = (longitudeEntered && timeEntered);
    130         var doableSunRiseSet  = (longitudeEntered && latitudeEntered);
    131         var doableAltitude    = (longitudeEntered && timeEntered && latitudeEntered);
    132         var doableAzimuth     = (longitudeEntered && timeEntered && latitudeEntered);
    133 
    134 
    135         // //////////// //
    136         //计算//
    137         // //////////// //
    138 
    139             // 转换单位
    140             
    141         // 经度东-西调整
    142         
    143         if (longitudeEntered) {
    144             var signedLongitude = inputLongitude;
    145             if (inputEastWest == "East") signedLongitude *= -1;      // [0] = 东, [1] = 西
    146         }
    147         
    148         // 纬度南北调整
    149         
    150         if (latitudeEntered) {
    151             var signedLatitude = inputLatitude;
    152             if (inputNorthSouth == "South") signedLatitude *= -1;      // [0] = 北, [1] = 南
    153         }
    154         
    155         // 修复经度 > 180 deg
    156         
    157         if (signedLongitude > 180) {
    158         
    159             signedLongitude = signedLongitude - 360;
    160         }
    161 
    162         // 修复经度< -180 deg
    163         
    164         if (signedLongitude < -180) {
    165         
    166             signedLongitude = signedLongitude + 360;
    167         }
    168 
    169         // 日光节约时间的调整,计算
    170     
    171         var daylightAdjustment = 0;
    172 
    173         if (inputDaylight == "Yes") daylightAdjustment = 1;
    174         
    175         // 如果有必要,转换高度单位
    176         
    177         if (inputFeetMeters == "feet") { inputElevation *= feetToMeters; }
    178         
    179         //设置为零的方位
    180         
    181         zeroAzimuth = inputZeroAzimuth;
    182 
    183         // 当地标准时间子午线
    184         
    185         var meridian = inputTimeZone * -15;
    186         
    187         // 如果太多与时区经度不同的警报
    188         
    189         var longitudeMeridianDifference = signedLongitude  - meridian;
    190     
    191         if ((! showedLongitudeMeridianWarning) && ((longitudeMeridianDifference > 30) || (longitudeMeridianDifference < -30))) {
    192         
    193             alert ("警告:  经度从选定的时区中心相差超过30度.  这可能是正确的, 或者它可能表明,其中一个输入是不正确的.
    
    请点击 '时区' 输入的详细信息.
    
    (不会再次显示这个警告.)");
    194             
    195             showedLongitudeMeridianWarning = true;
    196         }
    197         
    198             // 计算时间
    199             
    200         // 转换时间输入午后小时
    201         
    202         if (validInputTime) {
    203             
    204             // ...如果有必要从时间字符串删除分号
    205             
    206             inputTime = RemoveSemicolon (inputTime);
    207         
    208             // ...解析时间输入的字符串并得到小时和分钟
    209                 
    210             if (inputTime.length == 4) {                          // 如 "1234"
    211                 timeHours = inputTime.substring(0,2) - 0;
    212                 timeMinutes = inputTime.substring(2,4) - 0;
    213             }
    214             else {                                                // 如 "123"
    215                 timeHours = inputTime.substring(0,1) - 0;
    216                 timeMinutes = inputTime.substring(1,3) - 0;
    217             }
    218             
    219             // ...调整为 AM/PM 名称
    220             
    221             if ((inputAMPM == "AM") && (timeHours == 12)) timeHours = 0;
    222             if  (inputAMPM == "PM") { if (timeHours != 12) timeHours += 12; }
    223         
    224             // ...计算后午夜的时钟分钟
    225             
    226             var inputHoursAfterMidnight   = timeHours + timeMinutes / 60.0;
    227             var inputMinutesAfterMidnight = timeHours * 60.0 + timeMinutes;
    228         }
    229         
    230         // 计算通用时间
    231         
    232         var UT = 0.0;
    233 
    234         if (validInputTime) { UT = inputHoursAfterMidnight - inputTimeZone - daylightAdjustment; }
    235 
    236         var monthNum = (MonthStringToMonthNum (inputMonth)) - 0;
    237 
    238         if (monthNum > 2) {
    239             correctedYear = inputYear;
    240             correctedMonth = monthNum - 3;
    241         }
    242         else {
    243             correctedYear = inputYear - 1;
    244             correctedMonth = monthNum  + 9;
    245         }
    246 
    247         var t = ((UT / 24.0) + inputDate + Math.floor (30.6 * correctedMonth + 0.5) + Math.floor (365.25 * (correctedYear - 1976)) - 8707.5) / 36525.0;
    248 
    249         var G = 357.528 + 35999.05 * t;
    250         G = NormalizeTo360 (G);
    251     
    252         var C = (1.915 * Math.sin (G * degreesToRadians)) + (0.020 * Math.sin (2.0 * G * degreesToRadians));
    253         
    254         var L = 280.460 + (36000.770 * t) + C;
    255         L = NormalizeTo360 (L);
    256         
    257         var alpha = L - 2.466 * Math.sin (2.0 * L * degreesToRadians) + 0.053 *  Math.sin (4.0 * L * degreesToRadians);
    258         
    259         var GHA = UT * 15 - 180 - C + L - alpha;
    260         GHA = NormalizeTo360 (GHA);
    261 
    262         var obliquity = 23.4393 - 0.013 * t;
    263         
    264         var declination = Math.atan (Math.tan (obliquity * degreesToRadians) * Math.sin (alpha * degreesToRadians)) * radiansToDegrees;
    265 
    266         f.outputDeclination.value = FormatFloatString (declination);
    267     
    268         var eotAdjustment = (L - C - alpha) / 15.0;  
    269         
    270         f.outputEOT.value = FormatFloatString (eotAdjustment);
    271 
    272         if (doableLSOT || doableClockTime) {
    273 
    274             var clockTimeToLSOTAdjustment = ((signedLongitude - meridian) / 15.0) - eotAdjustment + daylightAdjustment;   // 以小时为单位
    275         }
    276 
    277         var solarHourAngle = 0;
    278         
    279         if (clockTimeInputMode) { solarHourAngle = GHA - signedLongitude; }
    280         
    281         else { solarHourAngle = 15 * (inputHoursAfterMidnight - 12); }
    282         
    283         solarHourAngle = NormalizeTo180 (solarHourAngle);
    284         
    285         var apparentSolarTime = 0;
    286         
    287         if (clockTimeInputMode) { apparentSolarTime = NormalizeTo24 (12 + solarHourAngle / 15.0); }
    288         
    289         else { apparentSolarTime = inputHoursAfterMidnight; }
    290 
    291         if (doableLSOT) {
    292         
    293             if (clockTimeInputMode) {
    294             
    295                 solarMinutesAfterMidnight = inputMinutesAfterMidnight - (clockTimeToLSOTAdjustment * 60.0);
    296             
    297                 var whichDay = 0;
    298                 
    299                 if (solarMinutesAfterMidnight < 0) {           
    300                     solarMinutesAfterMidnight += 24 * 60;
    301                     whichDay = -1;
    302                 }
    303                 
    304                 if (solarMinutesAfterMidnight >= 24 * 60) {    
    305                     solarMinutesAfterMidnight -= 24 * 60;
    306                     whichDay = 1;
    307                 }
    308             }
    309             
    310             else {
    311             
    312                 solarMinutesAfterMidnight = inputMinutesAfterMidnight;
    313                 
    314                 whichDay = 0;
    315             }
    316             
    317             solarTime = MinutesToClockTime (solarMinutesAfterMidnight, inputAMPM);
    318             
    319             if (whichDay == "-1") f.outputLSOT.value = solarTime + "-";
    320             if (whichDay ==  "0") f.outputLSOT.value = solarTime      ;
    321             if (whichDay ==  "1") f.outputLSOT.value = solarTime + "+";
    322         }
    323 
    324         else { f.outputLSOT.value = ""; }
    325         
    326         if (doableClockTime) {
    327         
    328             var clockMinutesAfterMidnight = inputMinutesAfterMidnight;
    329             
    330             if (lsotInputMode) { clockMinutesAfterMidnight = inputMinutesAfterMidnight + (clockTimeToLSOTAdjustment * 60.0); }
    331         
    332             var whichDay = 0;
    333             
    334             if (clockMinutesAfterMidnight < 0) {          
    335                 clockMinutesAfterMidnight += 24 * 60;
    336                 whichDay = -1;
    337             }
    338             
    339             if (clockMinutesAfterMidnight >= 24 * 60) {    
    340                 clockMinutesAfterMidnight -= 24 * 60;
    341                 whichDay = 1;
    342             }
    343             
    344             clockTime = MinutesToClockTime (clockMinutesAfterMidnight, inputAMPM);
    345             
    346             if (whichDay == "-1") f.outputClockTime.value = clockTime + "-";
    347             if (whichDay ==  "0") f.outputClockTime.value = clockTime      ;
    348             if (whichDay ==  "1") f.outputClockTime.value = clockTime + "+";
    349         }
    350         
    351         else { f.outputClockTime.value = ""; }
    352         
    353         // 小时角
    354         
    355             // 不同之间 180 和 + 180 度
    356         
    357         if (doableHourAngle) {
    358         
    359             var hourAngle = (solarMinutesAfterMidnight - (12 * 60)) / 4;
    360 
    361             f.outputHourAngle.value = FormatFloatString (hourAngle);
    362         }
    363         
    364         else { f.outputHourAngle.value = ""; }
    365         
    366         //地平高度角
    367 
    368         if (doableAltitude) {    
    369 
    370             var altitudeAngle = radiansToDegrees  * ArcSin (
    371                 (Math.sin (signedLatitude         * degreesToRadians)  *
    372                  Math.sin (declination            * degreesToRadians)) -
    373                 (Math.cos (signedLatitude         * degreesToRadians)  *
    374                  Math.cos (declination            * degreesToRadians)  *
    375                  Math.cos ((solarHourAngle + 180) * degreesToRadians)));
    376         
    377             f.outputAltitude.value = FormatFloatString (altitudeAngle);
    378         }
    379 
    380         else { f.outputAltitude.value = ""; }
    381         
    382         // 方位角
    383         
    384         if (doableAzimuth) {
    385         
    386             var preAzimuthAngle = radiansToDegrees * ArcCos (
    387                 (Math.cos (declination    * degreesToRadians)   *
    388                 ((Math.cos (signedLatitude * degreesToRadians)   *
    389                  Math.tan (declination    * degreesToRadians))   +
    390                  (Math.sin (signedLatitude * degreesToRadians)   *
    391                  Math.cos ((solarHourAngle + 180)            * degreesToRadians)))) /
    392                  Math.cos (altitudeAngle  * degreesToRadians));
    393 
    394             azimuthAngle = preAzimuthAngle + (zeroAzimuth - 180.0);
    395 
    396             // 方位角的正确标志
    397 
    398                 
    399             if (zeroAzimuth == 0) {
    400             
    401                 azimuthAngle = ChangeSign (azimuthAngle, "same", hourAngle);
    402             }
    403             
    404                 //北零方位
    405                 
    406             else {
    407             
    408                 azimuthAngle = ChangeSign (azimuthAngle, "opposite", hourAngle);
    409             }
    410 
    411             f.outputAzimuth.value = FormatFloatString (azimuthAngle);
    412         }
    413 
    414         else { f.outputAzimuth.value = ""; }
    415         
    416         // 时钟时间的日出与日落
    417         
    418         if (doableSunRiseSet) {
    419         var sunRiseSetLSoTMinutes = radiansToDegrees * ArcCos ( -1.0 *
    420             (Math.sin (signedLatitude * degreesToRadians) *
    421             Math.sin (declination    * degreesToRadians) - 
    422             Math.sin ((-0.8333 - 0.0347 * Math.sqrt (inputElevation)) * degreesToRadians)) /
    423             Math.cos (signedLatitude * degreesToRadians) /
    424             Math.cos (declination    * degreesToRadians)) * 4;
    425 
    426             f.outputSunrise.value = MinutesToClockTime ((12 * 60 - sunRiseSetLSoTMinutes + (clockTimeToLSOTAdjustment * 60)), inputAMPM);
    427         
    428             f.outputSunset.value  = MinutesToClockTime ((12 * 60 + sunRiseSetLSoTMinutes + (clockTimeToLSOTAdjustment * 60)), inputAMPM);        
    429         }
    430         else {
    431             f.outputSunrise.value = "";
    432             f.outputSunset.value = "";        
    433         }
    434     }    
    435         
    436     // 零出形式输出,是否输入了无效
    437     
    438     else {
    439 
    440         var f = document.theForm;
    441             
    442         f.outputAltitude.value = '';
    443         f.outputAzimuth.value = '';
    444         f.outputDeclination.value = '';
    445         f.outputEOT.value = '';
    446         f.outputClockTime.value = '';
    447         f.outputSunrise.value = '';
    448         f.outputSunset.value = '';
    449         f.outputLSOT.value = '';    
    450         f.outputHourAngle.value = '';    
    451     }
    452 
    453 }
  • 相关阅读:
    JS判断鼠标移入元素的方向
    EJB开发第一个无状态会话bean、开发EJBclient
    Android摇一摇振动效果Demo
    吃饭与团队惬意
    Factorization Machines 学习笔记(三)回归和分类
    代理---视图间数据的传递:标签显示输入的内容【多个视图中】
    cocos2d-x v3.2 FlappyBird 各个类对象详细代码分析(7)
    金典 SQL笔记(4)
    用GDB调试多进程程序
    C程序设计的抽象思维-算法分析-大多数元素
  • 原文地址:https://www.cnblogs.com/cndavy/p/6251264.html
Copyright © 2011-2022 走看看