PDA

View Full Version : حرفه ای: الگوریتم بدست آوردن اوقات شرعی



mohammad diba
پنج شنبه 05 فروردین 1389, 19:02 عصر
سلام بر دوستان بزرگوار سال نو مبارک
من نیاز به به الگوریتم دارم که اوقات شرعی هر منطقه را با توجه به طول یا عرض جغرافیایی بده نمی دونم چکار کنم . الگوریتمی برای این موضوع داریم؟ از کجا می تونم پیداش کنم.

mohammad diba
جمعه 06 فروردین 1389, 10:14 صبح
سلام کسی از دوستان نمی دونه اوقات شرعی شهرهای مختلف چه جوری به دست می اید . آخه معمولا تویه مساجد هر شهر به صورت یه جدول رو دیوار نصبه.

exlord
جمعه 06 فروردین 1389, 12:38 عصر
اینو بهتره از کسایی که تقویم مینویسن بپرسی ببینی چجوریه...........

ali_autumnal
جمعه 06 فروردین 1389, 13:50 عصر
سلام
من تقریبا نوشتم اما کمی ایراد داره موندم چطور رفعش کنم. تموم شد سورس و dll رو میخوام بزارم دوستان دانلود کنند.

اما اگه خواستید خودتون بنویسید این لینک رو بخونید. که دقیق ترین زمان رو اعلام میکنند. من هم از این مراجع استفاده کردم که کمی گیر کردم.

http://tanzil.info/praytime/doc/calculation/

تو این فایل الگوریتم بصورت یه فایل doc هست که من استفاده کردم. البته من از اینجا دانلود نکرم از سایت خوده پرفسر نمیدونم چی چی... الان آدرس دقیق رو پیدا نکردم اما در هر صورت همون فایل doc هست که من ام دانلود کردم.

http://www.islamway.com/flashes/7/PrayerTimes.zip

که این پرفسر میگه با این الگوریتم میشه واسه کل سالها با یکبار نوشتن الگوریتم، محاسبه دقیقی رو انجام داد!!

در ضمن اگه دوست داشتی میتونی تقویم من رو هم دانلود کنی که جایی واسه حرف زدن نداره:لبخند::لبخند::لبخند:
که اوقات شرعی رو هم کامل نوشتم بهش میخوام اضافه کنم.
http://barnamenevis.biz/forum/showthread.php?t=210562

mohammad diba
جمعه 06 فروردین 1389, 14:07 عصر
سلام خیلی ممون از راهنمایی تون
علی الظاهر شما راجع به تاریخ و این موارد خوب کار کرده اید از شما سپاسگزارم
می شه بیشتر توضیح بدید کجا مشکل دارید ؟ من آمادگی دارم تا این کد رو باهم تکمیل کنیم. رو من حساب کنید

ali_autumnal
جمعه 06 فروردین 1389, 15:56 عصر
سلام خیلی ممون از راهنمایی تون
علی الظاهر شما راجع به تاریخ و این موارد خوب کار کرده اید از شما سپاسگزارم
می شه بیشتر توضیح بدید کجا مشکل دارید ؟ من آمادگی دارم تا این کد رو باهم تکمیل کنیم. رو من حساب کنید

آره تقریبا...

باشه من کدهایی رو که گذاشتم رو میزارم اینجا شما هم چک کنید ببینیم ایراد کار کجاست.

ali_autumnal
جمعه 06 فروردین 1389, 16:16 عصر
من یه کلاس ایجاد کردم به اسم OghateSharei

متغیر های عمومی کلاس هستند:



public Boolean boolKeyTime = false; //Spring and Summery is True Autumn and Winter is False
public int intDayOfYear = 0, //1 Farvardin => intDayOfYear = 0 , 31 Farvardin => intDayOfYear = 30
intSh; // Sh=1 (Shafii) OR Sh=2 (Hanafi)
public double doubleLatitude, //B
doubleLongitude, //L
doubleTimeZone, //TZ
doubleAltitudeAboveSeaLevel;//H
public string strDawn = null, strSunrise = null, strNoon = null, strAfternoon = null, strSunset = null, strDusk = null;

یه تابع ای داره که کارش محاسبه n ^ m هست:




private double ExpTavan(double n, double m)
{
//e ~ 2.718281828
//========== Calculation n ^ m
//m = m * ln(n) => e ^ m
m=m*Math.Log(n,Math.E);

return Math.Exp(m);
}

یه تابع دیگه هست که مقدار گرفته شده رو تبدیل به ساعت و دقیقه و ثانیه میکنه:




