月齢計算


Small BasicのClockオブジェクトって、時計以外になんか使えないかなー……ということで。

月齢 - Wikipedia

月齢、つまり月の満ち欠けを簡単に計算する方法があるらしいです。
あくまで簡易計算法なので多少ズレたりするようですが……。
上の通りに月齢を求めるプログラムを書いてみましょう。変数aとbはそのまま流用しました。
割り算の余りは「Math.Remainder(dividend, divisor)」で求められます。

a = Math.Remainder((Clock.Year - 11), 19) * 11

If Clock.Month = 1 Or Clock.Month = 3 Then
  b = 0
ElseIf Clock.Month = 2 Or Clock.Month = 4 Or Clock.Month = 5 Then
  b = 2
Else
  b = Clock.Month - 2
EndIf

Getsurei = Math.Remainder((a + b + Clock.Date), 30)

GraphicsWindow.DrawText(1, 1, Clock.Year + "年" + Clock.Month + "月" + Clock.Date + "日の月齢は、" + Getsurei + "です。")

これを実行すると、今日の月齢が求められますね。
これだけでは芸がないので、テキストボックスとボタンを設置して、「知りたい日の月齢を求めるプログラム」にしてみましょう。
更に、その月齢の月の図を表示してみます。
月齢に応じた月の形は検索すれば色々と出てきますが、それをどう描くかが問題になりますね。
月そのものは円なので、「Shapes.AddEllipse」あたりで円を描けば良いのですが、満ち欠け部分をどうするか。
例えば三日月であれば、円を半分消して(四角形を被せるとかして)半円にした後に、更に楕円を被せて半円の一部分を消せば良さそう。
三日月は月齢=2、半月は月齢=7です。
背景が黒として、

GraphicsWindow.BrushColor = "Yellow"
GraphicsWindow.PenColor = "Yellow"
tuki1 = Shapes.AddEllipse(100, 100)
GraphicsWindow.BrushColor = "Black"
GraphicsWindow.PenColor = "Black"
tuki2haba = 100 * (7 - Getsurei) / 7
tuki2 = Shapes.AddEllipse(tuki2haba, 100)
tuki3 = Shapes.AddRectangle(50, 100)
Shapes.Move(tuki1, 10, 170)
Shapes.Move(tuki2, 10+50-tuki2haba/2, 170)
Shapes.Move(tuki3, 10, 170)

tuki1が月の円部分、tuki2が楕円、tuki3は月を半分消す為の四角形です。
楕円部分の横幅を月齢によって変化させています。
月齢が0から7の間ならこれで良さそう。
これを応用して、月齢が0から29まで場合分けして描いていけば完成です。

GraphicsWindow.Title = "月齢"
GraphicsWindow.Width = 250
GraphicsWindow.Height = 300
GraphicsWindow.BackgroundColor = "Black"
GraphicsWindow.BrushColor = "Black"
GraphicsWindow.PenColor = "White"
GraphicsWindow.FontSize = 16

yearbox = Controls.AddTextBox(1,1)
monthbox = Controls.AddTextBox(80,1)
daybox = Controls.AddTextBox(140,1)
Controls.SetSize(yearbox, 50, 30)
Controls.SetSize(monthbox, 30, 30)
Controls.SetSize(daybox, 30, 30)

'初期状態では、今日の日付をテキストボックスに入力しておく
Controls.SetTextBoxText(yearbox, Clock.Year)
Controls.SetTextBoxText(monthbox, Clock.Month)
Controls.SetTextBoxText(daybox, Clock.Day)

GraphicsWindow.BrushColor = "White"
GraphicsWindow.DrawText(53, 4 ,"年         月         日")

GraphicsWindow.BrushColor = "Black"
getreibutton = Controls.AddButton("月齢", 1, 50)
Controls.ButtonClicked = Getsurei

