------_ extPart_001_01C6D425.8C856FBC Content-Type: text/plain; charset indows-1252" Content-Transfer-Encoding: quoted-printable From: Philip Rhoades [mailto:phil / pricom.com.au] > I have been thinking about how to use Ruby for modelling populations - I > want to use circles on a grid to represent the size of individual > populations and determine if there is dispersal between pairs of > populations by testing whether there is overlap with the two circles. Here's a solution using SVG, assuming you want to visualize the results. It's even easier rolling your own Circle class using matrix/Vector to calculate distances. # 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 150 + 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...lots of SVG::Lines 0.step( 1000, 20 ){ |i| svg << SVG::Line.new( i, 0, i, 1000 ) svg << SVG::Line.new( 0, i, 1000, i ) } svg << g = SVG::Group.new{ self.style = SVG::Style.new( :fill => '#ffc', :stroke => 'red', :stroke_width => 1.5 ) } low_opacity = SVG::Style.new( :opacity => 0.5 ) populations.each{ |circle| circle.style = low_opacity 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 ------_ extPart_001_01C6D425.8C856FBC--