水平投射の Gkt 版

cairo と Ruby で遊んでみる(2) - Camera Obscura

Gtk への出力。
あんまりいい実装ではない。無理に一時ファイルを作っている。

main の部分だけ載せる。

require './output_to_gtk'

#main
Surface = Cairo::ImageSurface.new(Cairo::FORMAT_ARGB32, W, H)
C = Cairo::Context.new(Surface)
C.set_source_rgb(0, 0, 0)
C.rectangle(0, 0, W, H)
C.fill

C.set_source_rgb(1, 0, 0)

for i in 0..W
  tm = i / 10.0
  x1 = x.call(tm)
  y1 = H - y.call(num[tm], tm)
  C.arc(x1, y1, 2, 0, 2 * PI)
  C.stroke
end

Surface.write_to_png("_buf.png")
output_to_gtk(delete: true)

output_to_gtk.rb。Gtk に画像を出力する。

require 'bundler/setup'
require 'gtk2'

def output_to_gtk(fname: "_buf.png", delete: false, b_rgb: [0, 0, 0])
  pix = Gdk::Pixbuf.new(fname)
  File.delete(fname) if delete
  
  area = Gtk::DrawingArea.new
  area.signal_connect('expose-event') do |widget|
    ctx = widget.window.create_cairo_context
    ctx.set_source_rgb(b_rgb[0], b_rgb[1], b_rgb[2])
    ctx.paint
    ctx.save do
      ctx.new_path
      ctx.rectangle(0, 0, pix.width, pix.height)
      ctx.set_source_pixbuf(pix)
      ctx.fill
    end
  end
  
  window = Gtk::Window.new("Gtk")
  window.set_default_size(pix.width + 1, pix.height + 1)
  window.add(area)
  window.show_all
  Gtk.main
end

スクリーンショット


※参考
Ruby/GTK - Ruby-GNOME2 Project Website
gtk2-tut - Ruby-GNOME2 Project Website
rcairo による 3D テクスチャマッピング(まとめ) - Tociyuki::Diary

修正版

以下でいいようだ。これなら余計な一時ファイルを作らなくて済む。

main の部分だけ載せる。

require 'bundler/setup'
require 'cairo'
require './cairo_gtk'
include Math

#main
Surface = Cairo::ImageSurface.new(Cairo::FORMAT_ARGB32, W, H)
C = Cairo::Context.new(Surface)
C.set_source_rgb(0, 0, 0)
C.rectangle(0, 0, W, H)
C.fill

C.set_source_rgb(1, 0, 0)

for i in 0..W
  tm = i / 10.0
  x1 = x.call(tm)
  y1 = H - y.call(num[tm], tm)
  C.arc(x1, y1, 2, 0, 2 * PI)
  C.stroke
end

cairo_gtk(Surface, W, H)

cairo_gtk.rb

require 'bundler/setup'
require 'gtk2'

def cairo_gtk(surface, width, height)
  area = Gtk::DrawingArea.new
  area.signal_connect('expose-event') do |widget|
    ctx = widget.window.create_cairo_context
    ctx.set_source(surface)
    ctx.paint
  end
  
  window = Gtk::Window.new("Gtk")
  window.set_default_size(width + 1, height + 1)
  window.add(area)
  window.show_all
  Gtk.main
end