Sub Getsurei
  If Controls.LastClickedButton = getreibutton Then
    year = Controls.GetTextBoxText(yearbox)
    month = Controls.GetTextBoxText(monthbox)
    day = Controls.GetTextBoxText(daybox)
    If month <= 0 Or 13 <= month Or year <= 0 Or day <= 0 Or 32 <= month Then
      GraphicsWindow.BrushColor = "Black"
      GraphicsWindow.FillRectangle(1, 100, 400, 70)
      GraphicsWindow.BrushColor = "White"
      GraphicsWindow.DrawText(1, 100, "正しい日付を入力してください。")
    Else
      a = Math.Remainder((year - 11), 19) * 11
      If month = 1 Or month = 3 Then
        b = 0
      ElseIf month = 2 Or month = 4 Or month = 5 Then
        b = 2
      Else
        b = month - 2
      EndIf
      Getsurei = Math.Remainder((a + b + day), 30)
      GraphicsWindow.BrushColor = "Black"
      GraphicsWindow.FillRectangle(1, 100, 400, 70)
      GraphicsWindow.BrushColor = "White"
      GraphicsWindow.DrawText(1, 100, year + "年" + month + "月" + day + "日の月齢は、" + Getsurei + "です。")
    
      '特別な時の月の形はメッセージ追加
      If Getsurei = 2 Then
        GraphicsWindow.DrawText(1, 125, "三日月です。")
      EndIf
      If Getsurei = 15 Then
        GraphicsWindow.DrawText(1, 125, "満月です。")
      EndIf
      If Getsurei = 0 Then
        GraphicsWindow.DrawText(1, 125, "新月です。")
      EndIf
      
      '月齢が0〜7の時の月の形の描画
      If 0 <= Getsurei And Getsurei <= 7 Then
        GraphicsWindow.BrushColor = "Yellow"
        GraphicsWindow.PenColor = "Yellow"
        tuki1 = Shapes.AddEllipse(100, 100)
        GraphicsWindow.BrushColor = "Black"
        GraphicsWindow.PenColor = "Black"
        tuki2haba = 100 * (7 - Getsurei) / 7
        tuki2 = Shapes.AddEllipse(tuki2haba, 100)
        tuki3 = Shapes.AddRectangle(50, 100)
        Shapes.Move(tuki1, 10, 170)
        Shapes.Move(tuki2, 10+50-tuki2haba/2, 170)
        Shapes.Move(tuki3, 10, 170)
      EndIf
      
      '月齢が8〜14の時の月の形の描画
      If 8 <= Getsurei And Getsurei <= 14 Then
        GraphicsWindow.BrushColor = "Yellow"
        GraphicsWindow.PenColor = "Yellow"
        tuki1 = Shapes.AddEllipse(100, 100)
        Shapes.Move(tuki1, 10, 170)
        GraphicsWindow.BrushColor = "Black"
        GraphicsWindow.PenColor = "Black"
        tuki3 = Shapes.AddRectangle(50, 100)
        Shapes.Move(tuki3, 10, 170)
        GraphicsWindow.BrushColor = "Yellow"
        GraphicsWindow.PenColor = "Yellow"
        tuki2haba = 100 * (Getsurei - 7) / 7
        tuki2 = Shapes.AddEllipse(tuki2haba, 100)
        Shapes.Move(tuki2, 10+50-tuki2haba/2, 170)
      EndIf

      '月齢が15の時の月の形の描画(満月)
      If Getsurei = 15 Then
        GraphicsWindow.BrushColor = "Yellow"
        GraphicsWindow.PenColor = "Yellow"
        tuki1 = Shapes.AddEllipse(100, 100)
        Shapes.Move(tuki1, 10, 170)
      EndIf
    
      '月齢が16〜21の時の月の形の描画
      If 16 <= Getsurei And Getsurei <= 21 Then
        GraphicsWindow.BrushColor = "Yellow"
        GraphicsWindow.PenColor = "Yellow"
        tuki1 = Shapes.AddEllipse(100, 100)
        Shapes.Move(tuki1, 10, 170)
        GraphicsWindow.BrushColor = "Black"
        GraphicsWindow.PenColor = "Black"
        tuki3 = Shapes.AddRectangle(50, 100)
        Shapes.Move(tuki3, 10+50, 170)
        GraphicsWindow.BrushColor = "Yellow"
        GraphicsWindow.PenColor = "Yellow"
        tuki2haba = 100 * (7 - (Getsurei - 15)) / 7
        tuki2 = Shapes.AddEllipse(tuki2haba, 100)
        Shapes.Move(tuki2, 10+50-tuki2haba/2, 170)
      EndIf
    
      '月齢が22〜29の時の月の形の描画
      If 22 <= Getsurei And Getsurei <= 29 Then
        GraphicsWindow.BrushColor = "Yellow"
        GraphicsWindow.PenColor = "Yellow"
        tuki1 = Shapes.AddEllipse(100, 100)
        GraphicsWindow.BrushColor = "Black"
        GraphicsWindow.PenColor = "Black"
        tuki2haba = 100 * (Getsurei - 22) / 7
        tuki2 = Shapes.AddEllipse(tuki2haba, 100)
        tuki3 = Shapes.AddRectangle(50, 100)
        Shapes.Move(tuki1, 10, 170)
        Shapes.Move(tuki2, 10+50-tuki2haba/2, 170)
        Shapes.Move(tuki3, 10+50, 170)
      EndIf
    EndIf
  EndIf
EndSub

月齢

月齢

上では一応、テキストボックスにマイナスの数字が入っている時とか、月に13以上の数字が入っている場合とかに「正しい日付を入力してください。」と警告を出すようにしてみました。
日については32以上の数字で「正しい日付を入力してください。」表示を出すようにしていますが、本来は月別に日を設定しなければなりません。ただ、それをやると2月のうるう年の計算とか大変なことになるため、このような簡易的な方法にしました。

……結局、Clockオブジェクトとあんまり関係ないプログラムになった気がしなくもない。w


▲TOPへ戻る