用java打印一个圆
今天在家呆着学习Spring,随意搜一些关于java的QQ群,加了一个,一个人问了一个题,说是用程序打印出一个圆形,打印一个图形,从刚开始学C语言时,讲到循环那里是必做的题目了,主要有打印一个正三角,打印一个倒三角,还见过一个倒三角下面是一个正三角的图形,这些用for循环都能很好的实现,比如下面两个图形
*
* *
* * *
* * *
* *
*
现在说回这个题目,是打印一个圆形,特殊性在于圆,按照一般规律想,从第一行开始,有圆周围的点的地反,就打印一个* ,可是关键在于圆的特殊性,把打印这种题目再抽象一下,无非就是打印一个空格,或者打印一个* ,从第一行扫描到最后一行就成了一个由空格或者*构成的矩形或者正方形,然后在这个矩形里找到相应图形的点,三角形的话,肯定是可以找到这样的点的,想象一下,圆形的话,是没法找到这样的点,当这个有空格和*构成的正方形无限大时,圆边的点才能无限接近于正方形当中的每个点。
或者换一种描述方式,当把圆的横向平均分成n份的话,纵向的n份肯定不是平均的,纵向的坐标肯定是一个小数,当这个正方形无限大时,那么可以找到越接近这个小数的一个自然数,这样就可以找到坐标了
程序如下:
/**
* @param args
*/
public static void main(String[] args) {
int n=1000;//n越大,才能越接近圆
PrintCircle p = new PrintCircle();
for(int i=0;i<2*n;i++){
p.printPoint(n,i);
}
}
private int[] getXFromY(int y,int n)//n为半径,y<2n,返回2个x
{
if(y<=n){//上半侧
int x1=n-(int)Math.sqrt(n*n-(n–y)*(n–y));
int x2=(int)Math.sqrt(n*n-(n–y)*(n–y))+n;
return new int[]{x1,x2};
}
else if(y<=2*n){//下半侧
int x1=n-(int)Math.sqrt(n*n-(n–y)*(n–y));
int x2=(int)Math.sqrt(n*n-(n–y)*(n–y))+n;
return new int[]{x1,x2};
}
return null;
}
private void printPoint(int n,int y){//半径n,在(x,y)的位置打印一个*
int x1=getXFromY(y,n)[0];
int x2=getXFromY(y,n)[1];
for(int i=0;i<=2*n;i++){
if(i==2*n) System.out.println("\n");
if(i==x1||i==x2) System.out.print("*");
else System.out.print(" ");
}
}
}
我试了一下,n=1000,这个才大概像个圆,n小的话,一般看着大概像个椭圆
如果谁有更好的算法的话,欢迎告诉我:)
cloud
2009年3月2日 23:28
我要拿回去好好学习下
cloud
2009年3月4日 10:31
好的好的
要是能在那种单位面积里有很多个象素点里面测试会更好。。。
呵呵
Jack
2014年2月21日 20:24
for (int y = 0; y <= 2*r; y+=2) {
int x = (int)(r-Math.round(Math.sqrt((2*r*y-y*y))));
for (int j = 0; j < x; j++) {
System.out.print(" ");
}
System.out.print("*");
for (int k = 0; k < (r-x)*2; k++) {
System.out.print(" ");
}
System.out.println("*");
}
Jack
2014年2月21日 20:24
for (int y = 0; y <= 2*r; y+=2) {
int x = (int)(r-Math.round(Math.sqrt((2*r*y-y*y))));
for (int j = 0; j < x; j++) {
System.out.print(" ");
}
System.out.print("*");
for (int k = 0; k < (r-x)*2; k++) {
System.out.print(" ");
}
System.out.println("*");
}