夏だ。

花火の音がするので、昔から何かといろいろある花火のプログラムを作ろうと思った。
ランダムで星を生成するなら簡単に作れるわけで、星の初期位置をきちんと計算してみようかと。
やったことないのでテキトーに考えて、ざくざくっと作ってみたのが以下。
しかしこれでは星が3000個オーバーになってしまって、さすがに多い気がするので減らす必要はありそうだ。
これは動く前の、初期位置の計算まで。
計算結果を視覚的に見えるように描画だけしている。

require 'dxruby'

class Hoshi
  attr_accessor :x, :y, :dx, :dy, :dz
  def initialize(dx, dy, dz)
    @x = 320
    @y = 240
    @dx = dx
    @dy = dy
    @dz = dz
  end

  def rotation (x, y, z)
    ax = x * TO_RADIAN
    ay = y * TO_RADIAN
    az = z * TO_RADIAN

    x = Math.cos(az) * @dx - Math.sin(az) * @dy
    y = Math.sin(az) * @dx + Math.cos(az) * @dy

    @dx = x
    @dy = y

    z = Math.cos(ax) * @dz - Math.sin(ax) * @dy
    y = Math.sin(ax) * @dz + Math.cos(ax) * @dy

    @dz = z
    @dy = y

    x = Math.cos(ay) * @dx - Math.sin(ay) * @dz
    z = Math.sin(ay) * @dx + Math.cos(ay) * @dz

    @dx = x
    @dz = z
  end
end

TO_RADIAN = Math::PI / 180

hoshi_r = 10
hoshi_da = 360.0 / 100
tama_r = 160

z = 90.0

hoshi = []

hoshi.push(Hoshi.new(0.0, 160.0, 0.0))

loop do
  z = z - hoshi_da
  break if z < 0

  # 次の高さを求める
  y = Math.sin(z * TO_RADIAN) * tama_r

  # 半径を求める
  x = Math.cos(z * TO_RADIAN) * tama_r

  # 円周を求める
  syu = x * 2 * Math::PI

  kazu = (syu / hoshi_r).to_i

  da = 360.0 / kazu
  for i in 0...kazu
    hoshi.push(Hoshi.new(Math.cos((i * da) * TO_RADIAN) * x, y, Math.sin((i * da) * TO_RADIAN) * x))
  end
end

hoshi += hoshi.map {|h|
  Hoshi.new(h.dx, -h.dy, h.dz)
}

# 回転させる
x = rand(360)
y = rand(360)
z = rand(360)
hoshi.each do |h|
  h.rotation(x, y, z)
end


image = Image.new(640, 480)

hoshi.each do |h|
  image[h.dx / ((h.dz + 300) / 300) + h.x, h.dy / ((h.dz + 300) / 300) + h.y] = [255,255,255]
end

Window.loop do
  Window.draw(0, 0, image)
end