Policy change. Edit privileges will now require email addresses to be confirmed. (Details) --Michael Mol 14:53, 14 March 2012 (UTC)

Constrained random points on a circle

From Rosetta Code
Jump to: navigation, search
Task
Constrained random points on a circle
You are encouraged to solve this task according to the task description, using any language you may know.

Generate 100 <x,y> coordinate pairs such that x and y are integers sampled from the uniform distribution with the condition that 10 \leq \sqrt{ x^2 + y^2 } \leq 15 . Then display/plot them. The outcome should be a "fuzzy" circle. The actual number of points plotted may be less than 100, given that some pairs may be generated more than once.

There are several possible approaches to accomplish this. Here are two possible algorithms.

1) Generate random pairs of integers and filter out those that don't satisfy this condition:

10 \leq \sqrt{ x^2 + y^2 } \leq 15 .

2) Precalculate the set of all possible points (there are 404 of them) and select randomly from this set.

Contents

[edit] Ada

with Ada.Text_IO;
with Ada.Numerics.Discrete_Random;
procedure Circle is
-- extreme coordinate values are -15:0, 15:0, 0:-15, 0:15
subtype Coordinate is Integer range -15 .. 15;
type Point is record
X, Y : Coordinate;
end record;
type Point_List is array (Positive range <>) of Point;
 
function Acceptable (Position : Point) return Boolean is
Squared_Sum : Natural := Position.X ** 2 + Position.Y ** 2;
begin
return 10 ** 2 <= Squared_Sum and Squared_Sum <= 15 ** 2;
end Acceptable;
 
-- first algorithm
function Generate_Random_Points
(Count : Positive := 100)
return Point_List
is
package RNG is new Ada.Numerics.Discrete_Random (Coordinate);
Generator  : RNG.Generator;
Next_Point : Point;
Result  : Point_List (1 .. Count);
begin
RNG.Reset (Generator);
for N in Result'Range loop
loop
Next_Point.X := RNG.Random (Generator);
Next_Point.Y := RNG.Random (Generator);
exit when Acceptable (Next_Point);
end loop;
Result (N) := Next_Point;
end loop;
return Result;
end Generate_Random_Points;
 
-- second algorithm
function Choose_Precalculated
(Count : Positive := 100)
return Point_List
is
subtype Possible_Points is Positive range 1 .. 404;
package RNG is new Ada.Numerics.Discrete_Random (Possible_Points);
Generator  : RNG.Generator;
Point_Pool : Point_List (Possible_Points);
Next_Point : Point;
Next_Index : Possible_Points := 1;
Result  : Point_List (1 .. Count);
begin
-- precalculate
Precalculate : for X in Coordinate'Range loop
Next_Point.X := X;
for Y in Coordinate'Range loop
Next_Point.Y := Y;
if Acceptable (Next_Point) then
Point_Pool (Next_Index) := Next_Point;
exit Precalculate when Next_Index = Possible_Points'Last;
Next_Index := Next_Index + 1;
end if;
end loop;
end loop Precalculate;
-- choose
RNG.Reset (Generator);
for N in Result'Range loop
Result (N) := Point_Pool (RNG.Random (Generator));
end loop;
return Result;
end Choose_Precalculated;
 
procedure Print_Points (Points : Point_List) is
Output_String : array (Coordinate, Coordinate) of Character :=
(others => (others => ' '));
begin
for N in Points'Range loop
Output_String (Points (N).X, Points (N).Y) := '*';
end loop;
for Line in Output_String'Range (2) loop
for Column in Output_String'Range (1) loop
Ada.Text_IO.Put (Output_String (Column, Line));
end loop;
Ada.Text_IO.New_Line;
end loop;
end Print_Points;
 
My_Circle_Randomly  : Point_List := Generate_Random_Points;
My_Circle_Precalculated : Point_List := Choose_Precalculated;
begin
Ada.Text_IO.Put_Line ("Randomly generated:");
Print_Points (My_Circle_Randomly);
Ada.Text_IO.Put_Line ("Chosen from precalculated:");
Print_Points (My_Circle_Precalculated);
end Circle;

Output:

Randomly generated:

              **
          *  *    * *
               * * *  **
     *     * *      *
    **  *              * *
   *     *           *  *
      *              *   * *
   *                   **
  *    *               *
    *
    *                       *
   *                      * *
  * *                        *
                             *

   * *                       *
  *
     *                       *
  ***                      *
     *                  *    *
                            *
   *                       *
                     **    *
         **
     *        *   **     *
         * *        * *
      ***  * *         **
        * *   * ***
               *  *

Chosen from precalculated:

            *
            *    *   *
           * **   ** ** *
           * *  * *
                      *
   *  ** *              *
    *    *               * *
  *    *                ***
  *  ***                 *
                        *  * *
                            *

  *                       * *
    *                      **

   *
 *  **                     ***
                           *
                         *   *
  * **
   *                     *
     *
    *   *
         **           *
    *  *     *  *       * *
       **  *       *  * *
      *   **
        *
           *    * ***

[edit] ALGOL 68

Translation of: C
- note: This specimen retains the original C coding style.
Works with: ALGOL 68 version Revision 1 - no extensions to language used - requires ansi/xterm & ascii
Works with: ALGOL 68G version Any - tested with release 1.18.0-9h.tiny
PROC clrscr = VOID: 
printf(($g"[2J"$,REPR 27)); # ansi.sys #
 
PROC gotoxy = (INT x,y)VOID:
printf(($g"["g(0)";"g(0)"H"$,REPR 27, y,x)); # ansi.sys #
 
MODE POINT = STRUCT(
INT x,y
);
 
INT radius = 15;
INT inside radius = 10;
 
POINT center = (radius+1, radius+1);
 
FLEX[0]POINT set;
 
PROC swap with last set = (INT position,INT where last set)VOID:
(
INT temp := x OF set[position];
x OF set[position]:=x OF set[where last set];
x OF set[where last set] := temp;
 
temp := y OF set[position];
y OF set[position]:=y OF set[where last set];
y OF set[where last set] := temp
);
 
PROC create set = VOID:
(
set := HEAP[(2*radius+1)**2]POINT;
INT x,y,i:=LWB set;
 
FOR x FROM -radius TO radius DO
FOR y FROM -radius TO radius DO
IF sqrt(x*x+y*y)>=inside radius AND sqrt(x*x+y*y)<=radius THEN
x OF set[i] := x;
y OF set[i] := y;
i+:=1
FI
OD
OD;
 
set:=set[:i-1]
);
 
