Asp Forum
Home
|
Login
|
Register
|
Search
Forums
>
comp.lang.ruby
Re: Overlapping circles - modelling living populations
Gavin Kistner
9/9/2006 3:35:00 PM
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....
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/popul...
Servizio di avviso nuovi messaggi
Ricevi direttamente nella tua mail i nuovi messaggi per
Re: Overlapping circles - modelling living populations
Inserendo la tua e-mail nella casella sotto, riceverai un avviso tramite posta elettronica ogni volta che il motore di ricerca troverà un nuovo messaggio per te
Il servizio è completamente GRATUITO!
x
Login to ForumsZone
Login with Google
Login with E-Mail & Password