PHPでホロスコープを描く

(1/1)
西洋占星術では、ある日の太陽、月、惑星と黄道十二宮の位置関係を表すホロスコープという図を用いる。今回は、物理学と天文学を使ってホロスコープを描く PHP プログラムを作ってみることにする。

余談になるが、参考書籍に紹介している『天文計算入門』の初版は 1978 年(昭和 53 年)に発刊され、これを買って、関数電卓「FX-31」でハレー彗星の位置計算を行ったのが、私のプログラミングの事始めで、もう 40 年も前の話になる。
今回のプログラムのアルゴリズムは、当時のものを踏襲している。地心黄経さえ求められれば、準惑星や彗星もホロスコープ上に配置することができる。

(2019 年 6 月 2 日)ラッキーカラー計算機能を追加した。

サンプル・プログラム:実行例

PHPでホロスコープを描く
「年月日」「誕生日の星座」を選択し「作成」ボタンをクリックすると、その日のホロスコープを描き、ラッキーカラーを表示する。
📅 の右側のテキストボックスをクリックすると、「PHP で日付入力:カレンダーから選択」で紹介したカレンダー入力を使った日付入力ができる。
このホロスコープは、左が春分点(黄経0 度)で、反時計回りに黄道十二宮を配置している。

サンプル・プログラム