PROC plot fuzzy set = (CHAR ch)VOID:
(
INT pos,i;
 
TO UPB set DO
pos := ENTIER(random * UPB set) + 1;
 
gotoxy(x OF center + x OF set[pos],y OF center + y OF set[pos]);
 
print(ch);
 
swap with last set(pos,UPB set)
 
OD
);
 
main:
(
# srand((INT)time(NIL)); #
 
clrscr;
create set;
plot fuzzy set("*");
gotoxy(2*radius+1, 2*radius+1);
newline(stand in)
)

Sample output:

           *  * **
        * * *  * ** **
      ***** **   ***** **
     ** **  *  * * * ***
      *  ******** *** *** *
   ** *****         ** * ***
        *            ***** *
   ** **               **** *
   * * *               ****
  ****                  * ****
 * **                    *** *
 ** **                    **
 **                      * * *
  ****                   **  *
 ** *                    ****
 ****                     ** *
 *  **                   *  **
  * **                    *  *
 * ***                    *  *
 ******                 * * **
  * * **               **** *
   ** *                ***  *
   **** **           *    **
    ** ***            * ***
    * *  *** * **  *** ***
      *  *  ** ***** ****
      ** ******* *  *
        * ** ** *******
          *  ****** *
               *

[edit] AutoHotkey

Requires the GDI+ standard library by tic: http://www.autohotkey.com/forum/viewtopic.php?t=32238
Works with individual pixels.

Ahk fuzzycircle.png
z=100 ; x = x-coord; y = y-coord; z = count; pBitmap = a pointer to the image; f = filename
 
pToken := Gdip_Startup()
pBitmap := Gdip_CreateBitmap(31, 32)
 
While z
{
Random, x, -20, 20
Random, y, -20,20
If ( t := sqrt(x**2 + y**2) ) >= 10 && t <= 15
Gdip_SetPixel(pBitmap, x+15, y+16, 255<<24), z--
}
 
Gdip_SaveBitmapToFile(pBitmap, f := A_ScriptDir "\ahk_fuzzycircle.png")
run % f
 
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)

[edit] BBC BASIC

      MODE 8
ORIGIN 640, 512
FOR i% = 1 TO 1000
x% = RND(31)-16
y% = RND(31)-16
r = SQR(x%^2 + y%^2)
IF r >= 10 IF r <= 15 PLOT x%*2, y%*2
NEXT

[edit] C

#include <stdio.h>
#include <stdlib.h>
 
inline
int randn(int m)
{
int rand_max = RAND_MAX - (RAND_MAX % m);
int r;
while ((r = rand()) > rand_max);
return r / (rand_max / m);
}
 
int main()
{
int i, x, y, r2;
unsigned long buf[31] = {0}; /* could just use 2d array */
 
for (i = 0; i < 100; ) {
x = randn(31) - 15;
y = randn(31) - 15;
r2 = x * x + y * y;
if (r2 >= 100 && r2 <= 225) {
buf[15 + y] |= 1 << (x + 15);
i++;
}
}
 
for (y = 0; y < 31; y++) {
for (x = 0; x < 31; x++)
printf((buf[y] & 1 << x) ? ". " : " ");
printf("\n");
}
 
return 0;
}
Output
                            .   .     . .                     
. . .
. . . .
. . .
. . . . .
. . .
. . .
. .
. .
. .
. .
. . . .
. . .
 
.
.
 
. . .
. . .
. . .
. . . .
. . . . .
. .
. . . .
. . . . . . .
. . . .
. . . . . . .
. . . .
.
.

[edit] Clojure

