A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 廉伟 中级黑马   /  2012-8-26 11:17  /  3223 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文


  1. public class Test {
  2.     public static void main(String[] args) {
  3.         // 画一个半径为10,旋转为0,空白为全身空格,填充为★的五角星
  4.         Pentagram pen = new Pentagram(10, 0, ' ', '★');
  5.         // 在控制台上输出这个五角星
  6.         Draw.printCanvas(pen.getPentagram());
  7.     }
  8. }
  9. class Pentagram {
  10.     private final char FILL_CHAR;   // 填充字符
  11.     private final char SPACE_CHAR;  // 空档字符
  12.     private final int R;            // 五角星的外接圆半径
  13.     private final float ROTATION;   // 五角星逆时针旋转角度
  14.     private final int X;            // 用于生成画图数组
  15.     private final int Y;            // 用于生成画图数组
  16.    
  17.     /**
  18.      * 构造一个Pentagram对象
  19.      * @param radius 五角星的半径
  20.      * @param rotation 五角星的逆时针旋转度数
  21.      * @param spaceChar 画布上空白处填充字符
  22.      * @param fillChar 画布上线条部分填充字符
  23.      */
  24.     public Pentagram(int radius, float rotation, char spaceChar, char fillChar) {
  25.         this.R = radius;
  26.         this.ROTATION = rotation;
  27.         this.FILL_CHAR = fillChar;
  28.         this.SPACE_CHAR = spaceChar;
  29.         this.X = 2 * R + 1;
  30.         this.Y = 2 * R + 1;
  31.     }
  32.    

  33.     public char[][] getPentagram() {
  34.         char[][] canvas = initCanvas();
  35.         Draw draw = new Draw(FILL_CHAR);
  36.         // 设五角星的最右边的一个点为 A,逆时针选取点 B~E
  37.         // 通过圆的极坐标公式可以得出:
  38.         // 得出以下各点的坐标
  39.         // A 点坐标(0.951R, 0.309R)
  40.         // B 点坐标(0, R)
  41.         // C 点坐标(-0.951R, 0.309R)
  42.         // D 点坐标(-0.588R, -0.809R)
  43.         // E 点坐标(0.588R, -0.809R)
  44.         
  45.         // 画线段CA
  46.         draw.drawLine(mcos(162) * R, msin(162) * R, mcos(18) * R, msin(18) * R, canvas);
  47.         // 画线段DA
  48.         draw.drawLine(mcos(234) * R, msin(234) * R, mcos(18) * R, msin(18) * R, canvas);
  49.         // 画线段CE
  50.         draw.drawLine(mcos(162) * R, msin(162) * R, mcos(306) * R, msin(306) * R, canvas);
  51.         // 画线段DB
  52.         draw.drawLine(mcos(234) * R, msin(234) * R, mcos(90) * R, msin(90) * R, canvas);
  53.         // 画线段BE
  54.         draw.drawLine(mcos(90) * R, msin(90) * R, mcos(306) * R, msin(306) * R, canvas);
  55.         return canvas;
  56.     }

  57.     // 在方形的字符数组中指定两点画线条
  58.     // 对图形数组进行初始化,填充空格
  59.     private char[][] initCanvas() {
  60.         char[][] canvas = new char[Y][X];
  61.         for (int i = 0; i < Y; i++) {
  62.             for (int j = 0; j < X; j++) {
  63.                 canvas[i][j] = SPACE_CHAR;
  64.             }
  65.         }
  66.         return canvas;
  67.     }

  68.     // 根据角度求正弦值,保留两位小数
  69.     private double msin(float a) {
  70.         return ((int) (Math.sin(Math.toRadians(a + ROTATION)) * 100)) / 100.0;
  71.     }

  72.     // 根据角度求余弦值,保留两位小数
  73.     private double mcos(float a) {
  74.         return ((int) (Math.cos(Math.toRadians(a + ROTATION)) * 100)) / 100.0;
  75.     }
  76. }
  77. class Draw {   
  78.    
  79.     private char fillChar;
  80.    
  81.     public Draw(char fillChar) {        
  82.         this.fillChar = fillChar;
  83.     }

  84.     /**
  85.      * 根据两个点画线在二维字符数组上画线
  86.      * @param x1
  87.      * @param y1
  88.      * @param x2
  89.      * @param y2
  90.      * @param canvas
  91.      */
  92.     public void drawLine(double x1, double y1, double x2, double y2, char[][] canvas) {
  93.         int radius = (canvas.length - 1) / 2;
  94.         // 从 x 方向进行填充
  95.         if (x1 > x2) {
  96.             double t = x1;
  97.             x1 = x2;
  98.             x2 = t;
  99.             t = y1;
  100.             y1 = y2;
  101.             y2 = t;
  102.         }

  103.         // 获得直线方程的两个系数
  104.         double a = (y1 - y2) / (x1 - x2);
  105.         double b = y1 - a * x1;

  106.         // 根据 x 方向的值求出 y 值,并填充图形
  107.         for (int i = (int) Math.round(x1); i <= (int) Math.round(x2); i++) {
  108.             // 根据直线方程 y = ax + b,求 y
  109.             int y = (int) Math.round(a * i + b);

  110.             // 因为 y 和 i 算出来的结果有可能是负数,
  111.             // 为了采用数组来表示坐标,做了以下变换
  112.             // c[R][R] 即为坐标原点
  113.             // c[R][0..R] 为 x 方向的负半轴
  114.             // c[R][R+1..2*R] 为 x 方向的正半轴
  115.             // c[0..R][R] 为 y 方向的正半轴
  116.             // c[R+1..2*R][R] 为 y 方向的负半轴
  117.             int yy = radius - y;
  118.             int xx = radius + i;

  119.             yy = yy < 0 ? 0 : yy;
  120.             yy = yy > 2 * radius ? 2 * radius : yy;
  121.             xx = xx < 0 ? 0 : xx;
  122.             xx = xx > 2 * radius ? 2 * radius : xx;

  123.             canvas[yy][xx] = fillChar;
  124.         }

  125.         // 从 y 方向进行填充,便于减少间距问题产生的字符空档
  126.         if (y1 > y2) {
  127.             double t = x1;
  128.             x1 = x2;
  129.             x2 = t;
  130.             t = y1;
  131.             y1 = y2;
  132.             y2 = t;
  133.         }

  134.         // 根据 y 方向的值求出 x 值,并填充图形
  135.         for (int i = (int) Math.round(y1); i <= (int) Math.round(y2); i++) {
  136.             // 根据 x = (y - b) / a,求 x
  137.             int y = (int) Math.round((i - b) / a);

  138.             int yy = radius - i;
  139.             int xx = radius + y;

  140.             yy = yy < 0 ? 0 : yy;
  141.             yy = yy > 2 * radius ? 2 * radius : yy;
  142.             xx = xx < 0 ? 0 : xx;
  143.             xx = xx > 2 * radius ? 2 * radius : xx;

  144.             canvas[yy][xx] = fillChar;
  145.         }
  146.     }
  147.    
  148.     /**
  149.      * 将画完图之后的画布输出到控制台上
  150.      * @param canvas
  151.      */
  152.     public static void printCanvas(char[][] canvas) {
  153.         for (int i = 0; i < canvas.length; i++) {
  154.             for (int j = 0; j < canvas[i].length; j++) {
  155.                 System.out.print(canvas[i][j]);
  156.             }
  157.             System.out.println();
  158.         }
  159.     }
  160. }
复制代码
我想通过DOS命令行打印一个五角星,但是怎么弄都不是我想要的图形,怎么办啊?求帮助!!!

评分

参与人数 1技术分 +1 收起 理由
张_涛 + 1 赞一个!

查看全部评分

3 个回复

倒序浏览
先抢个沙发。我打印出来的是这样的!!

OM@1RILRTNO]7HS5[E8H`$X.jpg (22.96 KB, 下载次数: 13)

OM@1RILRTNO]7HS5[E8H`$X.jpg
回复 使用道具 举报
http://blog.csdn.net/bao110908/archive/2007/11/27/1904452.aspx
这个能帮助你

点评

链接相当给力  发表于 2012-8-26 11:58
回复 使用道具 举报
这个看起来好复杂啊。新手路过
{:soso_e113:}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马