てきとうなさいと べぇたばん

虹を円を描くように

Image#circleでは、一本線として円を描くため、ところどころ隙間ができてしまう。これは困った Image#circleFillを使って円を内側に向かって描いていけば、隙間が埋まる。

虹を作りたくてですね

いつものように、DXRubyいじってたら、
どうも虹を画面上に作りたくなってしまってですね。

作ってみました。

作り方を考える

上記のURLを見ると、RGBではなくHSVを使うようだ。

色相(Hue)を変化させていくのか。

Wikipediaでは公式も乗ってたので、参考にしてスクリプトにした。

require "dxruby"

image = Image.new(640, 480)

def hsvToRGB(hsv)
  h, s, v = hsv.collect{|n| n.to_f }

  return [v, v, v] if s == 0

  hi = (h / 60).to_i % 6
  f = h / 60 - hi

  pl = v * (1 - s)
  ql = v * (1 - f * s)
  tl = v * (1 - (1 - f) * s)

  case hi
  when 0
    ret = [v, tl, pl]
  when 1
    ret = [ql, v, pl]
  when 2
    ret = [pl, v, tl]
  when 3
    ret = [pl, ql, v]
  when 4
    ret = [tl, pl, v]
  when 5
    ret = [v, pl, ql]
  else
    raise "out of range"
  end

  ret.collect{|r| r * 255}
end

drawRainbow = lambda {|w, r|
  w.times do |i|
    image.circleFill(320, 240, r - i, hsvToRGB([i * (360 / w), 1.0, 1.0]))
  end

  # 真ん中を黒く塗りつぶしている。真ん中がcircleFillで赤になっちゃうので
  image.circleFill(320, 240, r - w, [0,0,0])
}

drawRainbow.call(50, 200)

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

ImageオブジェクトでcircleFillとかやっとくと、
それを書き換えるとかじゃない場合にはフレームごとに
circleFillとかやらなくてすむ。

うん、面白かったです。