(import '[java.awt Color Graphics Dimension]
'[javax.swing JFrame JPanel])
 
(let [points (->> (for [x (range -15 16)
y (range -15 16)
:when (<= 10 (Math/sqrt (+ (* x x) (* y y))) 15)]
[(+ x 15) (+ y 15)])
shuffle
(take 100 ,))]
(doto (JFrame.)
(.add (doto (proxy [JPanel] []
(paint [^Graphics g]
(doseq [[x y] points]
(.fillRect g (* 10 x) (* 10 y) 10 10))))
(.setPreferredSize (Dimension. 310 310))))
(.setResizable false)
(.setDefaultCloseOperation JFrame/DISPOSE_ON_CLOSE)
.pack
.show))

[edit] CoffeeScript

 
NUM_POINTS = 100
MIN_R = 10
MAX_R = 15
 
random_circle_points = ->
rand_point = ->
Math.floor (Math.random() * (MAX_R * 2 + 1) - MAX_R)
 
points = {}
cnt = 0
while cnt < 100
x = rand_point()
y = rand_point()
continue unless MIN_R * MIN_R <= x*x + y*y <= MAX_R * MAX_R
points["#{x},#{y}"] = true
cnt += 1
points
 
plot = (points) ->
range = [-1 * MAX_R .. MAX_R]
for y in range
s = ''
for x in range
s += if points["#{x},#{y}"] then '*' else ' '
console.log s
 
plot random_circle_points()
 

The output may be a bit distorted, since even monospace fonts take more vertical space per character than horizontal space.

 
> coffee foo.coffee
 
** *
* ** * *
* * * *
* ** *
* * * *
* *
*
* *
***
** **** *
* *
* *
**
*
 
* **
* * *
**
* * **
* *
* *
* *
* *
***
*** * * * * *
*** *
* * * * *
* * *
 

[edit] Common Lisp

(flet ((good-p (x y) (<= 100 (+ (* x x) (* y y)) 255)))
(loop with x with y with cnt = 0
with scr = (loop repeat 31 collect (loop repeat 31 collect " "))
while (< cnt 100)
do (when (good-p (- (setf x (random 31)) 15)
(- (setf y (random 31)) 15))
(setf (elt (elt scr y) x) "@ ")
(incf cnt))
finally (mapc #'(lambda (row) (format t "~{~a~^~}~%" row)) scr)))

[edit] D

This uses std.complex because D built-in complex numbers will be deprecated.

import std.stdio, std.random, std.math, std.complex;
 
void main() {
char[31][31] table = ' ';
 
foreach (i; 0 .. 100) {
int x, y;
do {
x = uniform(-15, 16);
y = uniform(-15, 16);
} while(abs(12.5 - complex(x, y).abs) > 2.5);
table[x + 15][y + 15] = '*';
}
 
foreach (row; table)
writeln(row);
}
                               
                   *           
          * **  *              
                  * *          
     **  * *   **  *  *        
    *    *            **  *    
        **            **  *    
                       *   *   
                        *      
       *                 ***   
 *  * *                        
   * *                     *   
   *                        *  
     *                      *  
   **                    * *   
  *                       *    
                            *  
                             * 
  *                          * 
                               
   *                           
     *                     **  
    * *                  *     
         *           * *  *    
   *     *             **      
    *     *  *  *     * *      
     **     *  **   **   *     
          **                   
        *     *  *  *          
               **              

[edit] Euphoria

Works with: Euphoria version 4.0.3, 4.0.0 or later

This program generates the set of 404 possible points in the ring. It randomly chooses 100 pairs from the set. The 100 pairs are a subset of that set because duplicates are discarded.

include std/console.e
 
sequence validpoints = {}
sequence discardedpoints = {}
sequence rand100points = {}
atom coordresult
integer randindex
 
--scan for all possible values. store discarded ones in another sequence, for extra reference.
for y = -15 to 15 do
for x = -15 to 15 do
 
coordresult = sqrt( x * x + y * y )
 
if coordresult >= 10 and coordresult <= 15 then --if it would fall in the ring area
validpoints &= {{x, y, coordresult}} --concatenate (add to the end) the coordinate pair x, y and the
-- result into a subsequence of sequence validpoints
else
discardedpoints &= {{x, y, coordresult}} --else put it in the discarded sequence
end if
 
end for
end for
 
for i = 1 to 100 label "oneofhundred" do --make 100 random coordinate pairs
randindex = rand(length(validpoints) ) --random value from 1 to the number of 3 value subsequences in validpoints (the data)
 
if length(rand100points) = 0 then --if rand100points sequence is empty, add the first subsequence to it.
rand100points &= {validpoints[randindex]}
 
else --if it isn't empty, then..
for j = 1 to length(rand100points) do --loop through each "data chunk" in rand100points
 
if equal(validpoints[randindex], rand100points[j]) = 1 then --if any are the same as the randomly chosen chunk in
retry "oneofhundred" -- validpoints, then retry from one line below the "oneofhundred" loop without incrementing i.
end if --the continue keyword would increment i instead.
 
end for
 
rand100points &= {validpoints[randindex]} --length of rand100points isnt 0 and no data chunks match ones that the program
--already picked before, so add this subsequence chunk to rand100points.
end if
 
end for
 
for i = 1 to 32 do --32 lines
printf(1,"\n")
for j = 1 to 32 label "xscan" do --32 characters on each line
 
for k = 1 to length(rand100points) do --for every subsequence in this
if rand100points[k][1]+16 = j and rand100points[k][2]+16 = i then --if the x and y coordinates in the picked points
printf(1, 178) --(adjusted to minimum of 1,1) are at the same place as in the console output grid
continue "xscan" --print a funny character and continue to the next "xscan"
end if
end for
 
printf(1, 176) --if no picked points were there, print another funny character to represent a blank space
 
end for
end for
 
printf(1, "\nNumber of valid coordinate pairs %d :", length(validpoints) )
printf(1, "\nNumber of discarded coordinate pairs : %d", length(discardedpoints) )
printf(1, "\nNumber of randomly picked coordinate pairs : %d\n", length(rand100points) )
any_key()

Output:

░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
░░░░░░░░░░░░░░░░░▓░░░░░░░░░░░░░░
░░░░░░░░░░░░░▓░░░░░░░░░░░░░░░░░░
░░░░░░░░░▓░░░▓▓░▓░░░▓░░░░░░░░░░░
░░░░░░▓░░░░░░▓░░░▓░░░░░▓░▓░░░░░░
░░░░░░░░░▓░▓░░░░░░░▓░░▓░░▓▓░░░░░
░░░▓░░░░▓░▓░░░░░░░░░░░░▓░░░░░░░░
░░░░░░░░░▓░░░░░░░░░░░▓░░░▓░░░░░░
░░░░░░░░░░░░░░░░░░░░░░░░▓▓░░▓░░░
░░░░░░▓▓░░░░░░░░░░░░░░░▓░░░░░░░░
░░░░░░▓░░░░░░░░░░░░░░░░░░░░░░░░░
░▓░░▓▓░░░░░░░░░░░░░░░░░░░░░░░▓░░
░░░░░▓░░░░░░░░░░░░░░░░░░░░░░▓░░░
░░▓░░░░░░░░░░░░░░░░░░░░░░▓▓▓▓░░░
░▓░░▓░░░░░░░░░░░░░░░░░░░░░░░░░░░
░░░░▓░░░░░░░░░░░░░░░░░░░░▓▓▓░▓░░
░░░▓░░░░░░░░░░░░░░░░░░░░░▓░▓░▓░░
░▓▓░░░░░░░░░░░░░░░░░░░░░░░▓▓░░░░
░░░▓░▓░░░░░░░░░░░░░░░░░░░▓░░░░░░
░░░▓░░░░░░░░░░░░░░░░░░░░░▓░░░▓░░
░░▓░▓░░░░░░░░░░░░░░░░░░░▓░░░▓░░░
░░░░░░░▓░░░░░░░░░░░░░░░▓░░░░░░░░
░░░▓░░░░░░░░░░░░░░░░░░░▓░░░░░░░░
░░░░░░░░░░░░░░░░░░░░░░░░▓░░░░░░░
░░░░░░▓░░▓░░░░░░░░░░░▓░▓░░░░░░░░
░░░░░░░░░░░░░░░░░▓░░░░░░░░░░░░░░
░░░░░░░▓░░▓░░░░░░░░░░░░▓░░░░░░░░
░░░░░░░░░░░░░▓░▓▓▓▓░░░▓▓░░░░░░░░
░░░░░░░░░▓▓░░▓░░▓░░▓▓░░░░░░░░░░░
░░░░░░░░░░▓░░▓░▓▓▓░░▓░░░░░░░░░░░
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
Number of valid coordinate pairs 404 :
Number of discarded coordinate pairs : 557
Number of randomly picked coordinate pairs : 100
Press Any Key to continue...
Extra EuSDL code :
 
for i = 1 to length(validpoints) do --simple each pixel output to screen surface
dummy=pixelColor(surface,validpoints[i][1]+18,validpoints[i][2]+18,#AA0202FF) --i is index number of each subsequence 'chunk'.
--index 1 is x, index 2 is y, inside that chunk.
end for
 
for i = 1 to length(discardedpoints) do
dummy=pixelColor(surface,discardedpoints[i][1]+18,discardedpoints[i][2]+52,#0202AAFF)
end for
 
for i = 1 to length(rand100points) do
dummy=pixelColor(surface,rand100points[i][1]+55,rand100points[i][2]+52,#02AA02FF)
end for
 
dummy=boxColor(surface,0,71,395,111,#232323FF) --background box
dummy=stringColor(surface,0,73,sprintf("Number of valid coordinate pairs %d :", length(validpoints) ),#AA0202FF)
 
dummy=stringColor(surface,0,83,sprintf("Number of discarded coordinate pairs : %d", length(discardedpoints) ),#0202AAFF)
 
dummy=stringColor(surface,0,93,sprintf("Number of randomly picked coordinate pairs : %d", length(rand100points) ),#02AA02FF)
SDL Output :

Fuzzy circle Euphoria.png That particular program used a -16 to +16 square area, so more was discarded.

[edit] F#

This version uses method 1 from the task description and just calculates 100 suitable points to plot. The INTERACTIVE bit just permits this code in a .fsx file to be run with the interactive interpreter or compiled to an exe.

module CirclePoints =
let main args =
let rnd = new System.Random()
let rand size = rnd.Next(size) - size/2
let size = 30
let gen n =
let rec f (x,y) =
let t = (int (sqrt (float (x*x + y*y)) ))
if 10 <= t && t <= 15 then (x,y) else f (rand size, rand size)
f (rand size, rand size)
let plot = Array.init 100 (fun n -> gen n)
for row in 0 .. size-1 do
let chars = Array.create (size+1) ' '
Array.choose (fun (x,y) -> if y = (row-size/2) then Some(x) else None) plot
|> Array.iter (fun x -> chars.[x+size/2] <- 'o')
printfn "%s" (new string(chars))
0
 
#if INTERACTIVE
CirclePoints.main fsi.CommandLineArgs
#else
[<EntryPoint>]
let main args = CirclePoints.main args
#endif

An example of the output:

          o  o oo
              o       o

         o o        o o
    o   o o oo o o       o o
   o                      o
     o  oo             oooo
     o                  oo
                       o  o
   oo                      o
  oooo                   o  o
 o                         o
    o
  o
  o                       oo
 o                          o
   o
     o
                         o
      o
   oo                    oo  o
                           o
   o  o  o                o
    o                   o o
    o         o  o  oo
       oo         o oo    o
     o   o      o  o
      o o      o oo   o
              o   o

[edit] Fortran

Works with: Fortran version 90 and later
program Constrained_Points
implicit none
 
integer, parameter :: samples = 100
integer :: i, j, n, randpoint
real :: r
 
type points
integer :: x, y
end type
 
type(points) :: set(500), temp
 
! Create set of valid points
n = 0
do i = -15, 15
do j = -15, 15
if(sqrt(real(i*i + j*j)) >= 10.0 .and. sqrt(real(i*i + j*j)) <= 15.0) then
n = n + 1
set(n)%x = i
set(n)%y = j
end if
end do
end do
 
! create 100 random points
! Choose a random number between 1 and n inclusive and swap point at this index with point at index 1
! Choose a random number between 2 and n inclusive and swap point at this index with point at index 2
! Continue in this fashion until 100 points have been selected
call random_seed
do i = 1, samples
call random_number(r)
randpoint = r * (n + 1 - i) + i
temp = set(i)
set(i) = set(randpoint)
set(randpoint) = temp
end do
 
! In order to facilitate printing sort random points into ascending order
! sort x in ascending order
do i = 2, samples
j = i - 1
temp = set(i)
do while (j>=1 .and. set(j)%x > temp%x)
set(j+1) = set(j)
j = j - 1
end do
set(j+1) = temp
end do
 
! sort y in ascending order for same x
do i = 2, samples
j = i - 1
temp = set(i)
do while (j>=1 .and. set(j)%x == temp%x .and. set(j)%y > temp%y)
set(j+1) = set(j)
j = j - 1
end do
set(j+1) = temp
end do
 
! print circle
write(*,"(a,a)", advance="no") repeat(" ", set(1)%y+15), "*"
do i = 2, samples
if(set(i)%x == set(i-1)%x) then
write(*,"(a,a)", advance="no") repeat(" ", set(i)%y - set(i-1)%y-1), "*"
else
n = set(i)%x - set(i-1)%x
do j = 1, n
write(*,*)
end do
write(*,"(a,a)", advance="no") repeat(" ", set(i)%y+15), "*"
end if
end do
 
end program

Output

                  * * 
        *   *         * 
      ** **    * **    * 
                ** 
     *  **   * **    * 
   ***   **               * 
    *    *           * 
                           * 
  *                      *  * 
     **                   * 
   *                      * 
  *  *                   * 
    *                        * 
    * 
    **                   ***  * 
    *                    * 
    **                   * 
    *                    * 
   *                      * 
  *   *                      * 
      **                 *  * 
    * *                *  ** 
   ** * *               * 
     * 
          ***         * * * 
     **         *   *    * 
         *  * * * 
         *     *  ** * 
            *

[edit] Go

Algorithm 1:

package main
 
import (
"bytes"
"fmt"
"math/rand"
"time"
)
 
type pt struct {
x, y int
}
 
func main() {
rand.Seed(time.Now().UnixNano())
// generate random points, accumulate 100 distinct points meeting condition
m := make(map[int]pt) // key is buffer index
for len(m) < 100 {
p := pt{rand.Intn(31) - 15, rand.Intn(31) - 15}
rs := p.x*p.x + p.y*p.y
if 100 <= rs && rs <= 225 {
m[(p.x+15)*2+(p.y+15)*31*2] = p
}
}
// plot to buffer
b := bytes.Repeat([]byte{' '}, 31*31*2)
for i := range m {
b[i] = '*'
}
// print buffer to screen
for i := 0; i < 31; i++ {
fmt.Println(string(b[i*31*2 : (i+1)*31*2]))
}
}

Algorithm 2:

package main
 
import (
"bytes"
"fmt"
"math/rand"
)
 
type pt struct {
x, y int
}
 
func main() {
// generate possible points
all := make([]pt, 0, 404)
for x := -15; x <= 15; x++ {
for y := -15; y <= 15; y++ {
rs := x*x + y*y
if 100 <= rs && rs <= 225 {
all = append(all, pt{x, y})
}
}
}
if len(all) != 404 {
panic(len(all))
}
// randomly order
rp := rand.Perm(404)
// plot 100 of them to a buffer
b := bytes.Repeat([]byte{' '}, 31*31*2)
for i := 0; i < 100; i++ {
p := all[rp[i]]
b[(p.x+15)*2+(p.y+15)*31*2] = '*'
}
// print buffer to screen
for i := 0; i < 31; i++ {
fmt.Println(string(b[i*31*2 : (i+1)*31*2]))
}
}

Output:

                      *   *           * *                     
                        * *   *                               
                  *                 *   *   *                 
          *   *   *       *             * * *                 
                *       *         *       * *                 
            *                             * *     *           
          *     * *                         *                 
                                                      * *     
        *   *                                   *             
          * *                                   *   *   *     
                                                        *     
        * *                                         * * *     
                                                  *     *     
    *                                                     *   
                                                  *           
  *       *                                       *           
                                                    *         
  * *     *                                                   
  *     *                                                     
  * *                                                         
    *     *                                                   
        *   * *                                     *         
            *                               *                 
              *   * *                               *         
            *     *   *       *         *                     
          * * *                 *         *   *   *           
            *         *   * * *       *         *             
                    *     *                                   
                          *   *   * *                         

[edit] Haskell

Using Knuth Shuffle

import Data.List
import Control.Monad
import Control.Arrow
import Rosetta.Knuthshuffle
 
task = do
let blanco = replicate (31*31) " "
cs = sequence [[-15,-14..15],[-15,-14..15]] :: [[Int]]
constraint = uncurry(&&).((<= 15*15) &&& (10*10 <=)). sum. map (join (*))
-- select and randomize all circle points
pts <- knuthShuffle $ filter constraint cs
-- 'paint' first 100 randomized circle points on canvas
let canvas = foldl (\cs [x,y] -> replaceAt (31*(x+15)+y+15) "/ " cs ) blanco (take 100 pts)
-- show canvas
mapM_ (putStrLn.concat). takeWhile(not.null). map (take 31) $ iterate (drop 31) canvas

Output (added a trailing space per 'pixel'

*Main> task
                                                              
                      /             / /                       
                          /     /       /                                       
              /                 /                                               
          /     /               /       / / /   /                               
            /                 / /       /                                       
      /     /     /                       /   /                                 
      /         /                           /                                   
        /   / /                                     /   /                       
        / / /                                 /       / /                       
                                                    /                           
    /     /                                       /                             
      / /                                             /                         
      /                                               /   /                     
        /                                                                       
/ /                                                   /     / 
                                                      /   /                     
                                                      /   /                     
      /                                                                         
      /                                             /                           
  /                                                   /       
                                                /     /                         
    /     /                                       /           
              / /                         / /         /       
        /   /       /                             /           
                          / /     / / /   / /                 
          / /             /                   /               
                            / /                               
                /   /   / / /   /       / /                   
                      /             / /

[edit] Icon and Unicon

Generate random points in the bounded by the outside edge. Reject any found out of the prescribed bounds and stop when the required numbers of points have been generated.
plot of 2000, 100, 120
link graphics
 
procedure main(A) # points, inside r, outside r in pixels - default to task values
 
if \A[1] == "help" then stop("Usage: plot #points inside-radius outside-radius")
points := \A[1] | 100
outside := \A[2] | 15
inside := \A[3] | 10
if inside > outside then inside :=: outside
 
wsize := integer(2.2*outside)
wsize <:= 150
center := wsize/2
 
WOpen("size="||wsize||","||wsize,"bg=black","fg=white") | stop("Unable to open window")
 
until(points -:= 1) <= 0 do {
x := ?(2*outside)-outside # random x
y := ?(2*outside)-outside # and y
if (inside <= integer(sqrt(x^2+y^2)) ) <= outside then
DrawPoint(x + center,y + center)
}
WDone()
 
end

[edit] J

This version deals 100 distinct coordinates from the set of acceptable coordinates (much like dealing cards from a shuffled deck):

gen=: ({~ 100?#)bind((#~ 1=99 225 I.+/"1@:*:),/,"0/~i:15)

Example use (gen'' generates the points, the rest of the example code deals with rendering them as a text array):

   '*' (<"1]15+gen '')} 31 31$' '
 
*
*
* * * * * *
* * * * *
* ***
** * * **
* **
* **
* * * *
* * **
* ** **
** * ***
* ** * *
** *
* ** *
** *
* ** *
* *
* *
* *
** *
* **
*
* * * *
* ** * * *
* *
**
* * *
** *

[edit] Java

import java.util.Random;
 
public class FuzzyCircle {
static final Random rnd = new Random();
public static void main(String[] args){
char[][] field = new char[31][31];
for(int i = 0; i < field.length; i++){
for(int j = 0; j < field[i].length; j++){
field[i][j] = ' ';
}
}
int pointsInDisc = 0;
while(pointsInDisc < 100){
int x = rnd.nextInt(31) - 15;
int y = rnd.nextInt(31) - 15;
double dist = Math.hypot(x, y);
if(dist >= 10 && dist <= 15 && field[x + 15][y + 15] == ' '){
field[x + 15][y + 15] = 'X';
pointsInDisc++;
}
}
for(char[] row:field){
for(char space:row){
System.out.print(space);
}
System.out.println();
}
}
}

Output:

                               
            XX X               
        X X    X  X   X        
       X        XX  X          
     XXXX      X        X      
    X    X      X  XXX         
        X             X        
    X                 X  XXX   
    X                     X    
       X               X   XX  
 X   X                       X 
    XX                    X    
                           X   
                               
 X                         X   
 XXXXX                   X   X 
                          X X  
                         X   X 
                          X X  
 X   X                    X    
 X                        X    
    XX                 X       
    XX                  X      
        X            XX   X    
     X XX              X       
    X       X X  X      X      
     XX   X     X      XXX     
        X    X X X     XX      
            X         X        
               X               
               X               

[edit] JavaScript

JavaScript embedded in HTML, using canvas:

<html><head><title>Circle</title></head>
<body>
<canvas id="cv" width="320" height="320"></canvas>
<script type="application/javascript">
 
var cv = document.getElementById('cv');
var ctx = cv.getContext('2d');
 
var w = cv.width;
var h = cv.height;
 
//draw circles
ctx.fillStyle = 'rgba(0, 255, 200, .3)';
ctx.strokeStyle = 'rgba(0,0,0,.1)';
ctx.beginPath();
ctx.arc(w/2, h/2, 150, 0, Math.PI*2, true);
ctx.arc(w/2, h/2, 100, 0, Math.PI*2, false);
ctx.closePath();
ctx.fill();
 
// draw grids
ctx.beginPath();
for (var i = 10; i < w; i += 10) {
ctx.moveTo(i, 0);
ctx.lineTo(i, h);
ctx.moveTo(0, i);
ctx.lineTo(w, i);
}
ctx.closePath();
ctx.stroke();
 
//draw points
ctx.fillStyle = 'navy';
var pts = 0;
while (pts < 100) {
var x = Math.floor(Math.random() * 31) - 15;
var y = Math.floor(Math.random() * 31) - 15;
var r = x * x + y * y;
if (r < 100 || r > 225) continue;
x = x * 10 + w/2;
y = y * 10 + h/2;
ctx.fillRect(x - 2, y - 2, 4, 4);
pts++;
}
 
</script></body></html>

[edit] Liberty BASIC

'   RC Constrained Random Points on a Circle
 
nomainwin
 
WindowWidth =400
WindowHeight =430
 
open "Constrained Random Points on a Circle" for graphics_nsb as #w
 
#w "trapclose [quit]"
#w "down ; size 7 ; color red ; fill black"
 
for i =1 to 1000
do
x =int( 30 *rnd( 1)) -15
y =int( 30 *rnd( 1)) -15
loop until IsInRange( x, y) =1
#w "set "; 200 +10 *x; " "; 200 - 10 *y
next
 
wait
 
function IsInRange( x, y)
z =sqr( x*x +y*y)
if 10 <=z and z <=15 then IsInRange =1 else IsInRange =0
end function
 
[quit]
close #w
end

[edit] Locomotive Basic

10 MODE 1:RANDOMIZE TIME
20 FOR J=1 TO 100
30 X=INT(RND*30-15)
40 Y=INT(RND*30-15)
50 D=X*X+Y*Y
60 IF D<100 OR D>225 THEN GOTO 40
70 PLOT 320+10*X,200+10*Y:LOCATE 1,1:PRINT J
80 NEXT
90 CALL &BB06 ' wait for key press

Points on a circle locomotive basic.png

[edit] Mathematica

This algorithm generates 500 pairs of random integers between +/- 15, picks out the ones that satisfy the inequality, and then takes the first 100 of those. It oversamples to reduce the chance of having less than 100 "candidates", which is not impossible, though extremely unlikely.

sample = Take[Cases[RandomInteger[{-15, 15}, {500, 2}], {x_, y_} /; 10 <= Sqrt[x^2 + y^2] <= 15], 100];
 
Show[{RegionPlot[10 <= Sqrt[x^2 + y^2] <= 15, {x, -16, 16}, {y, -16, 16}, Axes -> True], ListPlot[sample]}]

[edit] MATLAB

Uses the Monte-Carlo method described above.

function [xCoordinates,yCoordinates] = randomDisc(numPoints)
 
xCoordinates = [];
yCoordinates = [];
 
%Helper function that samples a random integer from the uniform
%distribution between -15 and 15.
function nums = randInt(n)
nums = round((31*rand(n,1))-15.5);
end
 
n = numPoints;
 
while n > 0
 
x = randInt(n);
y = randInt(n);
 
norms = sqrt((x.^2) + (y.^2));
inBounds = find((10 <= norms) & (norms <= 15));
 
xCoordinates = [xCoordinates; x(inBounds)];
yCoordinates = [yCoordinates; y(inBounds)];
 
n = numPoints - numel(xCoordinates);
end
 
xCoordinates(numPoints+1:end) = [];
yCoordinates(numPoints+1:end) = [];
 
end

Output:

>> [x,y] = randomDisc(100);
>> plot(x,y,'.')

Matlab-randomDisc-output.png


[edit] OCaml

let p x y =
let d = sqrt(x ** 2.0 +. y ** 2.0) in
10.0 <= d && d <= 15.0
 
let () =
Random.self_init();
let rec aux i acc =
if i >= 100 then acc else
let x = (Random.float 40.0) -. 20.0
and y = (Random.float 40.0) -. 20.0 in
if (p x y)
then aux (succ i) ((x,y)::acc)
else aux i acc
in
let points = aux 0 [] in
let g = Array.init 40 (fun _ -> String.make 40 ' ') in
List.iter (fun (x,y) ->
let x = (int_of_float x) + 20
and y = (int_of_float y) + 20 in
g.(y).[x] <- 'o'
) points;
Array.iter print_endline g


                o   o     o
                o
           oo      oo     oooo
               o      o   oo o
        oo
          o                o   o
         o
      oo  o
       oo o                 oo  o
                              oo
                              oo
         o                     o
      oooo                     o o
        oo                  o o
        o                    oo
                                 o
      o  o                  o  o
        o  o                 o o
       o  o
          o                   o
        o    o              oo
            o             oo
         o            o
             ooo o o       o
             o  ooo     o
              o
                 oo  o

[edit] PARI/GP

crpc()={
my(v=vector(404),t=0,i=0,vx=vy=vector(100));
for(x=1,14,for(y=1,14,
t=x^2+y^2;
if(t>99&t<226,
v[i++]=[x,y];
v[i++]=[x,-y];
v[i++]=[-x,y];
v[i++]=[-x,-y]
)
));
for(x=10,15,
v[i++]=[x,0];
v[i++]=[-x,0];
v[i++]=[0,x];
v[i++]=[0,-x]
);
for(i=1,#vx,
t=v[random(#v)+1];
vx[i]=t[1];
vy[i]=t[2];
);
plothraw(vx,vy)
};

[edit] Perl

my @points;
while (@points < 100) {
my ($x, $y) = (int(rand(31))-15, int(rand(31)) - 15);
my $r2 = $x*$x + $y*$y;
next if $r2 < 100 || $r2 > 225;
push @points, [$x, $y];
}
 
print << 'HEAD';
%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox 0 0 400 400
200 200 translate 10 10 scale
0 setlinewidth
1 0 0 setrgbcolor
0 0 10 0 360 arc stroke
0 0 15 360 0 arcn stroke
0 setgray
/pt { .1 0 360 arc fill } def
HEAD

 
print "@$_ pt\n" for @points;
print "%%EOF";

Randomly generates points and reject ones not in the ring. Writes an EPS file.

[edit] Perl 6

my @range = -15..16;
 
my @points = gather for @range X @range -> $x, $y {
take [$x,$y] if 10 <= sqrt($x*$x+$y*$y) <= 15
}
my @samples = @points.roll(100); # or .pick(100) to get distinct points
 
# format and print
my %matrix;
for @range X @range -> $x, $y { %matrix{$y}{$x} = ' ' }
%matrix{$_[1]}{$_[0]} = '*' for @samples;
%matrix{$_}{@range}.join(' ').say for @range;

Turning that program completely inside-out and reducing to a single statement with a single non-parameter variable, we get this version, which also works:

(say ~.map: { $_ // ' ' } for my @matrix) given do
-> [$x, $y] { @matrix[$x][$y] = '*' } for pick 100, do
for ^32 X ^32 -> $x, $y {
[$x,$y] when 100..225 given [+] ($x,$y X- 15) X** 2;
}
 

This uses, among other things, a 0-based matrix rather than a hash, a given on the first line that allows us to print the final value of the matrix straight from its initial declaration, a for statement feeding a for statement modifier, a lambda that unpacks a single x-y argument into two variables, the functional form of pick rather than the method form, a quasi-list comprehension in the middle loop that filters each given with a when, precalculated squared limits so we don't have to take the square root, use of X- and X** to subtract and exponentiate both $x and $y in parallel.

After the given do has loaded up @matrix with our circle, the map on the first line substitutes a space for any undefined matrix element, and the extra space between elements is supplied by the stringification of the list value, performed by the prefix ~ operator, the unary equivalent of concatenation in Perl 6.

At this point you would be justified in concluding that we are completely mad. :-)

[edit] PicoLisp

(let Area (make (do 31 (link (need 31 " "))))
(use (X Y)
(do 100
(until
(>=
15
(sqrt
(+
(* (setq X (rand -15 15)) X)
(* (setq Y (rand -15 15)) Y) ) )
10 ) )
(set (nth Area (+ 16 X) (+ 16 Y)) "#") ) )
(mapc prinl Area) )

Output:

           #
        ##
           #  #  #  #
         ## #    #  #   #
       #      #   # # #
    #       #     # #   #
      #   #         #    #
      #                #   #
                       #
       #               #
     ##                      #
                          #
   #                      # #
  ###                      #
 #                         # #
##                          # #
  #                        #
 #                        #
 ## #
                           #
   #
     #                 #
     #
   ###                  #   #
      ###           # #    #
    #      #
         #  #   ##
                 # #
      #     #           #
                # #  #

[edit] PL/I

 
constrain: procedure options (main);
declare 1 point (100),
2 x fixed binary,
2 y fixed binary;
declare (i, j, a, b, c) fixed binary;
 
j = 0;
do i = 1 to 100;
a = 30*random()-15; b = 30*random()-15;
c = sqrt(a**2 + b**2);
if abs(c) >= 10 & abs(c) <= 15 then
do; j = j + 1; x(j) = a; y(j) = b; end;
end;
 
/* PLOT */
declare table(-15:15, -15:15) character (1);
table = ' ';
do i = 1 to j;
table(x(i), y(i)) = '*';
end;
do i = -15 to 15;
put skip;
do j = -15 to 15;
put edit (table(i,j)) (a);
end;
end;
end constrain;
 

Output:

        **  *                  
                *   *          
                               
    **                         
         **                    
                               
                         *     
                           *** 
      *                        
                               
                               
                         *     
    **                         
                               
                           *   
 * **                          
                               
                               
                        * *    
  **                        *  
     * *                       
                               
                     ***       
                         ***   
       ***                     
            *                  
                     *

[edit] Prolog

Works with SWI-Prolog

:- use_module(library(clpfd)).
 
circle :-
bagof([X,Y], init(X,Y), BL),
length(BL, N),
length(L, 100),
maplist(choose(BL, N), L),
draw_circle(L).
 
 
% point selection
choose(BL, N, V) :-
I is random(N),
nth0(I, BL, V).
 
% to find all couples of numbers verifying
% 100 <= x^2 + y^2 <= 225
init(X1, Y1) :-
X in -15..15,
Y in -15..15,
X*X + Y*Y #>= 100,
X*X + Y*Y #=< 225,
label([X,Y]),
X1 is 10 * X + 200,
Y1 is 10 * Y + 200.
 
 
draw_circle(L) :-
new(D, window('Circle')),
send(D, size,size(400,400)),
forall(member([X,Y], L),
( new(C, circle(4)),
send(C, fill_pattern, colour(@default, 0, 0, 0)),
send(C, center(point(X,Y))),
send(D, display, C))),
send(D, open).
 

Prolog-Circle.jpg

[edit] PureBasic

CreateImage(0,31,31)
StartDrawing(ImageOutput(0))
For i=1 To 100
Repeat
x=Random(30)-15
y=Random(30)-15
R.f=Sqr(x*x+y*y)
Until 10<=R And R<=15
Plot(x+15,y+15,#Red)
Next
StopDrawing()
 
Title$="PureBasic Plot"
Flags=#PB_Window_SystemMenu
OpenWindow(0,#PB_Ignore,#PB_Ignore,ImageWidth(0),ImageHeight(0),Title$,Flags)
ImageGadget(0,0,0,ImageWidth(0),ImageHeight(0),ImageID(0))
Repeat: Until WaitWindowEvent()=#PB_Event_CloseWindow

PureBasic Circle plot.png

[edit] Python

Note that the diagram shows the number of points at any given position (up to a maximum of 9 points).

>>> from collections import defaultdict
>>> from random import choice
>>> world = defaultdict(int)
>>> possiblepoints = [(x,y) for x in range(-15,16)
for y in range(-15,16)
if 10 <= abs(x+y*1j) <= 15]
>>> for i in range(100): world[choice(possiblepoints)] += 1
 
>>> for x in range(-15,16):
print(''.join(str(min([9, world[(x,y)]])) if world[(x,y)] else ' '
for y in range(-15,16)))
 
 
 
1 1
1 1
11 1 1 1 1
111 1 1211
1 2 1 1 11
1 11 21
1 1 11 1
1 2 1 1
 
1 2
1 1 1
1 1
2 11
1 1
1
 
 
1 1
1
2
1
1 1 1
1 2 1
1 3 11 2
11 1 1 1 2
1 1 2
1 1
1 1 1
2 2 1
1

If the number of samples is increased to 1100:

>>> for i in range(1000): world[choice(possiblepoints)] += 1
 
>>> for x in range(-15,16):
print(''.join(str(min([9, world[(x,y)]])) if world[(x,y)] else ' '
for y in range(-15,16)))
 
 
2
41341421333
5133333131253 1
5231514 14214721 24
326 21222143234122322
54235153132123344125 22
32331432 2422 33
5453135 4144344
132595 323123
4 6353 432224
5 4323 3 5313
23214 41433
42454 33342
332 4 34314
142 1 35 53
124211 53131
22221 152 4
22213 34562
654 4 4 212
24354 52232
544222 283323
411123 453325
251321 124332
2124134 2443226
2 113315 64324334
2412452 324 32121132363
4222434324635 5433
3113333123432112633
2131181233 424
47414232164
4

[edit] R

 
RMin <- 10
RMax <- 15
NPts <- 100
 
# instead of a for loop, we generate what should be enough points
# also take care to have enough range to avoid rounding inaccuracies
nBlock <- NPts * ((RMax/RMin) ^ 2)
nValid <- 0
while (nValid < NPts) {
X <- round(runif(nBlock, -RMax - 1, RMax + 1))
Y <- round(runif(nBlock, -RMax - 1, RMax + 1))
R <- sqrt(X^2 + Y^2)
Valid <- ( (R >= RMin) & (R <= RMax) )
nValid <- sum(Valid)
nBlock <- 2 * nBlock
}
plot(X[Valid][1:NPts],Y[Valid][1:NPts], pch=19, cex=0.25, col="blue",
xlab="x",ylab="y",main="Fuzzy circle", xlim=c(-RMax,RMax), ylim=c(-RMax,RMax) )
 

Example of solution

FuzzyCircle.jpg


[edit] REXX

[edit] version 1

No aspect adjustment is done in version of the REXX program.

 
/*REXX program gens 100 random points in an annulus: 10 ≤ √(x²≤y²) ≤ 15 */
 
arg points low high .; $= /*allow specifications from C.L. */
if points=='' then points=100
if low=='' then low=10; low2= low**2
if high=='' then high=15; high2=high**2
 
do x=-high; x2=x*x /*gen all possible annulus points*/
if x<0 & x2>high2 then iterate
if x>0 & x2>high2 then leave
do y=-high; y2=y*y; s=x2+y2
if (y<0 & s>high2) | s<low2 then iterate
if y>0 & s>high2 then leave
$=$ x','y
end /*y*/
end /*x*/
 
field.=; plotChar='O'; minY=high2; maxY=-minY; ap=words($)
 
do j=1 for points /*"draw" the x,y points [char O].*/
parse value word($,random(1,ap)) with x ',' y /*pick random point.*/
field.y=overlay(plotChar,field.y,x+high+1) /*"draw: the point. */
minY=min(minY,y); maxY=max(maxY,y) /*plot restricting. */
end /*j*/
 
do y=minY to maxY; if field.y=='' then iterate; say field.y; end /*plot*/
 

Output when using default input:

          O O     OO
           O          O
       O O    O O       O
      O  O
     OOO O   O O     O
   O O  OO           OO
     O                    O
       O               O   OO
      OO                O  O
                         O  O
                            O
  O  O                    O
                          O
  OO
    O
  O
    O
     O                     O
  O                          O
  O O O                   O
    O                   OO  O
  OOOO                   O
      O                O
   O      O
     O  O O  O
      O OOO            O
      O   O    O   O O
        O O O  O     OO
           OO

[edit] version 2

Aspect adjustment is done is this version of the REXX program.

 
/*REXX program gens 100 random points in an annulus: 10 ≤ √(x²≤y²) ≤ 15 */
 
arg points low high .; $= /*allow specifications from C.L. */
if points=='' then points=100
if low=='' then low=10; low2= low**2
if high=='' then high=15; high2=high**2
 
do x=-high; x2=x*x /*gen all possible annulus points*/
if x<0 & x2>high2 then iterate
if x>0 & x2>high2 then leave
do y=-high; y2=y*y; s=x2+y2
if (y<0 & s>high2) | s<low2 then iterate
if y>0 & s>high2 then leave
$=$ x','y
end /*y*/
end /*x*/
 
field.=; plotChar='O'; minY=high2; maxY=-minY; ap=words($)
 
do j=1 for points /*"draw" the x,y points [char O].*/
parse value word($,random(1,ap)) with x ',' y /*pick random point.*/
field.y=overlay(plotChar,field.y,2*x+2*high+1) /*"draw: the point. */
minY=min(minY,y); maxY=max(maxY,y) /*plot restricting. */
end /*j*/
 
do y=minY to maxY; if field.y=='' then iterate; say field.y; end /*plot*/
 

Output (with aspect adjustment) when using default input:

                              O
                      O       O
                          O O   O   O O O
                O                     O O O
            O         O   O   O   O
                      O           O               O
                O                           O       O
              O                                     O O
          O                                   O   O   O
    O     O                                         O   O
        O                                       O
                                                      O
  O                                               O
  O     O O                                           O
      O   O                                               O
      O                                               O
      O   O
        O O
                                                O     O   O
                                              O
    O   O     O                               O O
        O                                   O         O
          O   O                                     O
        O O     O             O           O   O
                      O           O         O
              O O O                       O
                                    O
                      O       O     O O

[edit] Ruby

Create the image with Raster graphics operations/Ruby

points = (1...100).map {
# choose a random radius and angle
angle = rand * 2.0 * Math::PI
rad = rand * 5.0 + 10.0
# convert back from polar to cartesian coordinates
[rad * Math::cos(angle), rad * Math::sin(angle)].map(&:round)
}
 
(-15..15).each do |row|
puts((-15..15).map { |col| points.include?([row, col]) ? "X" : " " }.join)
end
 
load 'raster_graphics.rb'
 
pixmap = Pixmap.new(321,321)
pixmap.draw_circle(Pixel.new(160,160),90,RGBColour::BLACK)
pixmap.draw_circle(Pixel.new(160,160),160,RGBColour::BLACK)
points.each {|(x,y)| pixmap[10*(x+16),10*(y+16)] = RGBColour::BLACK}
pngfile = __FILE__
pngfile[/\.rb/] = ".png"
pixmap.save_as_png(pngfile)

outputs:

Sample output from Ruby program
          X X
         X      XX
           X XXX
         XX X  X  X X  X
               XXXXX
      XX            XX
   X  X                    X
    X                   X
   X                   X
     X                   X XXX
     X
 XX X                     X
  X                           X
 X                        X
   XXX                      X
XX  X
  XXX                     X  X

  XX X                   X X
   XX                  X   X
   X                      X
                            X
  XX  X                   X
   X               X      X
      X        X   X
              X
             X       X X
          X    X     X
            X      X

[edit] Run BASIC

w = 320
h = 320
dim canvas(w,h)
for pts = 1 to 1000
x = (rnd(1) * 31) - 15
y = (rnd(1) * 31) - 15
r = x * x + y * y
if (r > 100) and (r < 225) then
x = int(x * 10 + w/2)
y = int(y * 10 + h/2)
canvas(x,y) = 1
end if
next pts
 
' -----------------------------
' display the graphic
' -----------------------------
graphic #g, w,h
for x = 1 to w
for y = 1 to h
if canvas(x,y) = 1 then #g "color green ; set "; x; " "; y else #g "color blue ; set "; x; " "; y
next y
next x
render #g
#g "flush"

[edit] 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

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                  
                                        

[edit] 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 ""
}

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               
Personal tools
Namespaces
Variants
Actions
Community/News
Browse wiki
Misc
Toolbox