圧縮ファイルの内容
horoscope.phpサンプル・プログラム本体
pahooAstronomy.php天文計算クラス pahooAstronomy。
使い方は「PHPでホロスコープを描く」などを参照。include_path が通ったディレクトリに配置すること。
pahooCalendar.php暦計算クラス pahooCalendar。
暦計算クラスの使い方は「PHPで日出没・月出没・月齢・潮を計算」を参照。include_path が通ったディレクトリに配置すること。
jsdate.js年月日セレクタを用意するJavaScript。
使い方は「jQueryで年月日セレクタを用意する」を参照。
/svg/*.svg黄道十二宮・惑星・月・太陽の記号(SVGファイル)。

サンプル・プログラムの流れ

プログラムの流れを単純化すると、
  1. 各惑星の日心座標を計算する。
  2. 各惑星(太陽、月を含む)の地心座標を計算する。
  3. ホロスコープを描く。
となる。

準備:定数

0031: //ホロスコープID
0032: define('HOROSCOPE', 'horoscope');
0033: 
0034: //ホロスコープを計算する時刻(日本標準時)
0035: define('HOUR', 21);
0036: 
0037: //ホロスコープの表示サイズ(単位:ピクセル)
0038: define('RADIUS', 300);                //外側の円の半径
0039: define('WIDTH1', 50);             //星座を描く部分の幅
0040: 
0041: //ホロスコープの表示色
0042: define('COLOR1', '#FFDD88');       //星座配置部分の色
0043: define('COLOR2', '#FFFFCC');       //惑星配置部分の色
0044: define('COLOR3', '#FFBB00');       //境界線の色
0045: define('COLOR4', '#0000FF');       //星座アイコンの色
0046: define('COLOR5', '#0000CC');       //惑星アイコンの色
0047: 
0048: //ホロスコープの表示色
0049: define('SVGPATH', './svg/');      //SVGアイコン・ファイルのパス名
0050: 
0051: //誕生日の星座(初期値)
0052: define('DEF_ZODIAC', 'Aries');

ホロスコープのサイズ、描画色などは定数にしている。自由に変更できる。

準備:アイコン・ファイルなど

0304: //黄道十二宮
0305: $Zodiac = array(
0306: //    英名              十二宮名    和名        記号    開始月日    開始黄経
0307: array('Aries',          '白羊宮', 'おひつじ座',   'U+2648', '0321',   0),
0308: array('Taurus',          '金牛宮', 'おうし座',   'U+2649', '0420',   30),
0309: array('Gemini',          '双児宮', 'ふたご座',   'U+264A', '0521',   60),
0310: array('Cancer',          '巨蟹宮', 'かに座',       'U+264B', '0622',   90),
0311: array('Leo',          '獅子宮', 'しし座',       'U+264C', '0723',   120),
0312: array('Virgo',          '処女宮', 'おとめ座',   'U+264D', '0823',   150),
0313: array('Libra',          '天秤宮', 'てんびん座',   'U+264E', '0923',   180),
0314: array('Scorpio',      '天蝎宮', 'さそり座',   'U+264F', '1024',   210),
0315: array('Sagittarius',  '人馬宮', 'いて座',       'U+2650', '1123',   240),
0316: array('Capricorn',      '磨羯宮', 'やぎ座',       'U+2651', '1222',   270),
0317: array('Aquarius',      '宝瓶宮', 'みずがめ座',   'U+2652', '0120',   300),
0318: array('Pisces',          '双魚宮', 'うお座',       'U+2653', '0219',   300)
0319: );

0321: //惑星・太陽・月
0322: $Planets = array(
0323: //    英名          和名        記号        カラー
0324: array('Sun',      '太陽',        'U+2609',    'D68E31'),
0325: array('Moon',      '',        'U+263D',    'DCDCDC'),
0326: array('Mercury',  '水星',        'U+263F',    'FFFF00'),
0327: array('Venus',      '金星',        'U+2640',    '00FF00'),
0328: array('Mars',      '火星',        'U+2642',    'FF0000'),
0329: array('Jupiter',  '木星',        'U+2643',    'F312D8'),
0330: array('Saturn',      '土星',        'U+2644',    '8B0000'),
0331: array('Uranus',      '天王星',    'U+2645',    '00FFFF'),
0332: array('Neptune',  '海王星',    'U+2646',    '00139F'),
0333: array('Pluto',      '冥王星',    'U+2647',    '000000'),
0334: array('Earth',      '地球',        'U+1F728',    '000000')
0335: );

ホロスコープ上に描く黄道十二宮や惑星の軌道は、UNICODE 文字に定義されているが、実装されていないフォントがあるようなので、Wikimedia Commons に収録されている SVG ファイルを利用させてもらった。
これらのファイルを、定数 SVGPATH に格納しておく。

準備:pahooAstronomy クラス

0010: require_once('pahooCalendar.php');
0011: 
0012: // pahooAstronomyクラス ======================================================
0013: class pahooAstronomy extends pahooCalendar {

天文計算を行うクラス pahooAstronomy は、クラス pahooCalendar を継承する。よって、クラスファイル "pahooAstronomy.php", "pahooCalendar.php" の 2 つを組み込み関数  require_once  を使って読めるディレクトリに配置する。

解説:惑星の日心座標を求める

0017: // 平均軌道要素
0018: var $PlanetOrbitalElements = array(
0019: 'Mercury' => array(
0020: 252.2509,    +4.0932377062,    +0.000303,        //L 平均黄経
0021: 77.4561, +1.556401,        +0.000295,        //ω 近日点黄経
0022: 48.3309, +1.186112,        +0.000175,        //Ω 昇交点黄経
0023: 7.0050,      +0.001821,                        //i 軌道傾角
0024: 0.205632,    +0.00002040,                  //e 軌道離心率
0025: +0.387098,    0.0                              //a 軌道長半径
0026: ),
0027: 'Venus' => array(
0028: 181.9798,    +1.602168732, +0.000310,        //L 平均黄経
0029: 131.5637,    +1.402152,        -0.001076,        //ω 近日点黄経
0030: 76.6799, +0.901044,        +0.000406,        //Ω 昇交点黄経
0031: 3.3947,      +0.001004,                        //i 軌道傾角
0032: 0.006772,    -0.00004778,                  //e 軌道離心率
0033: 0.723330,    0.0                              //a 軌道長半径
0034: ),
0035: 'Mars' => array(
0036: 355.4330,    +0.524071085, +0.000311,        //L 平均黄経
0037: 336.0602,    +1.840968,        +0.000135,        //ω 近日点黄経
0038: 49.5581, +0.772019,        +0.0,         //Ω 昇交点黄経
0039: 1.8497,      -0.000601,                        //i 軌道傾角
0040: 0.093401,    +0.00009048,                  //e 軌道離心率
0041: +1.523679,    0.0                              //a 軌道長半径
0042: ),
0043: 'Jupiter' => array(
0044: 34.3515, +0.083129439, +0.000223,        //L 平均黄経
0045: 14.3312, +1.612635,        +0.001030,        //ω 近日点黄経
0046: 100.4644,    +1.020977,        +0.000403,        //Ω 昇交点黄経
0047: 1.3033,      -0.005496,                        //i 軌道傾角
0048: 0.048498,    +0.00016323,                  //e 軌道離心率
0049: 5.202603,    0.0                              //a 軌道長半径
0050: ),
0051: 'Saturn' => array(
0052: 50.0774, +0.033497907, +0.000519,        //L 平均黄経
0053: 93.0572, +1.963761,        +0.000838,        //ω 近日点黄経
0054: 113.665, +0.877088,        -0.000121,        //Ω 昇交点黄経
0055: 2.4889,      -0.003736,                        //i 軌道傾角
0056: 0.055548,    -0.00034664,                  //e 軌道離心率
0057: 9.554909,    -0.0000021                        //a 軌道長半径
0058: ),
0059: 'Uranus' => array(
0060: 314.0550,    +0.011769036, +0.000304,        //L 平均黄経
0061: 173.0053,    +1.486378,        +0.000214,        //ω 近日点黄経
0062: 74.0060, +0.521127,        +0.001339,        //Ω 昇交点黄経
0063: 0.7732,      +0.000774,                        //i 軌道傾角
0064: 0.046381,    -0.00002729,                  //e 軌道離心率
0065: 19.218446,   -0.000003                     //a 軌道長半径
0066: ),
0067: 'Neptune' => array(
0068: 304.3487,    +0.006020077, +0.000309,        //L 平均黄経
0069: 48.1203, +1.426296,        +0.000384,        //ω 近日点黄経
0070: 131.784, +1.102204,        +0.000260,        //Ω 昇交点黄経
0071: 1.7700,      -0.009308,                        //i 軌道傾角
0072: 0.009456,    +0.00000603,                  //e 軌道離心率
0073: 30.110387,   0.0                              //a 軌道長半径
0074: ),
0075: 'Pluto' => array(
0076: 238.4670,    +0.00401596,  -0.0091,      //L 平均黄経
0077: 224.1416,    +1.3901,      +0.0003,      //ω 近日点黄経
0078: 110.3182,    +1.3507,      +0.0004,      //Ω 昇交点黄経
0079: 17.1451, -0.0055,                      //i 軌道傾角
0080: 0.249005,    +0.000039,                        //e 軌道離心率
0081: 39.540343,   +0.003131                     //a 軌道長半径
0082: )
0083: );

0085: /**
0086:  * ケプラー運動方程式の解法(漸化法)
0087:  * @param double $l 平均近点離角
0088:  * @param double $e 軌道離心率
0089:  * @return double 離心近点離角
0090: */
0091: function __kepler($l$e) {
0092:     $u0 = $l;
0093:     do {
0094:         $du = ($l - $u0 + rad2deg($e * sin(deg2rad($u0)))) / (1 - $e * cos(deg2rad($u0)));
0095:         $u1 = $u0 + $du;
0096:         $u0 = $u1;
0097:     } while(abs($du) < 1e-15);
0098: 
0099:     return $u1;
0100: }

