Prev: Ruby BasicNext: Ruby Basic From: brabuhr on 21 Jun 2010 22:19 On Mon, Jun 21, 2010 at 9:12 PM, wrote:> On Mon, Jun 21, 2010 at 7:12 PM, Dave Howell > wrote: >> On Jun 21, 2010, at 15:45 , Caleb Clausen wrote: >>> On 6/19/10, Daniel Moore wrote: >>>> The quiz this week >>>> is to generate random points uniformly distributed within a circle of >>>> a given radius and position. >>> >>> def random_point_in_a_circle(x,y,r) >>>  angle=rand*2*Math::PI >>>  r*=rand >>>  x+=r*Math.sin(angle) >>>  y+=r*Math.cos(angle) >>> >>>  return x,y >>> end >>> >>> 7 lines, 5 minutes, 0 tests or visualizations. Super-easy. >> >> And wrong, unfortunately. You're selecting a random angle, and then a random distance from the center. This will result in way too many points at the center of the circle. > > I whipped up a quick little visualization: Quick hack to animate the above method side by side with an alternate method: require 'java' JFrame = javax.swing.JFrame JPanel = javax.swing.JPanel frame = JFrame.new("Random Points within a Circle") frame.default_close_operation = JFrame::EXIT_ON_CLOSE frame.set_size(700, 400) frame.show class RPwiaC < JPanel def initialize times, *procs super() @times = times @procs = procs end def paintComponent(graphics) super(graphics) @times.times do @procs.each_with_index do |proc, i| x,y = proc.call(200 + (300 * i),200,150) graphics.draw_line(x-1,y-1,x+1,y+1) graphics.draw_line(x-1,y+1,x+1,y-1) end end end end panel = RPwiaC.new( 5000, lambda{|x,y,r| angle=rand*2*Math::PI r*=rand x+=r*Math.sin(angle) y+=r*Math.cos(angle) return x,y }, lambda{|x,y,r| loop { a = x + rand(2*r) - r b = y + rand(2*r) - r d = Math.sqrt((x - a) ** 2 + (y - b) ** 2) return a,b if d < r } } ) frame.add(panel) panel.revalidate loop { panel.repaint } From: Caleb Clausen on 21 Jun 2010 22:41 On 6/21/10, Dave Howell wrote:> > On Jun 21, 2010, at 15:45 , Caleb Clausen wrote: >> 7 lines, 5 minutes, 0 tests or visualizations. Super-easy. > > And wrong, unfortunately. You're selecting a random angle, and then a random > distance from the center. This will result in way too many points at the > center of the circle. I guess this is why Benoit had that sqrt in there. I don't quite get why it's necessary. I kinda like Yaser's solution. From: Benoit Daloze on 22 Jun 2010 12:15 On 22 June 2010 00:30, Yaser Sulaiman wrote:> It's not as advanced as Daloze's solution, and it definitely can (should?) > be enhanced, but my solution is available at http://gist.github.com/447554. > Any feedback is welcomed. I would say it is a good try, and the distinction Vector/Point is interesting, while being a problem with DRY (you repeat the calculation of the distance). A quick tip a friend showed me: Math.sqrt(a**2 + b**2) => Math.hypot(a, b) In the end, you manually add the offset to x and y. As you have Vector/Point, the Point+Vector should be defined and then the 4 last lines would be: "center + v" On 22 June 2010 01:12, Dave Howell wrote:> > On Jun 21, 2010, at 15:45 , Caleb Clausen wrote: > >> On 6/19/10, Daniel Moore wrote: >>> The quiz this week >>> is to generate random points uniformly distributed within a circle of >>> a given radius and position. >> >> def random_point_in_a_circle(x,y,r) >>  angle=rand*2*Math::PI >>  r*=rand >>  x+=r*Math.sin(angle) >>  y+=r*Math.cos(angle) >> >>  return x,y >> end >> >> 7 lines, 5 minutes, 0 tests or visualizations. Super-easy. > > And wrong, unfortunately. You're selecting a random angle, and then a random distance from the center. This will result in way too many points at the center of the circle. > That was also my initial thought, and I think for most of us. Caleb:> I guess this is why Benoit had that sqrt in there. I don't quite get > why it's necessary. Indeed, please look at my solution and remove the "sqrt", and you will see most of the points will be in the center . The output will look like: min: 1, moy, 1.13, max: 122 # This is way too much max Point: (-2.0,4.0) # which is the center The image would then look like a point in the center. I 'felt' it would result in that because the points near the center will be much closer to each other, as it will be as much points at any distance. Brabuhr's visualization is even *way* better to see it (especially the animated one) ! And finally, why the sqrt? I just felt like I should have as many points in each area, and the area of a circle is ðr^2, so let's reduce this r^2 and becomes r. (Also I wanted the random distance to be likely further from the center, and as rand returns between 0 and 1, we have to do ^(1/2) and not ^2. - Benoit From: brabuhr on 22 Jun 2010 14:09 2010/6/22 Benoit Daloze :> On 22 June 2010 01:12, Dave Howell wrote: >> On Jun 21, 2010, at 15:45 , Caleb Clausen wrote: >>> On 6/19/10, Daniel Moore wrote: >>>> The quiz this week >>>> is to generate random points uniformly distributed within a circle of >>>> a given radius and position. > > Caleb: >> I guess this is why Benoit had that sqrt in there. I don't quite get >> why it's necessary. > > The image would then look like a point in the center. > I 'felt' it would result in that because the points near the center > will be much closer to each other, as it will be as much points at any > distance. > > And finally, why the sqrt? I just felt like I should have as many > points in each area, and the area of a circle is ðr^2, so let's reduce > this r^2 and becomes r. (Also I wanted the random distance to be > likely further from the center, and as rand returns between 0 and 1, > we have to do ^(1/2) and not ^2. Found an explanation: http://www.anderswallin.net/2009/05/uniform-random-points-in-a-circle-using-polar-coordinates/ From: Caleb Clausen on 22 Jun 2010 15:51 On 6/22/10, brabuhr(a)gmail.com wrote:> Found an explanation: > http://www.anderswallin.net/2009/05/uniform-random-points-in-a-circle-using-polar-coordinates/ Thanks. It took me a while, but it's making sense now. First  |  Prev  |  Next  |  Last Pages: 1 2 3 4 Prev: Ruby BasicNext: Ruby Basic