Circle coodinates using GUI

What would be the necessary steps if I wanted to make a random number of circles within a circle?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include "Simple_window.h"    // get access to our window library
#include "Graph.h"            // get access to our graphics library facilities
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cmath>

//------------------------------------------------------------------------------
using namespace std;
using namespace Graph_lib;   // our graphics facilities are in Graph_lib

int PI = 3.14159265359;

int x_cor(int x){
	int xc, t;
	t = 360 - rand()%360;
	xc = rand()%250+1;
	x = xc + cos(t);
	return x;
}

int y_cor(int y){
	int yc, t;
	t = 360 - rand()%360;
	yc = rand()%250+1;
	y = yc + sin(t);
	return y;
}

int radius(int radius, int n){
	int r;
	r = 250*sin(PI/n)/(1 + sin(PI/n));
	return r;
}

int main(){
	srand(time(0));
    Point tl(0,0);           // to become top left  corner of window

    Simple_window win(tl,500,500,"Canvas");    // make a simple window

    Circle c0(Point(250, 250), 200);

    c0.set_color(rand()%243+23);  // adjust properties of poly
    win.attach(c0);

    while(true){
       int n;
       cout << "Enter Number of Circles: ";
       cin >> n;
       if (n <= 0) break;
       for (int i = 0; i < n; i++){
    	   Circle c(Point(x_cor(0),y_cor(0)), radius(250, n));
    	   win.attach(c);
       }
       win.wait_for_button();       // give control to the display engine
       }
    return 0;
}

//------------------------------------------------------------------------------
Last edited on
First you must assure that the radius of the new random circle is smaller then the outer circle:
int radius_inner = rand() % radius_outer;

Then, if you have the radius of the new circle, you could make a random angle which holds the the angle of the new circle center relative to the X-Axis.
double angle = rand() % (2 * PI); // angle in radians relative to outer circle's center

Then, you can calculate the maximum feasible distance of the inner circle's center from the center of the outer circle:
1
2
int max_x_distance = cos(angle) * (radius_outer - radius_inner);
int max_y_distance = sin(angle) * (radius_outer - raidus_inner);


At last you specify the inner circle's center coordinates:
1
2
int x_center_inner = rand() % max_x_distance + x_center_outer;
int y_center_inner = rand() % max_y_distance + y_center_outer;


*edited
Last edited on
Thank You for your input sir, so modified my code as you said, this is my current code, however, while it compiles, it crashes when during run time.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include "Simple_window.h"    // get access to our window library
#include "Graph.h"            // get access to our graphics library facilities
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cmath>

//------------------------------------------------------------------------------
using namespace std;
using namespace Graph_lib;   // our graphics facilities are in Graph_lib

int PI = 3.14159265359;

//int x_cor(){
//	int x;
//	int xc, t;
//	t = 360 - rand()%360;
//	xc = rand()%250;
//	x = xc + cos(t);
//	return x;
//}
//
//int y_cor(){
//	int y;
//	int yc, t;
//	t = 360 - rand()%360;
//	yc = rand()%250;
//	y = yc + sin(t);
//	return y;
//}

//int radius(int radius, int n){
//	int r;
//	r = 250*sin(PI/n)/(1 + sin(PI/n));
//	return r;
//}

int main(){
	srand(time(0));

	Point tl(0,0);           // to become top left  corner of window

	Simple_window win(tl,500,500,"Canvas");    // make a simple window

	Circle c0(Point(250, 250), 200);

	c0.set_color(rand()%243+23);  // adjust properties of poly
	win.attach(c0);

    while(true){
       int n;
       cout << "Enter Number of Cycles: ";
       cin >> n;
       if (n <= 0) break;
       for (int i = 0; i < n; i++){
    	   int genrand = rand();
    	   int radius_inner = rand() % 200;
    	   double angle = rand() % (2 * PI); // angle in radians relative to outer circle's center
    	   int max_x_distance = cos(angle) * (200 - radius_inner);
    	   int max_y_distance = sin(angle) * (200 - radius_inner);
    	   int xci = rand() % max_x_distance + 200;
    	   int yci = rand() % max_y_distance + 200;
    	   int r;
    	   r = 250*sin(PI/n)/(1 + sin(PI/n));
    	   for (int j = 0; j < genrand; j++){ //to make a random number of circles n times
    		   Circle c(Point(xci, yci), r);
    		   c.set_color(rand()%243+23);
    		   win.attach(c);
    	   }
       }
       win.wait_for_button();       // give control to the display engine
       }
    return 0;
}

//------------------------------------------------------------------------------ 


What would you suggest?
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const int max_radius{ 200 };
Circle outer( { win_width / 2, win_height / 2 }, max_radius );
outer.set_color( Color::blue );
outer.set_style( Line_style{ Line_style::solid, 3 } );
win.attach( outer );

const int rand_radius{ randint( 1, max_radius ) },
    x_bounds[]{ { outer.center( ).x - outer.radius( ) + rand_radius },
                { outer.center( ).x + outer.radius( ) - rand_radius } },
    y_bounds[]{ { outer.center( ).y - outer.radius( ) + rand_radius },
                { outer.center( ).y + outer.radius( ) - rand_radius } };
Circle boundary{ outer.center( ), max_radius - rand_radius };
boundary.set_color( Color::dark_red );
boundary.set_style( { Line_style::dot, 2 } );
win.attach( boundary );

boundary constitutes the maximum/minimum coordinates that a circle of radius rand_radius can lie on. A picture for reference: https://puu.sh/sKs4O/98d59a927f.png

Using the above, we can randomly generate N circles with a random radius inside the outer circle.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Vector_ref<Circle> rand_circles{};
const int num_circles{ 20 };
for( int i{}; i < num_circles; i++ ) {
    const int rand_radius{ randint( 1, max_radius ) },
        x_bounds[]{ { outer.center( ).x - outer.radius( ) + rand_radius },
                    { outer.center( ).x + outer.radius( ) - rand_radius } },
        y_bounds[]{ { outer.center( ).y - outer.radius( ) + rand_radius },
                    { outer.center( ).y + outer.radius( ) - rand_radius } };
    const Point rand_pt{ randint( x_bounds[0], x_bounds[1] ),
                        randint( y_bounds[0], y_bounds[1] ) };

    Circle* rand_circle{ new Circle{ rand_pt, rand_radius } };
    rand_circle->set_color( Color{ randint( 255 ) } );
    rand_circles.push_back( rand_circle );
}

for( int i{}; i < rand_circles.size( ); i++ )
    win.attach( rand_circles[i] );

Picture: https://puu.sh/sKs77/f7f550b3b4.png

I'm not sure why some of them go outside the outer circle, though.

edit: The code above is for the bounding box of the circle. This explains why there are some circles outside the outer circle, as it is within the bounding box. https://puu.sh/sKu8d/1f0b1fa855.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Vector_ref<Circle> rand_circles{};
const int num_circles{ 20 };
for( int i{}; i < num_circles; i++ ) {
    const int rand_radius{ randint( 1, max_radius ) },
        rand_angle = randint( 1, 360 ) / 180.0 * M_PI,
        x0 = (max_radius - rand_radius) * cos( rand_angle ) + outer.center( ).x,
        y0 = (max_radius - rand_radius) * sin( rand_angle ) + outer.center( ).y;

    Circle* rand_circle{ new Circle{ { x0, y0 }, rand_radius } };
    rand_circle->set_color( Color{ randint( 255 ) } );
    rand_circles.push_back( rand_circle );
}
for( int i{}; i < rand_circles.size( ); i++ )
    win.attach( rand_circles[i] );

This will generate circles with a random radius, that touch the outer circle's circumference.
https://puu.sh/sKubF/03ebaffd2d.png
Last edited on
Is there any way we can ensure that the circles with the big circle are all touching the big circle like the one in this photo:
https://postimg.org/image/tpn8n9l6h/
the purpose of the program is that for each number the user enters, the program creates a random number circles of the same size the are all tangent to the outer circle, the program repeats this process for each cycle.
Example in Link Above:
User entered 1 and the program cycles once randomly creating a random number of circles of constant random measurements. In this case the program created 8 circles.
Then the User entered 120 and the program cycled a 120 times creating a random number of circles of random but constant measurement in each cycle. The measurements change each cycle and number of circles change each cycle.
To make your inner circles connecting to the outer circle's border, try this:

its all the same at my last code post, but:
change this...
1
2
int x_center_inner = rand() % max_x_distance + x_center_outer;
int y_center_inner = rand() % max_y_distance + y_center_outer;

..by that:
1
2
int x_center_inner = max_x_distance + x_center_outer;
int y_center_inner = max_y_distance + y_center_outer;



Or change - if integrafix' code works - at his/her last post example line 6 and 7 by: Should work like it is.

The only difference is, that the circles will now positioned at the maximum feasible site.

*edited
Last edited on
I did attempt Mr. integrafix's code but for some reason it crashes. I made a few minor changes. Can you tell me where I went wrong?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include "Simple_window.h"    // get access to our window library
#include "Graph.h"            // get access to our graphics library facilities
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cmath>

//------------------------------------------------------------------------------
using namespace std;
using namespace Graph_lib;   // our graphics facilities are in Graph_lib

int PI = 3.14159265359;

//int x_cor(){
//	int x;
//	int xc, t;
//	t = 360 - rand()%360;
//	xc = rand()%250;
//	x = xc + cos(t);
//	return x;
//}
//
//int y_cor(){
//	int y;
//	int yc, t;
//	t = 360 - rand()%360;
//	yc = rand()%250;
//	y = yc + sin(t);
//	return y;
//}