0102: /**
0103:  * 惑星の日心黄道座標を計算
0104:  * @param string $planet 惑星名
0105:  * @param int $year, $month, $day  グレゴリオ暦による年月日
0106:  * @param double $hour, $min, $sec 時分秒(世界時)
0107:  * @return array(黄経,黄緯,動径)/FALSE:惑星名の間違い
0108: */
0109: function zodiacSun($planet$year$month$day$hour$min$sec) {
0110:     //平均軌道要素
0111:     if (! isset($this->PlanetOrbitalElements[$planet]))        return FALSE;
0112:     $tbl = $this->PlanetOrbitalElements[$planet];
0113: 
0114:     //計算開始
0115:     $d = $this->Gregorian2JD($year$month$day$hour$min$sec) - 2451544.5;
0116:     $T = $d / 36525.0;
0117: 
0118:     //平均軌道要素
0119:     $L     = $this->__angle($tbl[0] + $tbl[1] * $d + $tbl[2] * pow($T, 2));
0120:     $omega = $this->__angle($tbl[3] + $tbl[4] * $T + $tbl[5] * pow($T, 2));
0121:     $OMEGA = $this->__angle($tbl[6] + $tbl[7] * $T + $tbl[8] * pow($T, 2));
0122:     $i     = $tbl[9] + $tbl[10] * $T;
0123:     $e     = $this->__angle($tbl[11] + $tbl[12] * $T);
0124:     $a     = $tbl[13] + $tbl[14] * $T;
0125:     if ($planet == 'Uranus') {
0126:         $n = 255.65443 / pow($tbl[13], 1.5);
0127:         $a = $tbl[13] + $tbl[14] * $n * $T;
0128:     }
0129: 
0130:     $M = $this->__angle($L - $omega);      //平均近点離角
0131:     $E = $this->__kepler($M$e);         //離心近点離角
0132: 
0133:     $V = $this->__angle(2 * rad2deg(atan(pow((1 + $e) / (1 - $e), 0.5) * tan(deg2rad($E / 2)))));    
0134: 
0135:     $U = $omega + $V - $OMEGA;     //黄緯引数
0136:     $r = $a * (1 - pow($e, 2)) / (1 + $e * cos(deg2rad($V)));  //動径
0137:     $b = rad2deg(asin(sin(deg2rad($i)) * sin(deg2rad($U)))); //黄緯
0138:     $l = $OMEGA + rad2deg(atan(cos(deg2rad($i)) * sin(deg2rad($U)) / cos(deg2rad($U))));
0139:     if (cos(deg2rad($U)) < 0)   $l += 180;                        //黄経
0140: 
0141:     return array($l$b$r);
0142: }

