#!/usr/local/bin/ruby # the paper foldings diagram class definitions are here require 'GD' $verbose = false $Information = Hash.new lines = <<-HEAR keyword string(Array) kind # orders of datum white [255,255,255] color black [0,0,0] color red [204,0,0] color blue [0,0,255] color green [0,204,0] color yellow [255,255,51] color Valley ([@red]*3+ [Transparent]*3) pattern Mountain ([@blue]*4+ [Transparent]*2+ [@blue]*2+ [Transparent]*1+ [@blue]*2+ [Transparent]*2+ [@blue]*4) pattern G ([@green]*1) pattern B ([@black]*1) pattern HEAR begin open('folding.colors.txt'){ |f| lines = f.readlines } rescue Errno::ENOENT # open('folding.colors.txt') end # open('folding.colors.txt') lines.each{ |line| line.sub!(/#.*$/,'') key, str, kind = line.chop.split(' ') if line.size>0 $Information[key]= [str, kind] } # lines.each if $0 == __FILE__ #p $Information $Information.select{ |key, str| /color/=~ str[1] }.each{ |key, str| print "key: #{key}, str: #{str[0]}\n" } #exit end class Folding include GD attr_reader :paper attr_reader :margin, :size, :wide, :high attr_reader :whitetransparent $Information.select{ |key, str| /color/=~ str[1] }.each{ |key, str| eval("attr_reader :#{key}") } Maekawa = Math::tan(Math::PI/8) Maekawa_ho = (1.0- Math::tan(Math::PI/8)) CraneBase = Polygon.new.addPt(0,0).addPt(Maekawa*50, 50).addPt(0,100).addPt(50, 50+ Maekawa_ho*50).addPt(100,100).addPt(50+ Maekawa_ho*50, 50).addPt(100,0).addPt(50, Maekawa*50) def CraneBase::scaleR(sx, sy); CraneBase.scale(sx.to_f/100, sy.to_f/100); self; end def CraneBase::transfR(a,b,c,d, tx,ty); CraneBase.transform(a,b,c,d, tx,ty); self; end def initialize(width, height=false, margin= 5, black_and_white=false) height || height = width @wide, @high, @margin = width, height, margin @size = (width+height)/2.0 @paper = Image.new(@margin+@wide+@margin, @margin+@high+@margin) if $Information.has_key?('white') then @whitetransparent = @paper.colorAllocate(*eval($Information['white'][0])) else @whitetransparent = @paper.colorAllocate(255,255,255) # Assertion! This case be not tested by testfolding.rb . end @paper.transparent(@whitetransparent) @paper.fill(1,1, @whitetransparent) $Information.select{ |key, str| /color/=~ str[1] }.each{ |key, str| eval("@#{key}= @paper.colorAllocate(*#{str[0]})") } @red, @blue, @green, @yellow = [@black]*7 if black_and_white if block_given? then begin # yield yield(self, @paper) ensure # yield @paper.destroy @paper = nil end # yield end # if block_given? end # def initialize(width, height=false, margin= 5) def poly(points, color) @paper.polygon(points.offset(@margin, @margin), color) self end $Information.select{ |key, str| /pattern/=~ str[1] }.each{ |key, str| eval <<-HEAR def poly#{key}(points) @paper.setStyle( *#{str[0]} ) @paper.polygon(points.offset(@margin, @margin), Styled) self end HEAR } def line(x1, y1, x2, y2, color) @paper.line(x1+@margin, y1+@margin, x2+@margin, y2+@margin, color) self end $Information.select{ |key, str| /pattern/=~ str[1] }.each{ |key, str| eval <<-HEAR def line#{key}(x1, y1, x2, y2) @paper.setStyle( *#{str[0]} ) @paper.line(x1+@margin, y1+@margin, x2+@margin, y2+@margin, Styled) self end HEAR } alias mountain lineMountain alias valley lineValley # undef lineMountain # undef lineValley def rect(x1, y1, x2, y2, color) @paper.rectangle(x1+@margin, y1+@margin, x2+@margin, y2+@margin, color) self end $Information.select{ |key, str| /pattern/=~ str[1] }.each{ |key, str| eval <<-HEAR def rect#{key}(x1, y1, x2, y2) @paper.setStyle( *#{str[0]} ) @paper.rectangle(x1+@margin, y1+@margin, x2+@margin, y2+@margin, Styled) self end HEAR } # fill は pattern を取れるのだろうか、それとも color か? # patterrn は取れた。だがその意味は良く解らない。 # それは動くのに test も出来ない位 buggy だ。だから color にしてみる。 def fill(x1, y1, color) @paper.fill(x1+@margin, y1+@margin, color) self end # $Information.select{ |key, str| /pattern/=~ str[1] }.each{ |key, str| $Information.select{ |key, str| /color/=~ str[1] }.each{ |key, str| eval <<-HEAR def fill#{key}(x1, y1) # @paper.setStyle( *#{str[0]} ) # @paper.fill(x1+@margin, y1+@margin, Styled) @paper.fill(x1+@margin, y1+@margin, #{key}) self end HEAR } # setPixel は pattern を取れるのだろうか、それとも color か? # 同上な筈と思っていたが、そうでもない様だ。 def point(x1, y1, color) @paper.setPixel(x1+@margin, y1+@margin, color) self end $Information.select{ |key, str| /pattern/=~ str[1] }.each{ |key, str| eval <<-HEAR def point#{key}(x1, y1) @paper.setStyle( *#{str[0]} ) @paper.setPixel(x1+@margin, y1+@margin, Styled) self end HEAR } # いいや違う。arc の変数は違うような気がする。 # cx,xy, w,h # 幅縦は直径だけど、倍することにして短径長径にするか迷い中 def arc(cx, cy, w, h, color, t1=0, t2=360) @paper.arc(cx+@margin, cy+@margin, w, h, t1, t2, color) self end alias ellipse arc $Information.select{ |key, str| /pattern/=~ str[1] }.each{ |key, str| eval <<-HEAR def arc#{key}(cx, cy, w, h, t1=0,t2=360) @paper.setStyle( *#{str[0]} ) @paper.arc(cx+@margin, cy+@margin, w, h, t1, t2, Styled) self end alias ellipse#{key} arc#{key} HEAR } # circle なんか中心ずれてない? # arc ってば、中心と幅縦指定だったよ。それでそれは半径か直径か? 直径みたいなんで rは半径 def circle(x1, y1, r, color, t1=0, t2=360) # @paper.arc(x1-r+@margin, y1-r+@margin, x1+r+@margin, y1+r+@margin, t1, t2, color) @paper.arc(x1+@margin, y1+@margin, r*2,r*2, t1, t2, color) self end $Information.select{ |key, str| /pattern/=~ str[1] }.each{ |key, str| eval <<-HEAR def circle#{key}(x1, y1, r, t1=0,t2=360) @paper.setStyle( *#{str[0]} ) @paper.arc(x1+@margin, y1+@margin, r*2, r*2, t1, t2, Styled) self end HEAR } def mark(cx,cy, r=nil, color=nil) color = @red if not color if not r then r = @size/16 r = 9 if r <= 9 end # if not r then @paper.arc(cx+@margin,cy+@margin, r,r, 0,360, color) self end # FontSize な文字列には、'Giant','Large','Medium','Small','Tiny' def string(x,y, str, size=nil, color=nil) color = @blue if not color size = 'Medium' if not size case size when /^G/i#iant size = GD::Font::GiantFont when /^L/i#arge size = GD::Font::LargeFont when /^M/i#edium size = GD::Font::MediumFont when /^S/i#mall size = GD::Font::SmallFont when /^T/i#iny size = GD::Font::TinyFont else size = GD::Font::MediumFont end # case size @paper.string(size, x+@margin,y+@margin, str, color) self end def copy(to_x,to_y, from_x,from_y, w,h) @paper.copy(@paper, to_x+@margin,to_y+@margin, from_x+@margin,from_y+@margin, w,h) self end def copyResized(to_x,to_y, from_x,from_y, to_w,to_h, from_w,from_h) @paper.copyResized(@paper, to_x+@margin,to_y+@margin, from_x+@margin,from_y+@margin, to_w,to_h, from_w,from_h) self end def copyMerge(to_x,to_y, from_x,from_y, w,h, percent) @paper.copyMerge(@paper, to_x+@margin,to_y+@margin, from_x+@margin,from_y+@margin, w,h, percent) self end def copyMergeGray(to_x,to_y, from_x,from_y, w,h, percent) @paper.copyMergeGray(@paper, to_x+@margin,to_y+@margin, from_x+@margin,from_y+@margin, w,h, percent) self end def save(filename) case filename when /\.png$/i methodName = 'png' when /\.gd$/i methodName = 'gd' else filename+= '.png' methodName = 'png' end $stderr.puts "File #{filename} already exists, and overwrite it." if FileTest.file?(filename) and $verbose File::open(filename, 'w'){ |f| eval("@paper.#{methodName}(f)") } end end # class Folding if $0 == __FILE__ dir = 'test\\' zu = Folding.new(50) zu.rectB(5,5, 45,45) zu.paper.fill(20,20, zu.yellow) poly = Folding::Polygon.new.addPt(11,13).addPt(30,50).addPt(49,13) zu.paper.polygon(poly, zu.red) poly = Folding::Polygon.new.addPt(0,0).addPt(zu.size* Folding::Maekawa,50).addPt(0,50) zu.polyMountain(poly) File::open(dir+'cls2.png', 'w'){ |f| zu.paper.png(f) } zu.paper.destroy zu = nil zu = Folding.new(50){ |fo, p| fo.lineG(0,0, 50,50) fo.mountain(0,50, 50,0) fo.valley(25,0, 25,50) poly = Folding::Polygon.new.addPt(0,0).addPt(25,50).addPt(50,0) fo.poly(poly, fo.red) fo.fill(5,3, fo.paleblue) poly.scale(0.7, 0.7) fo.polyMountain(poly) File::open(dir+'cls3.png', 'w'){ |f| fo.paper.png(f) } # poly = Folding::CraneBase; poly.scale(0.5,0.5) fo.polyB(Folding::CraneBase.scaleR(0.5,0.5)) fo.polyB(Folding::CraneBase.transfR(0.7,0.7,(-0.7),0.7, 25,-17)) fo.save(dir+'cls5.png') } zu = Folding.new(50,41,7,true){ |fo, p| fo.lineG(50,0, 0,40) fo.valley(0,0, 50,40) poly = Folding::Polygon.new.addPt(0,0).addPt(25,41).addPt(50,0) fo.polyMountain(poly) fo.circle(30,30, 10, fo.green) fo.circle(30,30, 5, fo.paleblue) File::open(dir+'cls4.png', 'w'){ |f| p.png(f) } fo.rectB(12,12, 38,38) # fo.save(dir+'cls6.gd') } Folding.new(60){ |fo, p| fo.circleG(30,30, 20) # fo.fillPBlue(25,25) # fo.fillMountain(25,25) # fo.fillValley(25,25) fo.fillwhite(25,25).point(25,20, fo.green).pointB(25,25).pointValley(22,22) fo.circle(40,40, 10, fo.black) # p.arc(5,5, 10,10, 0,360, fo.blue) # p.arc(34,5, 46,7, 0,360, fo.blue) fo.mark(3,7).mark(7,40, 10).mark(45,50, 5, fo.blue) fo.string(10,30, 'asdf').string(10,40, 'zxcv', 'Giant').string(25,15, '-->', 'Small', fo.green) fo.copy(3,3, 40,5, 15,15).copyResized(7,40, 30,7, 20,20, 10,30) fo.save(dir+'cls6') } File::open(dir+'cls.htm', 'w') do |f| html = "