private string DoubleToTime(double x)
{
x = Math.Floor(3600 * x);
double h = Math.Floor(x / 3600);
double mp = x - 3600 * h;
double m = Math.Floor(mp / 60);
double s = Math.Floor(mp - 60 * m);
if (boolKeyTime == true)
++h;
if (h < 10 && m < 10 && s < 10)
return "0" + h.ToString() + ":0" + m.ToString() + ":0" + s.ToString();
else if (h < 10 && m < 10 && s >= 10)
return "0" + h.ToString() + ":0" + m.ToString() + ":" + s.ToString();
else if (h < 10 && m >= 10 && s < 10)
return "0" + h.ToString() + ":" + m.ToString() + ":0" + s.ToString();
else if (h < 10 && m >= 10 && s >= 10)
return "0" + h.ToString() + ":" + m.ToString() + ":" + s.ToString();
else if (h >= 10 && m < 10 && s < 10)
return h.ToString() + ":0" + m.ToString() + ":0" + s.ToString();
else if (h >= 10 && m < 10 && s >= 10)
return h.ToString() + ":0" + m.ToString() + ":" + s.ToString();
else if (h >= 10 && m >= 10 && s < 10)
return h.ToString() + ":" + m.ToString() + ":0" + s.ToString();
else if (h >= 10 && m >= 10 && s >= 10)
return h.ToString() + ":" + m.ToString() + ":" + s.ToString();
return null;
}
و بصورت زیر تحویل میده:
12:01:10

یه تابع اصلی هست که کارش محاسبه توسط الگوریتم ای که در پست 3 گذاشتم:




public void PrayerTimesCalculation()
{
double doubleYearAngle = (2 * Math.PI * intDayOfYear)/365;

//========== Calculation D
double doubleSolarDeclination = ((180 / Math.PI) * (0.006918 -
(0.399912 * Math.Cos(doubleYearAngle)) + (0.070257 * Math.Sin(doubleYearAngle)) -
(0.006758 * Math.Cos(2 * doubleYearAngle)) + (0.000907 * Math.Sin(2 * doubleYearAngle)) -
(0.002697 * Math.Cos(3 * doubleYearAngle)) + (0.001480 * Math.Sin(3 * doubleYearAngle))));

//========== Calculation T
double doubleEquationOfTime = (229.18 * (0.000075 +
(0.001868 * Math.Cos(doubleYearAngle)) - (0.032077 * Math.Sin(doubleYearAngle)) -
(0.014615 * Math.Cos(2 * doubleYearAngle)) - (0.040849 * Math.Sin(2 * doubleYearAngle))));

//==========
double doubleRefLongitude = 15 * doubleTimeZone, //Degrees
G = 18; //Degrees

//========== Calculation Hours
double Z, U, Vd, Vn,W;
Z = 12 + ((doubleRefLongitude - doubleLongitude) / 15) - (doubleEquationOfTime / 60);

//========== Calculation H ^ 0.5
double h = Math.Abs(doubleAltitudeAboveSeaLevel);
h = ExpTavan(h, 0.5);

//========== Calculation U
U = (180 / (15 * Math.PI) *
Math.Acos((Math.Sin((-0.8333 - 0.0347 * Math.Sign(doubleAltitudeAboveSeaLevel) * h * (Math.PI / 180)) -
Math.Sin(doubleSolarDeclination * (Math.PI / 180)) * Math.Sin(doubleLatitude * (Math.PI / 180))) /
(Math.Cos(doubleSolarDeclination * (Math.PI / 180)) * Math.Cos(doubleLatitude * (Math.PI / 180))))));

//========== Calculation Vd
double doubleDawnsTwilightAngle=15, //Gd = (15°-19°)Degrees
doubleNightTwilightAngle=15; //Gn = (15°-19°)Degrees
Vd = (180 / (15 * Math.PI) *
Math.Acos((-Math.Sin(doubleDawnsTwilightAngle * Math.PI / 180) - Math.Sin(doubleSolarDeclination * Math.PI / 180) * Math.Sin(doubleLatitude * Math.PI / 180)) /
(Math.Cos(doubleSolarDeclination * Math.PI / 180) * Math.Cos(doubleLatitude * Math.PI / 180))));

//========== Calculation Vn
Vn = (180 / (15 * Math.PI) *
Math.Acos((-Math.Sin(doubleNightTwilightAngle * Math.PI / 180) - Math.Sin(doubleSolarDeclination * Math.PI / 180) * Math.Sin(doubleLatitude * Math.PI / 180)) /
(Math.Cos(doubleSolarDeclination * Math.PI / 180) * Math.Cos(doubleLatitude * Math.PI / 180))));

//========== Calculation W
//ArcCotan(x)= Arctan(1/x)
W = ((180 / (15 * Math.PI)) *
Math.Acos((Math.Sin(Math.Atan(1/(intSh + Math.Tan(Math.Abs(doubleLatitude - doubleSolarDeclination) * Math.PI / 180)))) - Math.Sin(doubleSolarDeclination * Math.PI / 180) * Math.Sin(doubleLatitude * Math.PI / 180)) /
(Math.Cos(doubleSolarDeclination * Math.PI / 180) * Math.Cos(doubleLatitude * Math.PI / 180))));

//========== Calculation Dawn سپیده دم
double Dawn = Z - Vd;
strDawn = DoubleToTime(Dawn);
//========== Calculation Sunrise طلوع آفتاب
double Sunrise = Z - U;
strSunrise = DoubleToTime(Sunrise);
//========== Calculation Noon ظهر
double Noon = Z;
strNoon = DoubleToTime(Noon);
//========== Calculation Afternoon بعدازظهر
double Afternoon = Z + W;
strAfternoon = DoubleToTime(Afternoon);
//========== Calculation Sunset غروب آفتاب
double Sunset = Z + U;
strSunset = DoubleToTime(Sunset);
//========== Calculation Dusk هنگام غروب
double Dusk = Z + Vn;
strDusk = DoubleToTime(Dusk);
}

