vector – PullMonkey Blog http://pullmonkey.com Fri, 19 Nov 2010 21:52:14 +0000 en-US hourly 1 https://wordpress.org/?v=5.6 2D Vector Graphics in Ruby / Rails http://pullmonkey.com/2010/11/19/2d-vector-graphics-in-ruby-rails/ Fri, 19 Nov 2010 21:42:27 +0000 http://pullmonkey.com/?p=57544 I've been working with Cairo the last day or two to build a sign generator.   I chose Cairo because it seemed like a good fit for building a sign that had to be loss-less in detail and scalable, this rang vector graphics.   I found a few good examples here and there, but they were very few and the documentation was not exactly ruby-friendly.

So I'm going to do a few posts about what I learned and I am going to start with the very basics, since all I could find were completed and elaborate images, way too complicated for a beginner.

Let's start with rotating a square box by 45 degrees.  Very simple.

rotated_square

require 'rubygems'
require 'cairo'
class Box
# height and width for the rectangle, angle for the rotation
attr_accessor :height, :width, :angle
def initialize(height=200, width=200, angle=45)
@height, @width, @angle = [height, width, degrees_to_radians(angle)]
# The first argument for a surface is the filename, the next two are our canvas/surface size.
# I am making the surface twice as big as the object (WxH) we want to create, just to give it some padding.
@surface = Cairo::SVGSurface.new("rotated_square.svg", @width * 2, @height * 2)
# setup our context object to draw on
@cr = Cairo::Context.new(@surface)
# set it up with rotation
setup_scene_with_rotation
# draw the square
return build_rotated_square
end
private
def setup_scene_with_rotation
# give it a white background
@cr.set_source_color(:white)
@cr.paint
# rotate everything by our angle (in rads) from the middle
# if you do not move the rotation point to the center, you will be rotating from 0,0 (bottom left of the canvas)
# so first move to the middle of the surface (coords of W,H, since our canvas is 2W x 2H)
# then do the rotation
# then move back to 0,0
# we know that width, height is the center b/c we start at 0,0
# see @cr.current_point to be sure
@cr.translate(@width, @height)
@cr.rotate(@angle)
@cr.translate(-@width, -@height)
end
def build_rotated_square
# build a rectangle with height and width dimensions
# x and y are the starting points from which the rectangle is drawn
# x and y are the bottom left of the box
x = @width / 2
y = @height / 2
@cr.rectangle(x, y, @width, @height)
# the object has been created but is invisible, so let's draw a line around it
# the line will be black
@cr.set_source_color(:black)
# apply the line
@cr.stroke
# create the SVG
@cr.target.finish
end
# the angle comes in, in the form of the degrees and will need to be converted to radians
def degrees_to_radians(angle_in_degrees)
return angle_in_degrees / 180.0 * Math::PI
end
end
# let's get our box ... I'm not using GTK, so it will just spit out an image in the local fs
Box.new

That's it, pretty simple, right?

]]>