RMagick and circle problem

S

shawn bright

Hello all, i am back with this one.

my problem is that i am trying to draw a line on a circle that will
indicate a certain angle.
kinda like the hands on a clock. I have a line image that i rotate
around and then superimpose upon the circle image that i draw.

The problem is that when the line image is rotated, it is shorter than
the circle.

here is the code.
#!/usr/bin/ruby

require 'RMagick'

def gps_image(r)
# fetches the image file

gps_image = Magick::Image.read('line_stop.png').first
gps_image.background_color = 'none'

angle = 45
gps_image.rotate!(angle)

factor = (r.to_i * 2)
gps_image.crop_resized!(factor, factor, Magick::CenterGravity)
gps_image.write("site.site_name.png")

return gps_image
end

def circle_image
r = 45
#start with a bare canvas (square 2 times the radius of circle) the
extra two pixels is to not cut any of the border
canvas = Magick::Image.new((2 * r) +2, (2*r) +2,
Magick::HatchFill.new('transparent', 'transparent'))

# draw the circle
gc = Magick::Draw.new
gc.stroke('red')
gc.stroke_width(1)
# fill in the inside
color = 'blue'
gc.fill(color)
gc.fill_opacity(0.3)
gc.circle(r, r, 0, r)

# put our circle on the canvas
image = gc.draw(canvas)

# place the line for gps circles
gps_image = gps_image(r)
canvas.composite!(gps_image, 0, 0, Magick::OverCompositeOp)

# write the image out as a file
canvas.write("circle.png")
end

circle_image()

Everything is ok if the image is 90, 180, 270, or 0 degrees, but the
more i stray toward 45 degrees or so, the smaller the line comes out
on the image.

the image used here ( line_stop.png) is just a transparent image with
a line drawn on it in the middle. ( my clock hand )

thanks for any tips.

shawn
 
T

Tim Hunter

shawn said:
Hello all, i am back with this one.

my problem is that i am trying to draw a line on a circle that will
indicate a certain angle.
kinda like the hands on a clock. I have a line image that i rotate
around and then superimpose upon the circle image that i draw.

The problem is that when the line image is rotated, it is shorter than
the circle.

here is the code.
#!/usr/bin/ruby

require 'RMagick'

def gps_image(r)
# fetches the image file

gps_image = Magick::Image.read('line_stop.png').first
gps_image.background_color = 'none'

angle = 45
gps_image.rotate!(angle)

factor = (r.to_i * 2)
gps_image.crop_resized!(factor, factor, Magick::CenterGravity)
gps_image.write("site.site_name.png")

return gps_image
end

def circle_image
r = 45
#start with a bare canvas (square 2 times the radius of circle) the
extra two pixels is to not cut any of the border
canvas = Magick::Image.new((2 * r) +2, (2*r) +2,
Magick::HatchFill.new('transparent', 'transparent'))

# draw the circle
gc = Magick::Draw.new
gc.stroke('red')
gc.stroke_width(1)
# fill in the inside
color = 'blue'
gc.fill(color)
gc.fill_opacity(0.3)
gc.circle(r, r, 0, r)

# put our circle on the canvas
image = gc.draw(canvas)

# place the line for gps circles
gps_image = gps_image(r)
canvas.composite!(gps_image, 0, 0, Magick::OverCompositeOp)

# write the image out as a file
canvas.write("circle.png")
end

circle_image()

Everything is ok if the image is 90, 180, 270, or 0 degrees, but the
more i stray toward 45 degrees or so, the smaller the line comes out
on the image.

the image used here ( line_stop.png) is just a transparent image with
a line drawn on it in the middle. ( my clock hand )

thanks for any tips.

shawn

Looks like you're expecting the image produced by rotate! to be the same
size as the input image. The rotate! method doesn't just rotate the
line, it rotates the entire image. When you rotate the image by some
angle that's not a multiple of 90 degrees, the resulting image is going
to be wider than the input image. The resize part of crop_resized
shrinks the image to fit.

Instead of rotating the clock hand and then compositing the resulting
image over the circle image, it might be simpler to use Draw's composite
method to composite the clock hand over the circle with a suitable
rotation. Since rotation always rotates around the origin, use translate
to move the origin to the center of the circle. Here's an example.


require 'RMagick'

HAND_WIDTH = 5

def draw_hand(w)
img = Magick::Image.new(w, HAND_WIDTH) {self.background_color = "none"}
gc = Magick::Draw.new
gc.stroke_linecap "round"
gc.stroke "blue"
gc.stroke_width HAND_WIDTH
gc.line 0, HAND_WIDTH/2.0, w-(HAND_WIDTH*3)/4, HAND_WIDTH/2.0
gc.draw img
img
end

hand = draw_hand(100)

def clock(side, hand, angle)
img = Magick::Image.new(side+5, side+5)
gc = Magick::Draw.new
gc.stroke "red"
gc.fill "none"
gc.stroke_width 5
gc.circle side/2+2.5, side/2+2.5, side, side/2
gc.translate((side+2)/2, (side+2)/2)
gc.rotate angle
gc.composite 0, 0, 0, 0, hand
gc.draw img
img
end

clock = Magick::ImageList.new
8.times do |n|
clock << clock(200, hand, n*45)
end
clock.delay = 25
clock.animate
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,981
Messages
2,570,188
Members
46,731
Latest member
MarcyGipso

Latest Threads

Top