Polina Trotsenko
Polina Trotsenko

Reputation: 107

Print out an ASCII circle and axes with characters

I have to print a circle (taking as input it's radius, the coordinates of the center of the circle (cx and cy), and the character with which it has to be drawn).

I wrote a series of if-blocks for the axes and the circle. They work well if I use them separately, but when I put them in the same method (I have to have only one method) they overlap in an undesirable way.

Note: in case if the character overlaps the axes, the character has priority.

public static void drawCircle(int radius, int cx, int cy, char symbol) {
    // this method verifies that there are no negative
    // values involved (throws error/exception)
    verifyInput(radius, cx, cy);

    // set the values for extension of the axes
    // (aka how long are they)
    int xMax = cx + radius + 1;
    int yMax = cy + radius + 1;

    for (int j = yMax; j >= 0; j--) {
        for (int i = 0; i <= xMax; i++) {
            // set of if-block to print the axes
            if (i == 0 && j == 0) {
                System.out.print('+');
            } else if (i == 0) {
                if (j == yMax) {
                    System.out.print('^');
                }
                if (j != yMax) {
                    System.out.println('|');
                }
            } else if (j == 0) {
                if (i == xMax) {
                    System.out.println('>');
                }
                if (i != xMax) {
                    System.out.print('-');
                }
            }

            // if block to print the circle
            if (onCircle(radius, cx, cy, i, j) == true) {
                System.out.print('*');
            } else {
                System.out.print(' ');
            }
        }
        // I'm not sure if I need to use the print here V
        // System.out.println()
    }
}

Here is the onCircle method. It verifies for every i,j if it is on the outline of the circle to be drawn.

public static boolean onCircle(int radius, int cx, int cy, int x, int y) {
    boolean isDrawn = false;
    if (Math.pow(radius,2)<=(Math.pow((x-cx),2)+Math.pow((y-cy),2))
            && (Math.pow((x-cx),2)+Math.pow((y-cy),2))<=(Math.pow(radius,2)+1)) {
        isDrawn = true;
    }
    return isDrawn;
}

Here is my output (without the last print statement):

^          |
 ***  |
*   * |
*   * |
*   * + - - - - -*-*-*- >

Here is my output (with the last print statement):

^

|
   ***
|
  *   *
|
  *   *
|
  *   *

+ - - - - -*-*-*- >

Here is what I should get:

enter image description here

Upvotes: 3

Views: 1804

Answers (3)

St&#233;phane Millien
St&#233;phane Millien

Reputation: 3448

jwaddell is right, your code needs only 5 minor updates like this (see comment like // <--):

public static void drawCircle(int radius, int cx, int cy, char symbol) {
  // this method verifies that there are no negative
  // values involved (throws error/exception)
  verifyInput(radius, cx, cy);

  // set the values for extension of the axes
  // (aka how long are they)
  int xMax = cx + radius + 1;
  int yMax = cy + radius + 1;

  for (int j = yMax; j >= 0; j--) {
    for (int i = 0; i <= xMax; i++) {
      // set of if-block to print the axes
      if (onCircle(radius, cx, cy, i, j) == true) { // <-- draw circle first
        System.out.print(symbol);  // <-- use param 'symbol' here
      } else if (i == 0 && j == 0) {
        System.out.print('+');
      } else if (i == 0) {
        if (j == yMax) {
          System.out.print('^');
        }
        if (j != yMax) {
          System.out.print('|'); // <-- don't print new line here
        }
      } else if (j == 0) {
        if (i == xMax) {
          System.out.print('>'); // <-- don't print new line here
        }
        if (i != xMax) {
          System.out.print('-');
        }
      } else {
        System.out.print(' ');
      }
    }
    System.out.println(); // <-- then add new line here
  }
}

You can optimize onCircle like this:

public static boolean onCircle(int radius, int cx, int cy, int x, int y) {
  double distance2 = Math.pow((x - cx), 2) + Math.pow((y - cy), 2);
  double radius2 = Math.pow(radius, 2);

  return radius2 <= distance2 && distance2 <= (radius2 + 1.0d);
}

The result with drawCircle(5, 10, 12, '&'); is as expected:

^                
|        &&&     
|      &     &   
|     &       &  
|                
|    &         & 
|    &         & 
|    &         & 
|                
|     &       &  
|      &     &   
|        &&&     
|                
|                
|                
|                
|                
|                
+--------------->

Upvotes: 1

user15495739
user15495739

Reputation:

The general Equation of a circle:

Equation of a circle

In Java it can be implemented like this:

(x-a)*(x-a) + (y-b)*(y-b) == r*r

In the case of an integer coordinate system, it can be rounded like this:

(int) Math.sqrt((x-a)*(x-a) + (y-b)*(y-b)) == r

If the radius r=12 and the center of the circle a=5,b=1, then the circle and axes look like this:

r=12,a=5,b=1
                    ^y                                        
                    |                                         
                    |                                         
                    | * * * * * * * * *                       
                  * *                   * *                   
              * *   |                       * *               
            * *     |                         * *             
          * *       |                           * *           
          *         |                             *           
        *           |                               *         
        *           |                               *         
      *             |                                 *       
      *             |                                 *       
      *             |                                 *       
      *             |                                 *       
      *             |         *                       *       
------* ------------+---------------------------------* ---->x
      *             |                                 *       
      *             |                                 *       
      *             |                                 *       
        *           |                               *         
        *           |                               *         
          *         |                             *           
          * *       |                           * *           
            * *     |                         * *             
              * *   |                       * *               
                  * *                   * *                   
                    | * * * * * * * * *                       
                    |                                         
                    |                                         
                    |                                         

Try it online!

// radius
int r = 12;
// center of the circle
int a = 5, b = 1;
// whitespace
int s = 3;
// print area
int xMin = a-r-s, xMax = a+r+s;
int yMin = b-r-s, yMax = b+r+s;
// output an ASCII circle and axes
System.out.println("r="+r+",a="+a+",b="+b);
for (int y = yMax; y >= yMin; y--) {
    for (int x = xMin; x <= xMax; x++) {
        if ((int) Math.sqrt((x-a)*(x-a) + (y-b)*(y-b)) == r) {
            // circle
            System.out.print("* ");
        } else if (x == a && y == b) {
            // center of the circle
            System.out.print("* ");
        } else if (x == 0 && y == 0) {
            // origin of coordinates
            System.out.print("+-");
        } else if (x == 0) {
            // ordinate axis - y
            System.out.print(y == yMax ? "^y" : "| ");
        } else if (y == 0) {
            // abscissa axis - x
            System.out.print(x == xMax ? ">x" : "--");
        } else {
            // whitespace
            System.out.print("  ");
        }
    }
    // new line
    System.out.println();
}

See also:
Print out an ASCII circle and axes
Print out an ASCII circle of the specified width

Upvotes: 3

jwaddell
jwaddell

Reputation: 1934

It looks like the formatting issue is that you are sometimes using System.out.println where you should be using System.out.print. System.out.println will end the current line, so it should only be used once per output line. Thus you should just have the single empty System.out.printlnstatement at the end of the outer (j) loop, and use System.out.print throughout the rest of the program.

You will also need to fix the printing of the horizontal axis, as at the moment it will print both the axis and the circle, instead of just the circle.

Upvotes: 2

Related Questions