The public class is already given (this is a HW) and all I need is to write the method that draws the unfilled circle.

The given public static is the following

char[][] kreis(char[][] zf, int xM, int yM, int r, char z)

and the middle point is (xM; yM) and of course the radius is (r) . And the equation given is this.

(x-xM)^2+(y-yM)^2 = r^2

However, here is why I can't figure out how to do it: I need to write r^2 in java as r*r but also I'm instructed to use the "squareroot" through "Math.sqrt" and I'm confused as to what's the purpose of the square root?

2 Answers

0
UncreativeName On Best Solutions

Hey its you the char [][] zf guy :) You probably want something like this:

char[][] kreis(char[][] zf, int xM, int yM, int r, char z){
    try {
        for (int x = xM - r; x <= xM + r; x++) {
            int y = (int) Math.sqrt(Math.pow(r, 2) - Math.pow(x - xM, 2)) + yM;
            zf[x][y] = z;
            zf[x][2 * yM - y] = z;
        }
    } catch(IndexOutOfBoundsException e) {
        System.out.println("Error, circle out of bounds.");
    }
    return zf;
}

please test it if you can and tell me if it works, since I can't test it. Hope it works though.

0
tevemadar On

While you are right about that drawing a disc, or filled circle, would not need square root...

public static char[][] kreis(char[][] zf, int xM, int yM, int r, char z){
  for(int x=xM-r;x<=xM+r;x++)
    for(int y=yM-r;y<=yM+r;y++)
      if(x>0 && y>0 && y<zf.length && x<zf[0].length &&
        r*r>=(x-xM)*(x-xM)+(y-yM)*(y-yM))
        zf[y][x]=z;
  return zf;
}

...drawing the outline of the circle needs solving the equation for either x or y, as you want to fill only one "dot" for a coordinate:

public static char[][] kreis(char[][] zf, int xM, int yM, int r, char z){
  for(int i=-r;i<=r;i++){
    int j=(int)Math.round(Math.sqrt(r*r-i*i));
    int x=xM+i;
    int y=yM-j;
    if(x>0 && y>0 && y<zf.length && x<zf[0].length)
      zf[y][x]=z;
  }
  return zf;
}

This is just a half of the circle, but in addition to the need for doing the same with y=yM+j, it also shows that the outline is not continuous, so the approach also needs a swap between i and j:

public static char[][] kreis(char[][] zf, int xM, int yM, int r, char z){
  for(int i=-r;i<=r;i++){
    int j=(int)Math.round(Math.sqrt(r*r-i*i));
    int x=xM+i;
    int y=yM+j;
    if(x>0 && y>0 && y<zf.length && x<zf[0].length)
      zf[y][x]=z;
    y=yM-j;
    if(x>0 && y>0 && y<zf.length && x<zf[0].length)
      zf[y][x]=z;
    x=xM+j;
    y=yM+i;
    if(x>0 && y>0 && y<zf.length && x<zf[0].length)
      zf[y][x]=z;
    x=xM-j;
    if(x>0 && y>0 && y<zf.length && x<zf[0].length)
      zf[y][x]=z;
  }
  return zf;
}

Example here: https://ideone.com/h7UBog
In fact it would be enough to run the loop between -45...+45 degrees (so r*Math.cos(45*Math.PI/180)), because that is the always "continuous" portion of the arc, but the longer loop does not cause any harm either.
Side remark: the Math.round part smoothens the outline a little. If you want to have the exact same result what the disc-code produces, remove it.