KHolidays Library
lunarphase.cpp
00001 /* 00002 This file is part of the kholidays library. 00003 00004 Copyright (c) 2004,2007,2009 Allen Winter <winter@kde.org> 00005 00006 Copyright (c) 1989, 1993 //krazy:exclude=copyright 00007 The Regents of the University of California. All rights reserved. 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Library General Public 00011 License as published by the Free Software Foundation; either 00012 version 2 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU Library General Public License for more details. 00018 00019 You should have received a copy of the GNU Library General Public License 00020 along with this library; see the file COPYING.LIB. If not, write to the 00021 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00022 Boston, MA 02110-1301, USA. 00023 */ 00024 00025 #include "lunarphase.h" 00026 #include <config-kholidays.h> 00027 00028 #include <KDebug> 00029 #include <KGlobal> 00030 #include <KLocale> 00031 00032 #include <QtCore/QDateTime> 00033 00034 using namespace KHolidays; 00035 00036 static double percentFull( uint tmpt ); 00037 static double degreesToRadians( double degree ); 00038 static void adj360( double *degree ); 00039 00040 QString LunarPhase::phaseNameAtDate( const QDate &date ) 00041 { 00042 return phaseName( phaseAtDate( date ) ); 00043 } 00044 00045 QString LunarPhase::phaseName( LunarPhase::Phase phase ) 00046 { 00047 switch ( phase ) { 00048 case NewMoon: 00049 return( i18n( "New Moon" ) ); 00050 case FullMoon: 00051 return( i18n( "Full Moon" ) ); 00052 case FirstQuarter: 00053 return( i18n( "First Quarter Moon" ) ); 00054 case LastQuarter: 00055 return( i18n( "Last Quarter Moon" ) ); 00056 default: 00057 case None: 00058 return QString(); 00059 } 00060 } 00061 00062 LunarPhase::Phase LunarPhase::phaseAtDate( const QDate &date ) 00063 { 00064 Phase retPhase = None; 00065 00066 // compute percent-full for the middle of today and yesterday. 00067 const QTime anytime( 12, 0, 0 ); 00068 const QDateTime today( date, anytime, Qt::UTC ); 00069 const double todayPer = percentFull( today.toTime_t() ) + 0.5; 00070 00071 const QDateTime tomorrow( date.addDays( 1 ), anytime, Qt::UTC ); 00072 const double tomorrowPer = percentFull( tomorrow.toTime_t() ) + 0.5; 00073 00074 if ( static_cast<int>( todayPer ) == 100 && 00075 static_cast<int>( tomorrowPer ) != 100 ) { 00076 retPhase = FullMoon; 00077 } else if ( static_cast<int>( todayPer ) == 0 && 00078 static_cast<int>( tomorrowPer ) != 0 ) { 00079 retPhase = NewMoon; 00080 } else { 00081 if ( todayPer > 50 && tomorrowPer < 50 ) { 00082 retPhase = LastQuarter; 00083 } 00084 if ( todayPer < 50 && tomorrowPer > 50 ) { 00085 retPhase = FirstQuarter; 00086 } 00087 00088 // Note: if you want to support crescent and gibbous phases then please 00089 // read the source for the original BSD 'pom' program. 00090 } 00091 00092 return( retPhase ); 00093 } 00094 00095 /* 00096 * Copyright (c) 1989, 1993 00097 * The Regents of the University of California. All rights reserved. 00098 * 00099 * This code is derived from software posted to USENET. 00100 * 00101 * Redistribution and use in source and binary forms, with or without 00102 * modification, are permitted provided that the following conditions 00103 * are met: 00104 * 1. Redistributions of source code must retain the above copyright 00105 * notice, this list of conditions and the following disclaimer. 00106 * 2. Redistributions in binary form must reproduce the above copyright 00107 * notice, this list of conditions and the following disclaimer in the 00108 * documentation and/or other materials provided with the distribution. 00109 * 3. All advertising materials mentioning features or use of this software 00110 * must display the following acknowledgement: 00111 * This product includes software developed by the University of 00112 * California, Berkeley and its contributors. 00113 * 4. Neither the name of the University nor the names of its contributors 00114 * may be used to endorse or promote products derived from this software 00115 * without specific prior written permission. 00116 * 00117 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 00118 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00119 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00120 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 00121 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00122 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00123 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00124 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00125 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00126 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00127 * SUCH DAMAGE. 00128 */ 00129 00130 #ifdef HAVE_SYS_CDEFS_H 00131 #include <sys/cdefs.h> 00132 #endif 00133 00134 /* 00135 * Phase of the Moon. Calculates the current phase of the moon. 00136 * Based on routines from `Practical Astronomy with Your Calculator', 00137 * by Duffett-Smith. Comments give the section from the book that 00138 * particular piece of code was adapted from. 00139 * 00140 * -- Keith E. Brandt VIII 1984 00141 * 00142 * Updated to the Third Edition of Duffett-Smith's book, Paul Janzen, IX 1998 00143 * 00144 */ 00145 00146 #include <ctype.h> 00147 #ifdef HAVE_ERR_H 00148 #include <err.h> 00149 #endif 00150 #include <math.h> 00151 #include <string.h> 00152 #include <stdlib.h> 00153 #include <time.h> 00154 #include <unistd.h> 00155 00156 static double PI = 3.14159265358979323846; 00157 00158 /* 00159 * The EPOCH in the third edition of the book is 1990 Jan 0.0 TDT. 00160 * In this program, we do not bother to correct for the differences 00161 * between UTC (as shown by the UNIX clock) and TDT. (TDT = TAI + 32.184s; 00162 * TAI-UTC = 32s in Jan 1999.) 00163 */ 00164 static int EPOCH_MINUS_1970 = ( 20 * 365 + 5 - 1 ); /* 20 years, 5 leaps, back 1 day to Jan 0 */ 00165 static double EPSILONg = 279.403303; /* solar ecliptic long at EPOCH */ 00166 static double RHOg = 282.768422; /* solar ecliptic long of perigee at EPOCH */ 00167 static double ECCEN = 0.016713; /* solar orbit eccentricity */ 00168 static double lzero = 318.351648; /* lunar mean long at EPOCH */ 00169 static double Pzero = 36.340410; /* lunar mean long of perigee at EPOCH */ 00170 static double Nzero = 318.510107; /* lunar mean long of node at EPOCH */ 00171 00172 /* 00173 * percentFull -- 00174 * return phase of the moon as a percentage of full 00175 */ 00176 static double percentFull( uint tmpt ) 00177 { 00178 double N, Msol, Ec, LambdaSol, l, Mm, Ev, Ac, A3, Mmprime; 00179 double A4, lprime, V, ldprime, D, Nm; 00180 00181 double days; 00182 days = ( tmpt - EPOCH_MINUS_1970 * 86400 ) / 86400.0; 00183 00184 N = 360 * days / 365.242191; /* sec 46 #3 */ 00185 adj360( &N ); 00186 Msol = N + EPSILONg - RHOg; /* sec 46 #4 */ 00187 adj360( &Msol ); 00188 Ec = 360 / PI * ECCEN * sin( degreesToRadians( Msol ) ); /* sec 46 #5 */ 00189 LambdaSol = N + Ec + EPSILONg; /* sec 46 #6 */ 00190 adj360( &LambdaSol ); 00191 l = 13.1763966 * days + lzero; /* sec 65 #4 */ 00192 adj360( &l ); 00193 Mm = l - ( 0.1114041 * days ) - Pzero; /* sec 65 #5 */ 00194 adj360( &Mm ); 00195 Nm = Nzero - ( 0.0529539 * days ); /* sec 65 #6 */ 00196 adj360( &Nm ); 00197 Ev = 1.2739 * sin( degreesToRadians( 2 * ( l - LambdaSol ) - Mm ) ); /* sec 65 #7 */ 00198 Ac = 0.1858 * sin( degreesToRadians( Msol ) ); /* sec 65 #8 */ 00199 A3 = 0.37 * sin( degreesToRadians( Msol ) ); 00200 Mmprime = Mm + Ev - Ac - A3; /* sec 65 #9 */ 00201 Ec = 6.2886 * sin( degreesToRadians( Mmprime ) ); /* sec 65 #10 */ 00202 A4 = 0.214 * sin( degreesToRadians( 2 * Mmprime ) ); /* sec 65 #11 */ 00203 lprime = l + Ev + Ec - Ac + A4; /* sec 65 #12 */ 00204 V = 0.6583 * sin( degreesToRadians( 2 * ( lprime - LambdaSol ) ) );/* sec 65 #13 */ 00205 ldprime = lprime + V; /* sec 65 #14 */ 00206 D = ldprime - LambdaSol; /* sec 67 #2 */ 00207 D = 50.0 * ( 1 - cos( degreesToRadians( D ) ) ); /* sec 67 #3 */ 00208 return D; 00209 } 00210 00211 /* 00212 * degreesToRadians -- 00213 * convert degrees to radians 00214 */ 00215 static double degreesToRadians( double degree ) 00216 { 00217 return ( degree * PI ) / 180.00; 00218 } 00219 00220 /* 00221 * adj360 -- 00222 * adjust value so 0 <= degree <= 360 00223 */ 00224 static void adj360( double *degree ) 00225 { 00226 for ( ;; ) { 00227 if ( *degree < 0 ) { 00228 *degree += 360; 00229 } else if ( *degree > 360 ) { 00230 *degree -= 360; 00231 } else { 00232 break; 00233 } 00234 } 00235 }
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon May 14 2012 04:38:39 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon May 14 2012 04:38:39 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.