Teste live coding
forked from MoonPhase (diff: 1)
ActionScript3 source code
/**
* Copyright rodrigocardozo ( http://wonderfl.net/user/rodrigocardozo )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/6xN8
*/
// forked from flashrod's MoonPhase
package {
import flash.display.Shape;
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.display.Loader;
/** 月齢表示 */
[SWF(backgroundColor="0x000000")]
public class MoonPhase extends Sprite {
private static const DELTA:Number = 1e-2; // 朔を求めるときの閾値
/** 画像サイズ */
public static const SIZE:int = 200;
/** 初期化 */
public function MoonPhase() {
var ud:Date = new Date(); // 今日の日付
var jd:JulianDay = JulianDay.create(ud);
var a:Number = round360(calcAngle(jd)); // 朔からの角度(°)
// 影と明るい部分がある月のイメージを作る
var loader:Loader = new Loader();
var url:String = "http://wonderfl.net/static/tmp/related_images/9400354c5bd4a35f9f6cdd7bf1bb8ede13be3c2em";
loader.load(new URLRequest(url));
addChild(loader);
addChild(new Phase(a));
// 角度から月齢を得る
var label:TextField = new TextField();
label.autoSize = TextFieldAutoSize.LEFT;
label.text = ageStr(calcAge(jd, a));
label.textColor = 0xFFFFFF;
label.y = SIZE-16;
addChild(label);
var stat:TextField = new TextField();
stat.autoSize = TextFieldAutoSize.LEFT;
stat.text = new ISO8601Date(ud).toString();
stat.textColor = 0xFFFFFF;
addChild(stat);
}
/** 月齢を表記文字列にする
*/
private function ageStr(a:Number):String {
var s:String = String(a);
var i:int = s.indexOf(".");
if (i >= 0 && i < (s.length - 2)) {
s = s.substring(0, i + 2);
}
return s;
}
/** 角度から月齢を計算する.
* @param jd 今の日付時刻
* @param a 角度(°)
* @return 月齢(0.0~29.9くらい)
*/
private function calcAge(jd:JulianDay, a:Number):Number {
var d:Number = jd.doubleValue(); // 今のユリアン日
// 朔のユリアン日を求める.
for (var i:int = 0; i < 10; ++i) { // 無限ループにならないように、最大10回
d -= a * 29 / 360; // 概算で角度から朔までの日数を引く
a = calcAngle(JulianDay.build(d));
if (Math.abs(a) < DELTA) // 角度が0に近かったら朔とみなす
break;
}
return jd.doubleValue() - d; // 今の日から朔の日までの差が月齢
}
/** 指定された日の、地球から見た月と太陽のなす角度を得る.
* @param jd 指定日
* @return 角度(°)
*/
public function calcAngle(jd:JulianDay):Number {
var sun:Lucky = Sun.getPos(jd); // 地球から見た太陽の位置
var moon:Lucky = Moon.getPos(jd); // 地球から見た月の位置
var s:Number = moon.lng - sun.lng; // 朔からの角度
return s;
}
/** 0から360の間に押さえ込む
* @param a 角度(°)
* @return aを0から360の間に押さえ込んだ値
*/
public function round360(a:Number):Number {
while (a < 0)
a += 360;
while (a > 360)
a -= 360;
return a;
}
}
}
/** 日付時刻の表記 */
class ISO8601Date {
/** 日付時刻 */
private var cal:Date;
/**
* @param cal 日付時刻
*/
public function ISO8601Date(cal:Date) { this.cal = cal; }
/**
*/
public static function tttt(t:int):String {
var sign:String = signChar(t);
t = Math.abs(t);
var h:int = t / 60;
var m:int = t % 60;
return sign + format2(h) + format2(m);
}
/**
* @return ISO8601形式日付文字列
*/
public function toString():String {
var y:int = cal.fullYear;
var m:int = cal.month + 1;
var d:int = cal.date;
var h:int = cal.hours;
var min:int = cal.minutes;
var s:int = cal.seconds;
var tz:String = tttt(cal.getTimezoneOffset());
return y + "-" + format2(m) + "-" + format2(d)
+ " " + format2(h) + ":" + format2(min) + ":" + format2(s) + tz;
}
/** 頭に0をつけてでも二桁の数値表現にする
* @param a a
* @return formatted string
*/
public static function format2(a:Number):String {
var s:String = "0" + a.toString();
return s.substring(s.length - 2);
}
/** 符号文字を戻す
* @param a 実数
* @return " ":正または零 、 "-":負
*/
public static function signChar(a:Number):String {
if (a < 0) {
return "-";
}
return "+";
}
}
/** ユリアン日 */
class JulianDay {
public var fix:int; // 整数部
public var dec:Number; // 小数部 decimal
/** ユリアン日の整数部と小数部からユリアン日を生成する.
* @param fix ユリアン日の整数部
* @param dec ユリアン日の少数部
* @return ユリアン日
*/
public function JulianDay(fix:int, dec:Number) {
this.fix = fix;
this.dec = dec;
}
public static function build(a:Number):JulianDay {
var fix:int = Math.floor(a);
var dec:Number = a - fix;
return new JulianDay(fix, dec);
}
/** 日付時刻からユリアン日を生成する.
* @param ud 日付時刻
* @return ユリアン日
*/
public static function create(ud:Date):JulianDay {
var year:int = ud.fullYearUTC;
var month:int = ud.monthUTC+1; // Dateは1月が0
var day:int = ud.dateUTC;
var hour:int = ud.hoursUTC;
var min:int = ud.minutesUTC;
var sec:int = ud.secondsUTC;
var j:int; // ユリアン日整数部
var d:Number; // ユリアン日小数部
var bc:Boolean = (year <= 0);
/* グレゴリアンカレンダーの最初の日 */
var gregory:Boolean = (year > 1582)
|| (year == 1582 && month > 10)
|| (year == 1582 && month == 10 && day >= 15);
if (month <= 2) {
year--;
month += 12;
}
if (hour < 12) {
j = 0;
d = 0.5;
} else {
j = 1;
d = -0.5;
}
d += (hour*3600 + min*60 + sec)/86400.0;
j += bc ? int((year-3)/4) : int(year/4);
if (gregory)
j += 2 - int(year/100) + int(year/400);
j += 1720994 + year*365 + (month+1)*30 + int((month+1)*3/5) + day;
return new JulianDay(j, d);
}
/** ユリアン日からグリニッジ標準時カレンダーを得る.
* @return 日付時刻
*/
public function toUniversalTime():Date {
var j:int = this.fix;
var d:Number = this.dec;
// 標準時計算用変数
var year:int;
var month:int;
var day:int;
var hour:int;
var min:int;
var sec:int;
var c:int;
var k:int;
var e:int;
var s:int;
if (d >= 0.5) {
j++;
d -= 0.5;
} else {
d += 0.5;
}
if (j >= 2299161) {
j = j + 1 + (j-1867216)/36524 - (j-1867216)/146096;
}
j += 1524;
c = (int)((j - 122.1) / 365.25);
k = 365*c + c/4;
e = (int)((j - k) / 30.6001);
year = c - 4716;
month = e - 1;
if (month > 12) {
month -= 12;
year++;
}
day = j - k - int(30.6*e);
s = int(d * 86400 + 0.5);
hour = s / 3600;
min = (s % 3600) / 60;
sec = s % 60;
var cal:Date = new Date(); //.getInstance(TimeZone.getTimeZone("GMT"));
cal.fullYearUTC = year;
cal.monthUTC = month-1;
cal.dateUTC = day;
cal.hoursUTC = hour;
cal.minutesUTC = min;
cal.secondsUTC = sec;
return cal;
}
/** ユリアン日を実数で表す.
* @return ユリアン日を実数で表す値
*/
public function doubleValue():Number {
return fix + dec;
}
/** ユリアン日を表示用の文字列化に変換する.
* @return 表示用文字列
*/
public function toString():String {
return "<JulianDay fix="+fix+" dec="+dec+"/>";
}
}
/** 黄経と黄緯クラス
*/
class Lucky {
public var lng:Number; // 黄経(単位 度)
public var lat:Number; // 黄緯(単位 度)
public var dist:int; // 地心距離(月/太陽中心間の距離)(単位 キロメートル)
/** 黄経黄緯を生成する.
* @param lng 黄経(単位 度)
* @param lat 黄緯(単位 度)
* @param dist 地心距離(月/太陽中心間の距離)(単位 キロメートル)
*/
public function Lucky(lng:Number, lat:Number, dist:int) {
this.lng = lng;
this.lat = lat;
this.dist = dist;
}
/** 黄経黄緯を表示できる文字列を得る */
public function toString():String {
return "<Lucky lng="+lng+" lat="+lat+" dist="+dist+"/>";
}
}
/** 太陽位置計算クラス
* 海上保安庁水路部による太陽の位置の略算式
*/
class Sun {
private static const K:int = 0;
private static const A:int = 1;
private static const B:int = 2;
private static const l:Array = [
[ 1.9147, 35999.05, 267.52 ], [ -0.0048, 35999.05, 267.52 ],
[ 0.0200, 71998.1, 265.1 ], [ 0.0020, 32964.0, 158.0 ],
[ 0.0018, 19.0, 159.0 ], [ 0.0018, 445267.0, 208.0 ],
[ 0.0015, 45038.0, 254.0 ], [ 0.0013, 22519.0, 352.0 ],
[ 0.0007, 65929.0, 45.0 ], [ 0.0007, 3035.0, 110.0 ],
[ 0.0007, 9038.0, 64.0 ], [ 0.0006, 33718.0, 316.0 ],
[ 0.0005, 155.0, 118.0 ], [ 0.0005, 2281.0, 221.0 ],
[ 0.0004, 29930.0, 48.0 ], [ 0.0004, 31557.0, 161.0 ]];
private static const c:Array = [
[ 0.016706, 35999.05, 177.53 ], [ -0.000042, 35999.05, 177.53 ],
[ 0.000139, 71998.0, 175.0 ], [ 0.000031, 445267.0, 298.0 ],
[ 0.000016, 32964.0, 68.0 ], [ 0.000016, 45038.0, 164.0 ],
[ 0.000005, 22519.0, 233.0 ], [ 0.000005, 33718.0, 226.0 ]];
/** 太陽の位置を得る.
* @param jd ユリアン日.
* @return 黄経黄緯
*/
public static function getPos( jd:JulianDay):Lucky {
var j:int = jd.fix;
var d:Number = jd.dec;
var t:Number = (j + d - 2451545.0)/36525.0;
var s:Number = 280.4659 + 36000.7695 * t;
for (var i:int = 0; i < 16; i++) {
var r:Number = l[i][A] * t + l[i][B];
s += l[i][K] * Math.cos(r * 0.017453292519943);
}
while (s < 0)
s += 360.0;
while (s >= 360.0)
s -= 360.0;
var lng:Number = s;
s = 1.000140;
for ( i = 0; i < 8; i++) {
r = c[i][A] * t + c[i][B];
s += c[i][K] * Math.cos(r * 0.017453292519943);
}
var dist:int = (int)(s * 149597870.0);
return new Lucky(lng, 0, dist);
}
}
/** 月位置計算クラス.
* 海上保安庁水路部による月の位置の略算式
*/
class Moon {
private static const K:int = 0;
private static const A:int = 1;
private static const B:int = 2;
private static const ln:Array = [
[ 6.2888, 477198.868, 44.963 ],[ 1.274, 413335.35, 10.74 ],
[ 0.6583, 890534.22, 145.7 ], [ 0.2136, 954397.74, 179.93 ],
[ 0.1851, 35999.05, 87.53 ], [ 0.1144, 966404.0, 276.5 ],
[ 0.0588, 63863.5, 124.2 ], [ 0.0571, 377336.3, 13.2 ],
[ 0.0533,1367733.1, 280.7 ], [ 0.0458, 854535.2, 148.2 ],
[ 0.0409, 441199.8, 47.4 ], [ 0.0347, 445267.1, 27.9 ],
[ 0.0304, 513179.9, 222.5 ], [ 0.0154, 75870.0, 41.0 ],
[ 0.0125,1443603.0, 52.0 ], [ 0.0110, 489205.0, 142.0 ],
[ 0.0107,1303870.0, 246.0 ], [ 0.0100,1431597.0, 315.0 ],
[ 0.0085, 826671.0, 111.0 ], [ 0.0079, 449334.0, 188.0 ],
[ 0.0068, 926533.0, 323.0 ], [ 0.0052, 31932.0, 107.0 ],
[ 0.0050, 481266.0, 205.0 ], [ 0.0040,1331734.0, 283.0 ],
[ 0.0040,1844932.0, 56.0 ], [ 0.0040, 133.0, 29.0 ],
[ 0.0038,1781068.0, 21.0 ], [ 0.0037, 541062.0, 259.0 ],
[ 0.0028, 1934.0, 145.0 ], [ 0.0027, 918399.0, 182.0 ],
[ 0.0026,1379739.0, 17.0 ], [ 0.0024, 99863.0, 122.0 ],
[ 0.0023, 922466.0, 163.0 ], [ 0.0022, 818536.0, 151.0 ],
[ 0.0021, 990397.0, 357.0 ], [ 0.0021, 71998.0, 85.0 ],
[ 0.0021, 341337.0, 16.0 ], [ 0.0018, 401329.0, 274.0 ],
[ 0.0016,1856938.0, 152.0 ], [ 0.0012,1267871.0, 249.0 ],
[ 0.0011,1920802.0, 186.0 ], [ 0.0009, 858602.0, 129.0 ],
[ 0.0008,1403732.0, 98.0 ], [ 0.0007, 790672.0, 114.0 ],
[ 0.0007, 405201.0, 50.0 ], [ 0.0007, 485333.0, 186.0 ],
[ 0.0007, 27864.0, 127.0 ], [ 0.0006, 111869.0, 38.0 ],
[ 0.0006,2258267.0, 156.0 ], [ 0.0005,1908795.0, 90.0 ],
[ 0.0005,1745069.0, 24.0 ], [ 0.0005, 509131.0, 242.0 ],
[ 0.0004, 39871.0, 223.0 ], [ 0.0004, 12006.0, 187.0 ],
[ 0.0003, 958465.0, 340.0 ], [ 0.0003, 381404.0, 354.0 ],
[ 0.0003, 349472.0, 337.0 ], [ 0.0003,1808933.0, 58.0 ],
[ 0.0003, 549197.0, 220.0 ], [ 0.0003, 4067.0, 70.0 ],
[ 0.0003,2322131.0, 191.0 ]];
private static const la:Array = [
[ 5.1281, 483202.019, 3.273], [ 0.2806, 960400.89, 138.24 ],
[ 0.2777, 6003.15, 48.31 ], [ 0.1733, 407332.20, 52.43 ],
[ 0.0554, 896537.4, 104.0 ], [ 0.0463, 69866.7, 82.5 ],
[ 0.0326,1373736.2, 239.0 ], [ 0.0172,1437599.8, 273.2 ],
[ 0.0093, 884531.0, 187.0 ], [ 0.0088, 471196.0, 87.0 ],
[ 0.0082, 371333.0, 55.0 ], [ 0.0043, 547066.0, 217.0 ],
[ 0.0042,1850935.0, 14.0 ], [ 0.0034, 443331.0, 230.0 ],
[ 0.0025, 860538.0, 106.0 ], [ 0.0022, 481268.0, 308.0 ],
[ 0.0022,1337737.0, 241.0 ], [ 0.0021, 105866.0, 80.0 ],
[ 0.0019, 924402.0, 141.0 ], [ 0.0018, 820668.0, 153.0 ],
[ 0.0018, 519201.0, 181.0 ], [ 0.0018,1449606.0, 10.0 ],
[ 0.0015, 42002.0, 46.0 ], [ 0.0015, 928469.0, 121.0 ],
[ 0.0015, 996400.0, 316.0 ], [ 0.0014, 29996.0, 129.0 ],
[ 0.0013, 447203.0, 6.0 ], [ 0.0013, 37935.0, 65.0 ],
[ 0.0011,1914799.0, 48.0 ], [ 0.0010,1297866.0, 288.0 ],
[ 0.0009,1787072.0, 340.0 ], [ 0.0008, 972407.0, 235.0 ],
[ 0.0007,1309873.0, 205.0 ], [ 0.0006, 559072.0, 134.0 ],
[ 0.0006,1361730.0, 322.0 ], [ 0.0005, 848532.0, 190.0 ],
[ 0.0005, 419339.0, 149.0 ], [ 0.0005, 948395.0, 222.0 ],
[ 0.0004,2328134.0, 149.0 ], [ 0.0004,1024264.0, 352.0 ],
[ 0.0003, 932536.0, 282.0 ], [ 0.0003,1409735.0, 57.0 ],
[ 0.0003,2264270.0, 115.0 ], [ 0.0003,1814936.0, 16.0 ],
[ 0.0003, 335334.0, 57.0 ]];
private static const lc:Array = [
[ 0.051820, 477198.868,134.963], [ 0.009530, 413335.35, 100.74 ],
[ 0.007842, 890534.22, 235.7 ], [ 0.002824, 954397.74, 269.93 ],
[ 0.000858,1367733.1, 10.7 ], [ 0.000531, 854535.2, 238.2 ],
[ 0.000400, 377336.3, 103.2 ], [ 0.000319, 441199.8, 137.4 ],
[ 0.000271, 445267.0, 118.0 ], [ 0.000263, 513198.0, 312.0 ],
[ 0.000197, 489205.0, 232.0 ], [ 0.000173,1431597.0, 45.0 ],
[ 0.000167,1303870.0, 336.0 ], [ 0.000111, 35999.0, 178.0 ],
[ 0.000103, 826671.0, 201.0 ], [ 0.000084, 63864.0, 214.0 ],
[ 0.000083, 926533.0, 53.0 ], [ 0.000078,1844932.0, 146.0 ],
[ 0.000073,1781068.0, 111.0 ], [ 0.000064,1331734.0, 13.0 ],
[ 0.000063, 449334.0, 278.0 ], [ 0.000041, 481266.0, 295.0 ],
[ 0.000034, 918399.0, 272.0 ], [ 0.000033, 541062.0, 349.0 ],
[ 0.000031, 922466.0, 253.0 ], [ 0.000030, 75870.0, 131.0 ],
[ 0.000029, 990397.0, 87.0 ], [ 0.000026, 818536.0, 241.0 ],
[ 0.000023, 553069.0, 266.0 ], [ 0.000019,1267871.0, 339.0 ],
[ 0.000013,1403732.0, 188.0 ], [ 0.000013, 341337.0, 106.0 ],
[ 0.000013, 401329.0, 4.0 ], [ 0.000012,2258267.0, 246.0 ],
[ 0.000011,1908795.0, 180.0 ], [ 0.000011, 858602.0, 219.0 ],
[ 0.000010,1745069.0, 114.0 ], [ 0.000009, 790672.0, 204.0 ],
[ 0.000007,2322131.0, 281.0 ], [ 0.000007,1808933.0, 148.0 ],
[ 0.000006, 485333.0, 276.0 ], [ 0.0000006, 99863.0, 212.0 ],
[ 0.000005, 405201.0, 140.0 ]];
/** 月の位置を得る.
* @param jd ユリアン日.
* @return 黄経黄緯
*/
public static function getPos( jd:JulianDay):Lucky {
var lng:Number;
var lat:Number;
var j:int = jd.fix;
var d:Number = jd.dec;
var t:Number = (j + d - 2451545.0)/36525.0;
var s:Number = 218.3162 + 481267.8809 * t;
var r:Number;
for (var i:int = 0; i < 61; i++) {
r = ln[i][A] * t + ln[i][B];
s += ln[i][K] * Math.cos(r * 0.017453292519943);
}
while (s < 0)
s += 360.0;
while (s >= 360.0)
s -= 360.0;
lng = s;
s = 0.0;
for ( i = 0; i < 45; i++) {
r = la[i][A] * t + la[i][B];
s += la[i][K] * Math.cos(r * 0.017453292519943);
}
while (s < 0)
s += 360.0;
while (s >= 360.0)
s -= 360.0;
lat = s;
s = 0.950725;
for ( i = 0; i < 43; i++) {
r = lc[i][A] * t + lc[i][B];
s += lc[i][K] * Math.cos(r * 0.017453292519943);
}
var dist:int = (int)(6378.14 / Math.sin(s * 0.017453292519943));
return new Lucky(lng, lat, dist);
}
}
import flash.display.Shape;
/** 月の満ち欠けを表現するイメージフィルタ.
*/
class Phase extends Shape {
public static const R:int = MoonPhase.SIZE/2; // 半径(ピクセル単位)
public static const R2:int = R*R; // 半径の自乗
/**
* @param angle 朔からの角度(°)(0~360)
*/
public function Phase(angle:int) {
var quoter:int = angle / 90; // 見た目の象限(0~3)
var cos:Number = Math.cos(angle * Math.PI / 180);
// 半透明の黒で影部を描く
graphics.lineStyle(1, 0x000000, 0.6);
for (var j:int = 0; j < MoonPhase.SIZE; ++j) {
var y:Number = j - R;
var y2:Number = y * y;
var x:Number = cos * Math.sqrt(R2 - y2);
switch (quoter) {
case 0:
graphics.moveTo(0, j);
graphics.lineTo(R + x, j);
break;
case 1:
graphics.moveTo(0, j);
graphics.lineTo(R + x, j);
break;
case 2:
graphics.moveTo(R - x, j);
graphics.lineTo(MoonPhase.SIZE, j);
break;
case 3:
graphics.moveTo(R - x, j);
graphics.lineTo(MoonPhase.SIZE, j);
break;
}
}
}
}