Constrained random points on a circle: Difference between revisions
(→Tcl: Added implementation) |
(→{{header|Tcl}}: Better separation of point generator from rest of code) |
||
Line 78: | Line 78: | ||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
<lang tcl>package require Tcl 8.5 |
<lang tcl>package require Tcl 8.5 |
||
# Generate random point at specified distance from the centre |
|||
proc getPoint {range from to} { |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
set x [expr {int($range * rand())}] |
|||
set y [expr {int($range * rand())}] |
|||
set d2 [expr {($x-$r2)**2 + ($y-$r2)**2}] |
|||
⚫ | |||
return [list $y $x] |
|||
} |
|||
⚫ | |||
} |
|||
# Make somewhere to store the counters |
# Make somewhere to store the counters |
||
set ary [lrepeat 31 [lrepeat 31 0]] |
set ary [lrepeat 31 [lrepeat 31 0]] |
||
# Generate 100 random points |
# Generate 100 random points |
||
for {set i 0} {$i < 100} {incr i} { |
for {set i 0} {$i < 100} {incr i} { |
||
set location [getPoint 31 10 15] |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
} |
} |
||
Revision as of 10:52, 3 September 2010
You are encouraged to solve this task according to the task description, using any language you may know.
The task is to generate a stream of 100 uniformly distributed random points (x,y integer pairs) that lie in a circular disc at 10 to 15 units from its center; and then display/plot them to show a fuzzy circle.
There are several possible approaches, depending on your language. One is simply to generate random pairs of integers and filter out those that don't satisfy the equation
10 <= sqrt( x*x + y*y ) <= 15
Another is to precalculate the set of all possible points (there are 404 of them) and select from this set. Yet another is to use real-valued polar coordinates then snap to integer Cartesian coordinates. I'm sure there are others.
SystemVerilog
<lang SystemVerilog>program main;
bit [39:0] bitmap [40];
class Point; rand bit signed [4:0] x; rand bit signed [4:0] y;
constraint on_circle_edge { (10*10) <= (x*x + y*y); (x*x + y*y) <= (15*15); };
function void do_point(); randomize; bitmap[x+20][y+20] = 1; endfunction endclass
initial begin Point p = new; repeat (100) p.do_point; foreach (bitmap[row]) $display( "%b", bitmap[row]); end
endprogram</lang>
Piping the output through sed to improve the contrast of the output:
% vcs -sverilog -R circle.sv | sed 's/0/ /g' 1 11 1 1 1 1 1 11 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 11 1 11 1 1 1 1 1 1 1 1 1 1 1 1 11 1 1 11 1111 1 1 111 1 11 1 111 1 11 1 1 1 1 1 1 1 11 1 1 1 11 1 1
Tcl
<lang tcl>package require Tcl 8.5
- Generate random point at specified distance from the centre
proc getPoint {range from to} {
set r2 [expr {$range / 2}] set f2 [expr {$from ** 2}] set t2 [expr {$to ** 2}] while 1 {
set x [expr {int($range * rand())}] set y [expr {int($range * rand())}] set d2 [expr {($x-$r2)**2 + ($y-$r2)**2}] if {$d2 >= $f2 && $d2 <= $t2} { return [list $y $x] }
}
}
- Make somewhere to store the counters
set ary [lrepeat 31 [lrepeat 31 0]]
- Generate 100 random points
for {set i 0} {$i < 100} {incr i} {
set location [getPoint 31 10 15] # Increment the counter for the point lset ary $location [expr {1 + [lindex $ary $location]}]
}
- Simple renderer
foreach line $ary {
foreach c $line {
puts -nonewline [expr {$c == 0 ? " " : $c > 9 ? "X" : $c}]
} puts ""
}</lang> Example output:
1 1 1 1 1 1 2 1 1 11 1 1 1 11 1 1 1 1 1 1 12 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 2 1 2 2 1 1 1 11 1 1 1 1 1 2 1 1 1 1 1 1 1 11 1 2 1 1 11 11 1 1 1 1 2 1 11 121 1 1 1 1 1 1