Showing posts with label Cpp. Show all posts
Showing posts with label Cpp. Show all posts

Friday, August 6, 2010

Prayer Times Calculations: Pure C++ Code

[25-March-2017] Update: For brothers and sisters in Indonesia or any country below the equator, thanks to Reza's comment,  the code now works correctly.
[18-January-2012 Update: I refined the code to make it easier and more elegant to use]
[06-July-2011 Update: I found this page http://praytimes.org/calculation#Implementation ]

This idea came to me when a friend of mine was asking for an 'offline database' for prayer times. I searched for algorithms to make my own database and almost all search results lead to the same algorithm. And all codes are divided into two categories: a simple but approximate one, and a complicated but precise one. I tried with the complicated one to understand it but it needs more time because of its nested functions and -unfortunately- it is not a priority right now. So I went with the easy one as a start.

One thing I noticed is that every person is trying to make the ultimate use of the framework he is working on (mostly dotNet). But come on, it is all about calculations. Why don't you make a code that can be easily converted from one language/platform to another? That's why I wanted to make that code. It has a major problem till now as it produces times later than my Egyptian calendar up to 5 minutes !!! Only later not earlier.


Anyways, here is the code, and I hope I can reach better results in the near future (in-sha'a Allah).


 The parameters needed are:
  • Year/Month/Day of the desired day.
  • Longitude/Latitude/Time Zone of the desired place.
  • Fajr Twilight/ Esha Twilight which differ in calculations from one country to another.


Organization
Angle of the sun under the Horizon (Fajr)
Angle of the sun under the Horizon (Isha)
Region
University Of Islamic Sciences, Karachi
18 Degrees
18 Degrees
Pakistan, Bangladesh,
India, Afghanistan, Parts of Europe
North America
15 Degrees
15 Degrees
Parts of the USA, Canada, Parts of the UK
Muslim World League
18 Degrees
17 Degrees
Europe, The Far East, Parts of the USA
Umm Al-Qura Committee
19 Degrees
90 minutes after the Sunset Prayer
120 minutes (in Ramadan only)
The Arabian Peninsula
Egyptian General Authority of Survey
19.5 Degrees
17.5 Degrees
Africa, Syria, Iraq, Lebanon, Malaysia, Parts of the USA


The only library used in this function was
#include <math.h>
to use the trigonometric functions (sin, cos,...)


The function takes the data of Year/Month/Day/Longitude/Latitude/TimeZone/FajrTwilight/IshaTwilight plus 6 references to double variables (Fajr/SunRise/Zuhr/Asr/Maghrib/Isha). These 6 variables are the ones to return data into. I also added some supporting functions to help in some number conversions (for example, Radians to Degrees and vise versa).

//convert Degree to Radian
double degToRad(double degree)
{
    return ((3.1415926 / 180) * degree);
}

//convert Radian to Degree
double radToDeg(double radian)
{
    return (radian * (180/3.1415926));
}

//make sure a value is between 0 and 360
double moreLess360(double value)
{
    while(value > 360 || value < 0)
    {
        if(value > 360)
            value -= 360;

        else if (value <0)
            value += 360;
    }

    return value;
}

//make sure a value is between 0 and 24
double moreLess24(double value)
{
    while(value > 24 || value < 0)
    {
        if(value > 24)
            value -= 24;

        else if (value <0)
            value += 24;
    }

    return value;
}

//convert the double number to Hours and Minutes
void doubleToHrMin(double number, int &hours, int &minutes)
{
    hours = floor(moreLess24(number));
    minutes = floor(moreLess24(number - hours) * 60);
}

void calcPrayerTimes(int year, int month, int day,
                     double longitude, double latitude, int timeZone,
                     double fajrTwilight, double ishaTwilight,
                     double &fajrTime, double &sunRiseTime, double &zuhrTime,
                     double &asrTime, double &maghribTime, double &ishaTime)
{
    double D = (367 * year) - ((year + (int)((month + 9) / 12)) * 7 / 4) + (((int)(275 * month / 9)) + day - 730531.5);

    double L = 280.461 + 0.9856474 * D;
    L = moreLess360(L);

    double M = 357.528 + (0.9856003) * D;
    M = moreLess360(M);

    double Lambda = L + 1.915 * sin(degToRad(M)) + 0.02 * sin(degToRad(2 * M));
    Lambda = moreLess360(Lambda);

    double Obliquity = 23.439 - 0.0000004 * D;
    double Alpha = radToDeg(atan((cos(degToRad(Obliquity)) * tan(degToRad(Lambda)))));
    Alpha = moreLess360(Alpha);

    Alpha = Alpha - (360 * (int)(Alpha / 360));
    Alpha = Alpha + 90 * (floor(Lambda / 90) - floor(Alpha / 90));

    double ST = 100.46 + 0.985647352 * D;
    double Dec = radToDeg(asin(sin(degToRad(Obliquity)) * sin(degToRad(Lambda))));
    double Durinal_Arc = radToDeg(acos((sin(degToRad(-0.8333)) - sin(degToRad(Dec)) * sin(degToRad(latitude))) / (cos(degToRad(Dec)) * cos(degToRad(latitude)))));

    double Noon = Alpha - ST;
    Noon = moreLess360(Noon);


    double UT_Noon = Noon - longitude;


    ////////////////////////////////////////////
    // Calculating Prayer Times Arcs & Times //
    //////////////////////////////////////////

    // 2) Zuhr Time [Local noon]
    zuhrTime = UT_Noon / 15 + timeZone;

    // Asr Hanafi
    //double Asr_Alt =radToDeg(atan(2 + tan(degToRad(abs(latitude - Dec)))));

    // Asr Shafii
    double Asr_Alt = radToDeg(atan(1 + tan(degToRad(abs(latitude - Dec)))));
    double Asr_Arc = radToDeg(acos((sin(degToRad(90 - Asr_Alt)) - sin(degToRad(Dec)) * sin(degToRad(latitude))) / (cos(degToRad(Dec)) * cos(degToRad(latitude)))));
    Asr_Arc = Asr_Arc / 15;
    // 3) Asr Time
    asrTime = zuhrTime + Asr_Arc;

    // 1) Shorouq Time
    sunRiseTime = zuhrTime - (Durinal_Arc / 15);

    // 4) Maghrib Time
    maghribTime = zuhrTime + (Durinal_Arc / 15);


    double Esha_Arc = radToDeg(acos((sin(degToRad(ishaTwilight)) - sin(degToRad(Dec)) * sin(degToRad(latitude))) / (cos(degToRad(Dec)) * cos(degToRad(latitude)))));
    // 5) Isha Time
    ishaTime = zuhrTime + (Esha_Arc / 15);

    // 0) Fajr Time
    double Fajr_Arc = radToDeg(acos((sin(degToRad(fajrTwilight)) - sin(degToRad(Dec)) * sin(degToRad(latitude))) / (cos(degToRad(Dec)) * cos(degToRad(latitude)))));
    fajrTime = zuhrTime - (Fajr_Arc / 15);

    return;
}



So, if I take Cairo as an example:
  • Date: 18-1-2012
  • Longitude: 30.2
  • Latitude: 30
  • Time Zone: +2 
  • Fajr Twilight: -19.5
  • Esha Twilight: -17.5
the function will be used like this:
double fajr, sunRise, zuhr, asr, maghrib, isha;
calcPrayerTimes(2012,1,18, 30.2, 30, 2, -19.5, -17.5, fajr, sunRise, zuhr, asr, maghrib, isha);

Note that these prayer times are still "double" and should be converted to a time format. I made the doubleToHrMin function (you can find it before the calcPrayerTimes fnction) which splits the number into Hours and Minutes. It takes the double and two references to int variables. Here is how to use it:

int hours, minutes;
doubleToHrMin(fajr, hours, minutes);

Now you have the prayer time as Hour/Minute to use it however you want.

So, in brief:
- I first add the above code block to my code, then use it whenever I want like this example:

double fajr, sunRise, zuhr, asr, maghrib, isha;
calcPrayerTimes(2012,1,18, 30.2, 30, 2, -19.5, -17.5,
                fajr, sunRise, zuhr, asr, maghrib, isha);

int hours, minutes;

doubleToHrMin(fajr, hours, minutes);
std::cout << "Fajr: " << hours << ":" << minutes << std::endl;

doubleToHrMin(sunRise, hours, minutes);
std::cout << "Sunrise: " << hours << ":" << minutes << std::endl;

doubleToHrMin(zuhr, hours, minutes);
std::cout << "Zuhr: " << hours << ":" << minutes << std::endl;

doubleToHrMin(asr, hours, minutes);
std::cout << "Asr: " << hours << ":" << minutes << std::endl;

doubleToHrMin(maghrib, hours, minutes);
std::cout << "Maghrib: " << hours << ":" << minutes << std::endl;

doubleToHrMin(isha, hours, minutes);
std::cout << "Isha: " << hours << ":" << minutes << std::endl;


(view the full prayer times example in this online IDE)

I hope it is useful to someone looking for the pure algorithm with no framework dependencies, and I hope I come back to it one more time to see the problem of these extra resulting minutes.


Resources:

جمعية الفلك بالقطيف
Muslim Programmers & Designers Community
Tanzil.info (1),(2)
PrayTime.info
IslamCity.com
IslamWare.com

Tuesday, June 29, 2010

C++ for Beginners: 2/2



هذا هو الجزء الثاني من C++ for Beginners و هدفه الأساسي التعريف ببعض الـ IDEs المستخدمة لإنشاء برامج C++ ذات واجهة رسومية GUI. لقد استخدمت اثنين بشكل أساسي و هما
Visual Studio
Qt
بالإضافة لمن رشّحوا استخدام NetBeans و Eclipse  و لكن لم أستخدمهم بعد. لذلك سأكتفي بالمقارنة بين ما استخدمته.

Platform:
Visual Studio : Works only on Windows
Qt: Works on Windows, Linux, Mac, Symbian … You just recompile your project on that platform to make a copy for it.
But if you only develop on Windows, this piece of info is not important.

GUI Design:
I liked the GUI in Qt much more than Visual Studio, because it has many useful elements, a variety of 3rd party classes, and a very very  important feature called ‘Layout’. It means that if you change the size of program window, the design will still fit inside it.

Debugging:
The debugging in Visual Studio is easier when debugging very big programs. But for normal programs, both Visual Studio and Qt are fine.

IntelliSense  (auto complete):
Both are fine, but Visual Studio has a more fancy one.

Event Handling:
Qt uses something called ‘Signals and Slots’ which makes event handling a lot easier than Visual Studio.

Documentation and Help:
Visual Studio is very popular, so there are a lot of forums that can help you. There are also lots of forums for Qt but not as much as Visual Studio.
For documentation, I found the documentation of Qt  more helpful than the MSDN of Visual Studio






بالنسبة لي فأنا أفضّل Qt أكثر من Visual Studio... و لكن يمكنكم أن تختبروهما و أي IDE آخر  تختارونه. ففي النهاية كل شخص يختار بناء على خبرات أو نقاط ذات اهتمام أكثر من الأخرى.


Websites to help:

NetBeans

Qt Free Reference:

Friday, June 25, 2010

C++ for Beginners: 1/2





لغة C++ هي واحدة من أقوى لغات البرمجة التي يمكنك تعلّمها دون مجهود كبير. فأساسيات اللغة ليست بالكثيرة و بالتالي سريعة الفهم و التعلّم. برامجها تمتاز بالسرعة. لا تعتمد على نظام تشغيل محدد فيمكن استخدامها على Windows, Linux, Mac.. بدون اختلافات. كما أنها لا تزال تتطوّر منذ ظهورها و بالتالي فهي تنافس لغات البرمجة الأخرى.


هذه بعض المصادر التي أنصح باستخدامها لتعلّم أساسيات C++ , و هي أساسيات يمكن تعلّمها في أبسط أشكال البرامج: Console Applications (أي برامج تتعامل فقط من خلال نصوص تظهر للمستخدم أو يدخلها المستخدم)


cplusplus.com
مصدر مثالي لتعلّم C++ من الصفر. يتكون من حوالي 140 صفحة تشمل الأساسيات التي يجب تعلّمها و تحتوي على بعض الأمثلة الصغيرة للتوضيح. هي غير كافية للتمكن من اللغة و لكنها تشكّل صورة كاملة عن اللغة يمكن البناء عليها من مصادر أكبر.


cprogramming.com
هذا المصدر أيضا يبدأ من الصفر و لكنه يحتوى على العديد من المواضيع المتقدمة التي يمكن الدخول فيها بعد التمكن من الأساسيات. و هو أيضا يشرح باستخدام أمثلة بسيطة لتوضيح كل نقطة.


C Frequently Asked Questions
أنصح بتصفحه و لكن بعد تعلّم أساسيات C++ , لأنه يناقش بعض الأخطاء التي قد نقع فيها أثناء البرمجة. أجده مفيدا للتأكد من مدى فهمي لبعض النقاط في C++


ثم المصدر المفضّل لدي:
C++ How to Program
هذا الكتاب رغم كثرة صفحاتة و طول الشرح في كل نقطة في C++ و كثرة الأمثلة التي قد تبدو مملة (على الأقل بالنسبة لي), إلا أنه مثالي في الشرح. فهو لا يعرّفني على إحدى النقاط و لكنه يشرحها بالفصيل و باحتمالاتها المختلفة, بل أيضا أفضل ممارسات البرمجة لكل نقطة من حيث تجنّب الأخطاء و زيادة السرعة. و مع الكتاب تأتي اسطوانة بها جميع الأمثلة المذكورة بالمتاب لتوفير وقت إعادة كتابتها. كما أن النسخة الجديدة من الكتاب بها مواضيع مهمة تخص تطوير C++ و أسباب بقاء C++ قوية و مستخدمة بكثرة حتى الآن.




أي من المصادر السابقة أجده كافيا لتعلّم C++ (مع اختلاف درجات الإتقان و تغطية المواضيع الجديدة). و بمعرفة هذه الأساسيات, نكون مستعدين للإنشاء البرامج ذات الواجهة الرسومية التي نستخدمها في كل برامجنا, و التي سأتحدث عنها في المرة القادمة.




بعض البرامج التي يمكن استخدامها:
في هذه المرحلة من تعلّم C++ , لا داعى لاستخدام أي من البرامج الكبيرة مثل Visual C++, و لكن تكفينا برامج بسيطة مثل: