Creating a circle

I want to create a circle using nested for-loops just like someone would create a diamond. So far, I was able to get the following using lots of for-loops:
         ***
     *         *
   *             *
  *               *
 *                 *
 *                 *
 *                 *
 *                 *
  *               *
   *             *
     *         *
         ***
Press any key to continue . . .


My code is long but simple. I couldn't figure out the algorithm for nested loops to create each line or better yet, each half of the circle if its even possible. I would like some help/hint on how I can reduced my code. Here's part of my code, this is for the first line of the circle. The others are similar.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int main ()
{
	int i,j,k;

	for(i=0;i<9;i++)
	{
		cout<<" ";
	}
	for(j=0;j<3;j++)
	{
		cout<<"*";
	}
	for(k=0;k<9;k++)
	{ 
		cout<<" ";
	}
	
	cout<<endl;
.
.
.
.


Last edited on
I don't want you guys to give me the answer but a hint. Also, is it even possible to create half the circle I made with a nested for-loops? Thank you!
let's see... of the top of my head.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int circle_radius = 10; // or whatever you want

for (int i = 0; i <= 2*circle_radius; i++)
{
    for (int j = 0; j <= 2*circle_radius; j++)
    {
         float distance_to_centre = sqrt((i - circle_radius)*(i - circle_radius) + (j - circle_radius)*(j - circle_radius));
        if (distance_to_centre > circle_radius-0.5 && distance_to_centre < circle_radius+0.5)
        {
             cout << "*";
        }
        else
        {
             cout << " ";
        }
    }
    cout << endl;
}


not run it but give that a go.

Edit: Tested it, seems to work.
Last edited on
Here's a better idea based on the fact that the console windows entries aren't square (i.e. one character occupies a non-square space)

My one (and I suspect most peoples), is set to a height/width ratio of 4/3 so if you want a circle you might want to draw an ellipse instead with semi-major axis = 4/3*semi-minor axis = 4/3*circle_radius

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int circle_radius = 10; // or whatever you want
    float console_ratio = 4.0/3.0;
    float a = console_ratio*circle_radius;
    float b = circle_radius;

    for (int y = -circle_radius; y <= circle_radius; y++)
    {
        for (int x = -console_ratio*circle_radius; x <= console_ratio*circle_radius; x++)
        {
            float d = (x/a)*(x/a) + (y/b)*(y/b);
            if (d > 0.90 && d < 1.1)
            {
                cout << "*";
            }
            else
            {
                 cout << " ";
            }
        }
        cout << endl;
    }
Last edited on
Amazing, thank you for your reply. As of right now, I'm going over your solutions and trying to understand them first before I use them. First of all, in your first solution, I understand everything up until here:

1
2
3
4
5
6
int circle_radius = 10; // or whatever you want

for (int i = 0; i <= 2*circle_radius; i++)
{
    for (int j = 0; j <= 2*circle_radius; j++)
    {

When I was trying to create a nested for-loop for the circle, it would never occur to me to multiply the circle_radius by 2. More importantly, it wouldn't occur to me to use the circle_radius in the condition in the first place. I thought I had to do something similar to this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int i,j,k;
 
	for( i = 10; i >= 1; i-- )
	{
		for( j = 1; j < i; j++ )
		{
			cout << " ";
		}
 
		for( k=10; k >= j*2; k-- )
		{
			cout << "*";
		}
 
		cout << "\n";
	}

This creates the upper part of a diamond I think. I thought I had to put conditions like

i >= 1, j < i, and k >= j*2

I barely understand why those conditions were used for the upper part of the diamond so you can imagine how I feel about the circle_radius. If you could explain a bit on why you use the circle_radius in the conditions I would really appreciate it (I'm debugging it using the Step Over function in VB so I can understand it). Now for the rest of that code, the if else statement surprised me. How did you get it?

1
2
3
4
5
6
7
8
        if (distance_to_centre > circle_radius-0.5 && distance_to_centre < circle_radius+0.5)
        {
             cout << "*";
        }
        else
        {
             cout << " ";
        }

Sorry if I'm asking a lot of questions, I just really want to understand how to get a circle out of for-loops. Thank you again!
Sure.

Any point on a circle is circle_radius away from the centre of the circle.

I just made a loop than created a box around the circle and set the centre of the circle to be the 'mid point' of the loop. E.g

- - - - -
- - - - -
- - c - -
- - - - -
- - - - -

where c is the centre and here radius would be 2. The loop goes row by row and check every entry.

I simply let the centre of the circle be at (circle_radius, circle_radius) and the loop values represent the x and y values to check. (in the above example, centre of circle is at (2,2) as you can see)

Calculate the distance to the centre of the circle using pythagoras formula.

Since we are using integers for the loop it won't be perfectly equal to the radius (which is what we want) so I set a tolerance of 0.5 either side.



EDIT:::::

You don't actually need to do that. Since we are working with ints we can make it so that our distance to centre DOES equal exactly the radius.

Replace the float and if part with

1
2
3
4
5
6
7
8
9
int distance_to_centre = sqrt((i - circle_radius)*(i - circle_radius) + (j - circle_radius)*(j - circle_radius));
            if (distance_to_centre == circle_radius)
            {
                cout << "*";
            }
            else
            {
                 cout << " ";
            }


which does the same job.
Last edited on
As for the second solution, I understand the purpose of the code but things like:

1
2
3
4
5
6
    float console_ratio = 4.0/3.0;
    float a = console_ratio*circle_radius;

    for (int y = -circle_radius; y <= circle_radius; y++)
    {
        for (int x = -console_ratio*circle_radius; x <= console_ratio*circle_radius; x++)

have me confuse. What's the purpose of the console_ratio? And, if you can, could you explain to me lines 6,8,10 in your second solution?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int circle_radius = 10; // or whatever you want
    float console_ratio = 4.0/3.0;
    float a = console_ratio*circle_radius;
    float b = circle_radius;

    for (int y = -circle_radius; y <= circle_radius; y++)
    {
        for (int x = -console_ratio*circle_radius; x <= console_ratio*circle_radius; x++)
        {
            float d = (x/a)*(x/a) + (y/b)*(y/b);
            if (d > 0.90 && d < 1.1)
            {
                cout << "*";
            }
            else
            {
                 cout << " ";
            }
        }
        cout << endl;
    }

Also, why does the if-else statement has

d > 0.90 && d < 1.1

condition? Sorry once again if I'm asking too many questions. Like I said I really want to understand this. Thank you!
Print this in the console.

1
2
3
4
5
6
7
8
for (int y = 0 y < 10; y++)
    {
        for (int x = 0; x < 10; x++)
        {
            cout << 'X';
        }
        cout << endl;
    }


It's a 10x10 loop but it prints a rectangle rather than a square (at least in my one) since my console is set to print characters that are 12 high and 8 wide (4/3 ratio).

Therefore if we print an ellipse with the same ratio the console character ratio should cancel with the ellipses ratio and it will look like a circle. Hard to explain but you're basically squeezing an ellipse to make it look like a circle.

As for the loops, I just changed my coordinate system to be centred at (0,0), line 10 is the equation of an ellipse and the d > 0.9... is the approximation to the equation for an ellipse shown here...

http://www.mathopenref.com/coordgeneralellipse.html
Last edited on
Thank you for your time on explaining this in more detail. I now have a better understanding of how it works. Thanks a lot, and sorry for taking so long to reply been busy with school.
Topic archived. No new replies allowed.