日心黄道座標
太陽を中心とする、経度(黄経 mimetex )、緯度(黄緯 mimetex )、太陽から惑星への距離(動径 mimetex )の 3 つ組みで惑星の位置を表すことを日心黄道座標と呼ぶ。

惑星は、太陽を焦点の 1 つとする楕円軌道を描く。これは、1639 年(寛永 16 年)に発表されたケプラーの法則の第1 法則である。
ある日時の日心黄道座標を求めるメソッドは zodiacSun である。

日心黄道座標を求めるには、まず、指定された日時の軌道6要素(黄経 mimetex ,近日点黄経 mimetex ,昇交点黄経 mimetex ,軌道傾角 mimetex ,軌道離心率 mimetex ,軌道長半径 mimetex )を求める必要がある。
この計算式は『天文年鑑』に掲載されている。水星から海王星までは 2019 年(平成 31 年)版を、冥王星は 2006 年(平成 18 年)に準惑星に降格された後は掲載されていないため 2002 年(平成 14 年)版を参考にした。計算に使う係数はグローバル変数 $PlanetOrbitalElements に、計算式そのものはメソッド zodiacSun に実装した。

軌道6要素から日心黄道座標を求める計算式を示す。
 mimetex 
 mimetex 
 mimetex 
 mimetex 
 mimetex 
 mimetex 
 mimetex のとき mimetex 
 mimetex 
 mimetex :平均近点角, mimetex :真近点角, mimetex :黄緯引数, mimetex :動径, mimetex :黄経, mimetex :黄緯

真近点角 mimetex を求める計算式はケプラーの運動方程式と呼ばれるが、解析的に説く方法がなく、アイザック・ニュートンが『プリンキピア』において近似的に求める方法を紹介している。
  1.  mimetex 
  2.  mimetex 
  3.  mimetex 
  4.  mimetex 
