Gavin,


On Sun, 2006-09-10 at 00:44 +0900, Gavin Kistner wrote:
> Here's a slightly better version that uses the overlapping status of a circle to change its color. (It doesn't do anything with pairs of circles, though that'd also be easy...you just have to know how you'd want to visualize it.)
> 
> # http://downloads.sourceforge.jp/ruby-svg/2288/ruby-svg-1.0.3.tar.gz
> require 'svg/svg'
> 
> class Array
>   def each_unique_pair
>     self.each_with_index{ |a,i|
>       self[(i+1)..-1].each{ |b| yield a,b }
>     }
>   end
> end
> 
> class SVG::Circle
>   # test (and save) result
>   def overlaps?( other_circle )
>     center_distance = Math.sqrt(
>       ( cx - other_circle.cx ) ** 2 +
>       ( cy - other_circle.cy ) ** 2
>     )
> 
>     intersects = center_distance < ( r + other_circle.r )
>     
>     # Save the result on both circles    
>     other_circle.overlaps[ self ] = intersects
>     self.overlaps[ other_circle ] = intersects
>   end
>   
>   def overlaps
>     # Make sure we have a hash to save a set of overlappers
>     @overlapping_circles ||= {}
>   end
>   
>   # An array of all circles this one overlaps
>   def overlapping_list
>     # Make sure we have a hash to save a set of overlappers
>     @overlapping_circles ||= {}
>     @overlapping_circles.select{ |circle,status|
>       status == true
>     }.map{ |circle,status|
>       circle
>     }
>   end
> end
> 
> # Create/manage your populations
> populations = []
> 20.times{
>   # Randomly add populations
>   x = rand 800 + 100
>   y = rand 800 + 100
>   radius = rand 100 + 10
>   populations << SVG::Circle.new( x, y, radius )
> }
> 
> # Make sure the overlapping list is valid
> populations.each_unique_pair{ |a,b|
>   a.overlaps?( b )
> }
> 
> # Make the picture
> svg = SVG.new('100%', '100%', '0 0 1000 1000')
> 
> # Your grid here
> 0.step( 1000, 20 ){ |i|
>   svg << SVG::Line.new( i, 0, i, 1000 )
>   svg << SVG::Line.new( 0, i, 1000, i )
> }
> 
> # Make all circles have a common style
> svg << g = SVG::Group.new{
>   self.style = SVG::Style.new(
>     :fill => '#ffe', :stroke => 'blue', :stroke_width => 1.5
>   )
> }
> 
> # Need opacity per element, not on the group
> low_opacity = SVG::Style.new( :opacity => 0.6 )
> 
> # Override style for circles that overlap
> olap_style = SVG::Style.new( :fill=>'#ff9', :stroke=>'red', :opacity=>0.4 )
> 
> populations.each{ |circle|
>   if circle.overlapping_list.empty?
>     circle.style = low_opacity
>   else
>     circle.style = olap_style
>   end
>   g << circle
> }
> 
> File.open( 'populations.svg', 'w' ){ |file|
>   file << svg.to_s
> }
> 
> # view in your favorite SVG viewer, like FF 1.5
> # for an example, see http://phrogz.net/svg/populations.svg


Many thanks for that!  I will have to go over this in detail to
understand what is happening but it looks nice!  A couple of things:

1. There seems to be some doubt about the survival of SVG . .

2. Opera supports SVG natively! (which seems to go against the first
point)

Regards,

Phil.
-- 
Philip Rhoades

Pricom Pty Limited  (ACN 003 252 275  ABN 91 003 252 275)
GPO Box 3411
Sydney NSW      2001
Australia
Mobile:  +61:(0)411-185-652
Fax:     +61:(0)2-8221-9599
E-mail:  phil / pricom.com.au