1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
=begin
rose.rb
$Author: mutoh $
$Date: 2005/02/01 06:11:52 $
Copyright (C) 2003 Tom Payne <ruby-gnome-users-en@tompayne.org>
=end
require 'libart2'
module Art
class Vpath
def Vpath.line(x0, y0, x1, y1)
Vpath.new([[Art::MOVETO, x0, y0], [Art::LINETO, x1, y1], [Art::END]])
end
def Vpath.slice(x, y, r, from, to)
delta = 2.0 * Math::PI / 128
from = Math::PI * from / 180.0
to = Math::PI * to / 180.0
from += 2.0 * Math::PI while from < 0
to += 2.0 * Math::PI while to <= from
a = [[Art::MOVETO, x, y], [Art::LINETO, x + r * Math.cos(from), y + r * Math.sin(from)]]
theta = ((from / delta).to_i + 1) * delta
while theta < to
a.push([Art::LINETO, x + r * Math.cos(theta), y + r * Math.sin(theta)])
theta += delta
end
a.push([Art::LINETO, x + r * Math.cos(to), y + r * Math.sin(to)])
a.push([Art::LINETO, x, y])
a.push([Art::END])
Vpath.new(a)
end
end
class Canvas
class Context < Hash
def initialize(overrides = {})
self[:affine_transform] = nil
self[:dash] = nil
self[:stroke] = false
self[:join] = Art::PATH_STROKE_JOIN_ROUND
self[:cap] = Art::PATH_STROKE_CAP_ROUND
self[:line_width] = 1.0
self[:miter_limit] = 1.0
self[:flatness] = 0.5
self[:color] = Art::Canvas::Color::BLACK
update(overrides)
end
def with(overrides)
clone.update(overrides)
end
end
def render_vpath_with_context(vpath, context)
vpath = vpath.affine_transform(context[:affine_transform]) unless context[:affine_transform].nil?
vpath = vpath.dash(context[:dash]) unless context[:dash].nil?
if context[:stroke]
svp = vpath.stroke(context[:join], context[:cap], context[:line_width], context[:miter_limit], context[:flatness])
else
svp = vpath.to_svp
end
render_svp(svp, context[:color])
end
end
end
class Array
def to_h(default = nil)
result = Hash.new(default)
each_with_index do |element, index|
result[index] = element
end
result
end
end
directions = ['e', 'se', 's', 'sw', 'w', 'nw', 'n', 'ne']
direction_index = directions.to_h.invert
width = 145
size = 128
border = 4
height = size + 2 * border
context = Art::Canvas::Context.new({:affine_transform => Art::Affine.translate(width / 2 + 0.5, height / 2 + 0.5) * Art::Affine.scale(size / 2.0, size / 2.0)})
line_context = context
line_context = context.with({:stroke => true, :line_width => 1, :color => Art::Canvas.color(0x00, 0x66, 0x00)})
crosshair_fill_context = context.with({:color => Art::Canvas.color(0xff, 0xff, 0xff)})
pie_fill_context = context.with({:color => Art::Canvas.color(0xee, 0xff, 0xee)})
hline = Art::Vpath.line(-1, 0, 1, 0)
vline = Art::Vpath.line(0, -1, 0, 1)
circle = Art::Vpath.circle(0, 0, 0.8)
overlap = 0.25 * 360.0 / directions.length
directions.each do |from|
directions.each do |to|
next if from == to
canvas = Art::Canvas.new(width, height, Art::Canvas::Color::WHITE, Art::Canvas::ALPHA_MASK)
canvas.render_vpath_with_context(circle, crosshair_fill_context)
canvas.render_vpath_with_context(circle, line_context)
canvas.render_vpath_with_context(hline, line_context)
canvas.render_vpath_with_context(vline, line_context)
slice = Art::Vpath.slice(0.0, 0.0, 0.9, 360.0 * direction_index[from] / directions.length - overlap, 360.0 * direction_index[to] / directions.length + overlap)
canvas.render_vpath_with_context(slice, pie_fill_context)
canvas.render_vpath_with_context(slice, line_context)
File.open("rose-#{width}x#{height}-#{from}-#{to}.png", 'wb') do |file|
file.write(canvas.to_png)
end
end
end
|