//int radius(int radius, int n){
//	int r;
//	r = 250*sin(PI/n)/(1 + sin(PI/n));
//	return r;
//}

int main(){
	srand(time(0));

	Point tl(0,0);           // to become top left  corner of window

	Simple_window win(tl,500,500,"Canvas");    // make a simple window

	const int max_radius{ 200 };
	Circle outer( {500 / 2, 500 / 2 }, max_radius );
	outer.set_color(rand() % 243 + 23);
	outer.set_style( Line_style{ Line_style::solid, 3 } );
	win.attach( outer );

	while(true){
       int n;
       cout << "Enter Number of Cycles: ";
       cin >> n;
       if (n <= 0) break;
       for (int i = 0; i < n; i++){
    	   int genrand = rand ();
    	   const int rand_radius{ genrand * ( 1, max_radius ) };
//    	       x_bounds[]{ { outer.center( ).x - outer.radius( ) + rand_radius },
//    	                   { outer.center( ).x + outer.radius( ) - rand_radius } },
//    	       y_bounds[]{ { outer.center( ).y - outer.radius( ) + rand_radius },
//    	                   { outer.center( ).y + outer.radius( ) - rand_radius } };
    	   Circle boundary (Point(250, 250) , max_radius - rand_radius );
    	   boundary.set_color(rand() % 243 + 23);
    	   boundary.set_style( { Line_style::solid, 2 } );
    	   win.attach( boundary );
    	   Vector_ref<Circle> rand_circles;
    	   const int num_circles{ 20 };
    	   for( int i{}; i < num_circles; i++ ) {
    	       const int rand_radius{ genrand*( 1, max_radius ) },
    	           rand_angle = genrand*( 1, 360 ) / 180.0 * M_PI,
    	           x0 = (max_radius - rand_radius) * cos( rand_angle ) + outer.center( ).x,
    	           y0 = (max_radius - rand_radius) * sin( rand_angle ) + outer.center( ).y;

    	       Circle* rand_circle{ new Circle{ { x0, y0 }, rand_radius } };
    	       rand_circle->set_color(rand() % 243 + 23);
    	       rand_circles.push_back( rand_circle );
    	   }
    	   for( int i{}; i < rand_circles.size( ); i++ )
    	       win.attach( rand_circles[i] );
       }
       win.wait_for_button();       // give control to the display engine
       }
    return 0;
}

//------------------------------------------------------------------------------
CelestialX wrote:
Is there any way we can ensure that the circles with the big circle are all touching the big circle like the one in this photo:
https://postimg.org/image/tpn8n9l6h/


1
2
3
4
5
6
7
8
9
10
11
12
13
14
Vector_ref<Circle> rand_circles{};
const int num_circles{ 20 };
for( int i{}; i < num_circles; i++ ) {
    const int rand_radius{ randint( 1, max_radius ) },
        rand_angle = randint( 1, 360 ) / 180.0 * M_PI,
        x0 = (max_radius - rand_radius) * cos( rand_angle ) + outer.center( ).x,
        y0 = (max_radius - rand_radius) * sin( rand_angle ) + outer.center( ).y;

    Circle* rand_circle{ new Circle{ { x0, y0 }, rand_radius } };
    rand_circle->set_color( Color{ randint( 255 ) } );
    rand_circles.push_back( rand_circle );
}
for( int i{}; i < rand_circles.size( ); i++ )
    win.attach( rand_circles[i] );

This will generate circles with a random radius, that touch the outer circle's circumference.
https://puu.sh/sKubF/03ebaffd2d.png

You can adapt my code to do just that.

edit: Here you go.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Vector_ref<Circle> rand_circles{};
const int rand_radius{ /*rand_num( 1, max_radius - 1 )*/ 50 },
    bound_radius{ max_radius - rand_radius };
const double bound_circum{ 2 * M_PI * bound_radius },
    // how many circles of radius rand_radius
    // we can fit on bound_circum
    // note: sometimes the last circle may overlap the first
    // due to integer truncation
    num_circles{ bound_circum / (2 * rand_radius) };

for( int i{}; i < num_circles; i++ ) {
    // https://puu.sh/sLpQF/5d34ada8ec.jpg
    const double rand_angle{ i * 2 * atan( 1.0 * rand_radius / bound_radius ) },
        // (x0, y0) represents the centre of the circle
        x0{ bound_radius * cos( rand_angle ) + outer.center( ).x },
        y0{ bound_radius * sin( rand_angle ) + outer.center( ).y };

    Circle* rand_circle{ new Circle{ Point( x0, y0 ), rand_radius } };
    rand_circle->set_color( Color{ rand_num( 0, 255 ) } );
    rand_circles.push_back( rand_circle );
}

Picture: https://puu.sh/sLpXP/f18523f663.png
Last edited on
Topic archived. No new replies allowed.