روش فراخوانی این کلاس:



OghateSharei ogh = new OghateSharei();

خوب حالا باید شماره روز رو به متغیر intDayOfYear نسبت بدیم.
که اگه امروز رو 6 فروردین 89 فرض کنیم باید یه واحد ازش کم کنیم و به متغیر intDayOfYear مقدار دهی کنیم.


ogh.intDayOfYear = 5;
چون شیعه هستیم باید مقدار 1 رو به متغیر intSh بدیم:


ogh.intSh = 1;
طول عرض جغرافیایی شهر رو، که مثلا زنجان هست رو بهش میدیم:


ogh.doubleLatitude = 36.68;
ogh.doubleLongitude = 48.5;
ارتفاع شهر زنجان از سطح دریا رو هم میدیم:


ogh.doubleAltitudeAboveSeaLevel = 1663;

TimeZone رو هم مقدار دهی میکنیم:


ogh.doubleTimeZone = 3.5;

چون الان تو شش ماهه اول سال قرار داریم و یک ساعت ، زمان رو کشیدن جلو این متغیر بول رو هم مقداردهی میکنیم تا زمان رو هم یک ساعت به جلو بکشه:


ogh.boolKeyTime = true;
خوب حالا باید تابع اصلی رو فراخونی کنیم تا محاسبات رو انجام بده.


ogh.PrayerTimesCalculation();

حالا بعداز فراخونی میتونیم از مقادیر متغیرهایی عمومی که رشته ای هستند استفاده کنیم.
متغیر هامون اینا بودن که خودتون از شون هرطور که دوست دارید استفاده کنید: (توج در بالا اینا تعریف شدن فقط خواستم بگم که این متغیر ها هستند.)


public string strDawn = null, strSunrise = null, strNoon = null, strAfternoon = null, strSunset = null, strDusk = null;



و اما ایراد کار اینه که فقط 2 الی 3 تا از زمان ها درست نشون میده!

کدها ها رو با الگوریتم بررسی کنید تا ایرادات رو باهم رفع کنیم.

ali_autumnal
جمعه 06 فروردین 1389, 16:51 عصر
در ضمن جهت اطلاع و مقایسه و صحت مقدیر بدست آمده میتونید به لینک زیر مراجعه کنید:

http://www.owghat.com/default.aspx#

mohammad diba
شنبه 07 فروردین 1389, 08:07 صبح
راستی علی اقا چرای برای توان از Math.Exp استفاده نکردی دلیل خاصی داشتی؟

ali_autumnal
شنبه 07 فروردین 1389, 09:54 صبح
راستی علی اقا چرای برای توان از Math.Exp استفاده نکردی دلیل خاصی داشتی؟

استفاده کردم یه نگاه بندازید!

چون n ^ m هستش و m میتونه هر عددی باشه مثله: 0.5 در نتیجه باید اول ln گرفت بعد از Exp استفاده کرد.