RMagick Web 2.0 Graphics
Alpha Compositing - Part 2

<< Back to page 3 <<

The star method

To draw the starburst I had to go way back to my high-school trigonometry lessons. The only thing I could remember was the Pythagorean Theorem but fortunately it was all I needed! I remembered that I could compute the coordinates of a point on the perimeter of a circle as

x = r * cos(theta)
y = r * sin(theta)

where r is the radius of the circle and theta is the inner angle. The Magick::Draw#star method uses these equations to compute the vertices of 2 25-sided regular polygons. One polygon is nested inside the other, The inner polygon is rotated such that its vertices are halfway between the vertices of the outer polygon. Draw#star then computes the points of the actual starburst polygon by alternating between a vertex on the outer polygon and a vertex on the inner polygon.

In the image below, the vertices of the red and blue polygons supply the points that form the perimeter of the starburst.

The Magick::Image#star method creates an instance of Magick::Draw, sets up the style attributes and calls Magick::Draw#star to compute the points of the starburst polygon. Then it calls Magick::Draw#draw to actually draw the starburst.

module Magick
    class Draw
        def star(sides, inner_radius, outer_radius)
            theta = 0.0
            incr = Math::PI * 2.0 / sides
            half_incr = incr / 2.0
            points = []
            sides.times do
                points << outer_radius * Math::cos(theta)
                points << outer_radius * Math::sin(theta)
                points << inner_radius * Math::cos(theta + half_incr)
                points << inner_radius * Math::sin(theta + half_incr)
                theta += incr
            end
            polygon *points
        end
    end

    class Image
        def star(sides, inner_radius, outer_radius, stroke, fill)
            gc = Draw.new
            gc.translate columns/2.0, rows/2.0
            gc.fill fill
            gc.stroke stroke
            gc.star sides, inner_radius, outer_radius
            gc.draw self
        end
    end
end