2~4 の計算を mimetex が十分小さくなるまで繰り返す。今回のプログラムは、この近似式をそのまま実装し、メソッド[#__kepler:tutle=__kepler] とした。

解説:惑星の地心座標を求める

0144: /**
0145:  * 惑星の地心黄道座標を計算
0146:  * @param string $planet 惑星名
0147:  * @param int $year, $month, $day  グレゴリオ暦による年月日
0148:  * @param double $hour, $min, $sec 時分秒(世界時)
0149:  * @return array(黄経,黄緯,動径)
0150: */
0151: function zodiacEarth($planet$year$month$day$hour$min$sec) {
0152:     //日心黄道座標
0153:     $items = $this->zodiacSun($planet$year$month$day$hour$min$sec);
0154:     if (($items == FALSE|| (count($items) != 3))   return FALSE;
0155: 
0156:     $l = $items[0];      //日心黄経
0157:     $b = $items[1];      //日心黄緯
0158:     $r = $items[2];      //日心動径
0159: 
0160:     //太陽の黄経・黄緯
0161:     $ls = $this->longitude_sun($year$month$day$hour + $this->TDIFF$min$sec);
0162:     $rs = $this->distance_sun($year$month$day$hour + $this->TDIFF$min$sec);
0163: 
0164:     //直交座標へ変換
0165:     $X = $r * cos(deg2rad($b)) * cos(deg2rad($l)) + $rs * cos(deg2rad($ls));
0166:     $Y = $r * cos(deg2rad($b)) * sin(deg2rad($l)) + $rs * sin(deg2rad($ls));
0167:     $Z = $r * sin(deg2rad($b));
0168: 
0169:     //地心黄道座標変換
0170:     $r1 = sqrt(pow($X, 2) + pow($Y, 2) + pow($Z, 2));  //動径
0171:     $b1 = rad2deg(asin($Z / $r1));                       //黄緯
0172:     $l1 = rad2deg(atan($Y / $X));
0173:     if ($X < 0)     $l1 += 180;
0174:     $l1 = $this->__angle($l1);                            //黄経
0175: 
0176:     return array($l1$b1$r1);
0177: }

地心黄道座標
ホロスコープは、地球から見た空(天球)における惑星の位置を描くものである。これを地心黄道座標と呼ぶ。
ある日時の地心黄道座標を求めるメソッドは zodiacSun である。
すでに求めた日心黄道座標地心黄道座標に変換することは、天動説を地動説に逆変換するようなものだが、数学的には日心黄道座標に「PHP で二十四節気・七十二候一覧を作成」で紹介した太陽の黄経、黄緯、動径(地球からの距離)をベクトル加算することで求められる。

準備:ホロスコープを描く

0463: /**
0464:  * ホロスコープを描く
0465:  * @param int    $year, $month, $day  グレゴリオ暦による年月日
0466:  * @param string $zd 星座名(英名)
0467:  * @return string HTML BODY
0468: */
0469: function drawHoroscope($year$month$day$zd) {
0470:     $id = HOROSCOPE;
0471:     $radius = RADIUS;
0472:     $width1 = WIDTH1;
0473:     $color1 = COLOR1;
0474:     $color2 = COLOR2;
0475:     $color3 = COLOR3;
0476:     $js1 = drawZodiac();
0477:     $js2 = drawPlanets($year$month$day$zd);
0478: $js =<<< EOT
0479: <script>
0480: onload = function() {
0481:     initJsdate({$year}, {$month}, {$day});       //年月日セレクタ
0482: 
0483:     var canvas = document.getElementById('{$id}');
0484:     if ( ! canvas || ! canvas.getContext ) { return false; }
0485:     var ctx = canvas.getContext('2d');
0486:     var r = {$radius};
0487:     var cx = r;
0488:     var cy = r;
0489:     var x, y;
0490: 
0491:     ctx.strokeStyle ='{$color3}';
0492: 
0493:     ctx.fillStyle = '{$color1}';
0494:     ctx.beginPath();
0495:     ctx.arc(cx, cx, r, 0, Math.PI * 2, false);
0496:     ctx.stroke();
0497:     ctx.fill();
0498: 
0499:     ctx.fillStyle = '{$color2}';
0500:     ctx.beginPath();
0501:     ctx.arc(cx, cy, r - {$width1}, 0, Math.PI * 2, false);
0502:     ctx.stroke();
0503:     ctx.fill();
0504: 
0505:     //12分割
0506:     for (var i = 0; i < 12; i++) {
0507:         var th = Math.PI - Math.PI * 2 / 12 * i;
0508:         x = r + r * Math.cos(th);
0509:         y = r + r * Math.sin(th);
0510:         ctx.moveTo(cx, cy);
0511:         ctx.lineTo(x, y);
0512:         ctx.stroke();
0513:     }
0514:     //黄道十二宮
0515:     {$js1}
0516:     //惑星・太陽・月
0517:     {$js2}
0518: }
0519: </script>
0520: 
0521: EOT;
0522: 
0523:     return $js;
0524: }

ホロスコープは HTML5 の CANVAS 機能を使って描くことにする。

ユーザー関数 drawHoroscope では、まず、「jQuery で年月日セレクタを用意する」で紹介した年月日選択プルダウンを JavaScript に実装する。

続いて、ホロスコープの円盤を描き、黄道十二宮と惑星・太陽・月のアイコンを配置する。

準備:黄道十二宮と惑星・太陽・月

0442: /**
0443:  * 黄道十二宮アイコンを配置
0444:  * @param int $year, $month, $day  グレゴリオ暦による年月日
0445:  * @return string 描画スクリプト
0446: */
0447: function drawZodiac() {
0448:     global $Zodiac;
0449: 
0450:     $id = HOROSCOPE;             //CANVASID
0451:     $rd = RADIUS - (WIDTH1 * 0.5); //中心からの距離
0452:     $size = WIDTH1 * 0.7;         //アイコンのサイズ
0453:     $color = COLOR4;             //アイコンのカラー
0454:     $js = '';
0455:     for ($i = 0; $i < 12; $i++) {
0456:         $name = $Zodiac[$i][0];
0457:         $js .= drawIcon($i * 30 + 15, $rd$name$size$color$id);
0458:     }
0459: 
0460:     return $js;
0461: }

0402: /**
0403:  * 惑星アイコンを配置+ラッキーカラー計算
0404:  * @param int    $year, $month, $day  グレゴリオ暦による年月日
0405:  * @param string $zd 星座名(英名)
0406:  * @return string 描画スクリプト
0407: */
0408: function drawPlanets($year$month$day$zd) {
0409:     global $Planets;
0410: 
0411:     //オブジェクト生成
0412:     $pas = new pahooAstronomy();
0413: 
0414:     $id = HOROSCOPE;             //CANVASID
0415:     $size = WIDTH1 * 0.7;         //アイコンのサイズ
0416:     $color = COLOR5;             //アイコンのカラー
0417:     $js = '';
0418:     for ($i = 0; $i < 10; $i++) {
0419:         $name = $Planets[$i][0];
0420:         $rd = (RADIUS - WIDTH1 * 2) / 10 * $i + WIDTH1;
0421:         //太陽
0422:         if ($i == 0) {
0423:             $l = $pas->longitude_sun($year$month$dayHOUR, 0, 0);
0424:         //月
0425:         } else if ($i == 1) {
0426:             $l = $pas->longitude_moon($year$month$dayHOUR, 0, 0);
0427:         //惑星
0428:         } else {
0429:             $items = $pas->zodiacEarth($name$year$month$dayHOUR - $pas->TDIFF, 0, 0);
0430:             $l = $items[0];
0431:         }
0432:         $js .= drawIcon($l$rd$name$size$color$id);
0433:         calcColor($i$l$zd);
0434:     }
0435: 
0436:     //オブジェクト解放
0437:     $pas = NULL;
0438: 
0439:     return $js;
0440: }

黄道十二宮のアイコンを配置する位置を計算し、アイコンを配置するのはユーザー関数 drawZodiac である。同様に、惑星・太陽・月については、ユーザー関数 drawPlanets を用いる。
ホロスコープは平面なので、必要なのは地心黄経だけである。drawPlanets では、前述のメソッド zodiacEarth を使って惑星の地心黄経を、メソッド longitude_sun を使って太陽の黄経を、メソッド longitude_moon を使って月の黄経を求める。

準備:SVGアイコンを1つ描く

0366: /**
0367:  * SVGアイコンを1つ描く
0368:  * @param string $th    黄経(度)
0369:  * @param string $rd    中心からの距離(ピクセル)
0370:  * @param string $name  アイコン名(主ファイル名)
0371:  * @param string $size  アイコンのサイズ(ピクセル)
0372:  * @param string $color アイコンのカラー(RGB指定)
0373:  * @param string $id    CANVASのID
0374:  * @return string 描画スクリプト
0375: */
0376: function drawIcon($th$rd$name$size$color$id) {
0377:     //描画座標
0378:     $th = 180 - $th;
0379:     $th = deg2rad($th);
0380:     $x = RADIUS + $rd * cos($th) - $size / 2;
0381:     $y = RADIUS + $rd * sin($th) - $size / 2;
0382: 
0383:     //SVGファイルの読み込み
0384:     $fname = SVGPATH . $name . '.svg';
0385:     $svg = file_get_contents($fname);
0386:     $svg = preg_replace('/\#000000/ums', $color$svg);      //色指定
0387:     $svg = 'data:image/svg+xml;base64,' . base64_encode($svg);
0388: 
0389:     //スクリプト生成
0390: $js = <<< EOD
0391:     var img_{$name} = new Image();
0392:     img_{$name}.src = '{$svg}';
0393:     img_{$name}.onload = function() {
0394:         var ctx = document.getElementById('{$id}').getContext('2d');
0395:         ctx.drawImage(img_{$name}, {$x}, {$y}, {$size}, {$size});
0396:     }
0397: 
0398: EOD;
0399:     return $js;
0400: }

冒頭で用意したアイコン(SVG ファイル)を CANVAS 上に配置するのがユーザー関数 drawIcon である。
SVG ファイルを読み込み、デフォルトでは黒(#000000)で描画されている部分を指定カラーに置換する。
つづいて BASE64 エンコードを行い、JavaScript の Image オブジェクトのソースとして展開する。

配置場所は地心黄経(度)$th を代入するだけなので、準惑星や彗星でも地心黄道座標さえ分かれば、なんでも配置できる。

準備:ラッキーカラー計算

0340: /**
0341:  * ラッキーカラー計算
0342:  * @param int    $i  惑星番号
0343:  * @param float  $th 黄経(度)
0344:  * @param string $zd 星座名(英名)
0345:  * @return string 描画スクリプト
0346: */
0347: function calcColor($i$th$zd) {
0348:     global $Zodiac$Planets$Pcolor;
0349: 
0350:     foreach ($Zodiac as $val) {
0351:         if ($val[0] == $zd) {
0352:             $dd = ($th - $val[5] - 15);
0353:             if ($dd < (-180))    $dd += 360;
0354:             $dd = (180 - abs($dd)) / 180;
0355:             $Pcolor[0] += $dd;
0356:             for ($j = 0; $j < 3; $j++) {
0357:                 $cc = hexdec(substr($Planets[$i][3]$j * 2, 2));
0358:                 $cc *= $dd;
0359:                 $Pcolor[$j + 1] += $cc;
0360:             }
0361:             break;
0362:         }
0363:     }
0364: }

ユーザー関数 calcColor は、その日のラッキーカラーを計算する。
ラッキーカラーの計算アルゴリズムは、$Planets に定義した惑星カラーを合成するものである。誕生日星座の中心座標と各惑星の座標の黄経差に応じて、離れているものほど色が暗くなるように合成している。

参考サイト

参考書籍

表紙 新装改訂版 天文計算入門
著者 長谷川一郎
出版社 恒星社厚生閣
サイズ 単行本
発売日 1996年01月25日
価格 2,700円(税込)
rakuten
ISBN 9784769908180
 
表紙 天体の位置計算
著者 長沢工
出版社 地人書館
サイズ 単行本
発売日 1985年09月
価格 2,160円(税込)
rakuten
ISBN 9784805202258
 
(この項おわり)
header