首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java AWT 繪圖實戰:繪製五星紅旗完整代碼解析

     編輯:Java 相關知識

使用 Java AWT 基礎繪圖 API 繪製五星紅旗,涵蓋五角星幾何計算、坐標變換、多星佈局、Applet 繪製流程。雖然 Applet 已淘汰,但幾何算法與繪圖邏輯對 Swing/JavaFX/Canvas 繪圖仍具參考價值。

核心幾何:五角星頂點坐標計算

五角星可視為正五邊形五個頂點連線形成。已知外接圓半徑 `R`、圓心 `(m,n)`,利用三角函數計算 10 個頂點 (5 個外頂點、5 個內凹頂點) 坐標:


class StarModel {
    // 預計算常量
    private final double sin72 = Math.sin(2 * Math.PI / 5);     // sin(72°)
    private final double cos36 = Math.cos(Math.PI / 5);         // cos(36°)
    private final double cos72 = Math.cos(2 * Math.PI / 5);     // cos(72°)
    private final double tan36 = Math.tan(Math.PI / 5);         // tan(36°)
    private final double tan72 = Math.tan(2 * Math.PI / 5);     // tan(72°)

    // 計算 10 個 X 坐標 (順序:頂點→內凹→頂點...)
    int[] calculateX(int centerX, int R) {
        int[] x = new int[10];
        int r = (int) (R * cos72); // 內切圓半徑
        x[0] = centerX;                                    // 頂點 0 (正上方)
        x[1] = centerX - (int) (r * tan36);                // 內凹 1
        x[2] = centerX - (int) (R * sin72);                // 頂點 2
        x[3] = centerX - (int) (r * sin72 / cos36);        // 內凹 3
        x[4] = centerX - (int) (2 * R * sin72 * cos72);    // 頂點 4
        x[5] = centerX;                                    // 頂點 5 (正下方,與 0 同 X)
        x[6] = centerX + (int) (2 * R * sin72 * cos72);    // 頂點 6 (對稱)
        x[7] = centerX + (int) (r * sin72 / cos36);        // 內凹 7
        x[8] = centerX + (int) (R * sin72);                // 頂點 8
        x[9] = centerX + (int) (r * tan36);                // 內凹 9
        return x;
    }

    // 計算 10 個 Y 坐標
    int[] calculateY(int centerY, int R) {
        int[] y = new int[10];
        int r = (int) (R * cos72);
        y[0] = centerY;                                    // 頂點 0
        y[1] = centerY + (int) (r * tan36 * tan72);        // 內凹 1
        y[2] = centerY + R - r;                            // 頂點 2
        y[3] = centerY + R + (int) (r * cos72 / cos36);    // 內凹 3
        y[4] = centerY + (int) (2 * R * sin72 * sin72);    // 頂點 4
        y[5] = centerY + R + (int) (r / cos36);            // 頂點 5
        y[6] = y[4];                                       // 對稱
        y[7] = y[3];
        y[8] = y[1];
        y[9] = y[1];
        return y;
    }
}

完整繪製類 (Applet 版)


import java.awt.*;
import java.applet.*;

public class DrawStar extends Applet {
    private static final long serialVersionUID = 1L;
    
    // 大星參數
    private final int bigStarX = 200, bigStarY = 70, bigStarR = 70;
    // 四小星參數 (圓心坐標、半徑)
    private final int[][] smallStars = {
        {310, 45, 20},
        {350, 90, 20},
        {355, 150, 20},
        {300, 200, 20}
    };
    
    private final StarModel model = new StarModel();

    @Override
    public void paint(Graphics g) {
        // 1. 繪製紅色背景 (旗面 3:2 比例,此處 700x400)
        g.setColor(Color.RED);
        g.fillRect(80, 20, 700, 400);
        
        // 2. 設置金黃色
        g.setColor(Color.YELLOW);
        
        // 3. 繪製大五角星
        g.fillPolygon(model.calculateX(bigStarX, bigStarR), 
                      model.calculateY(bigStarY, bigStarR), 10);
        
        // 4. 繪製四小五角星
        for (int[] star : smallStars) {
            g.fillPolygon(model.calculateX(star[0], star[2]), 
                          model.calculateY(star[1], star[2]), 10);
        }
    }
}

現代化重寫:Swing / JavaFX / BufferedImage 版

Swing 獨立視窗版 (推薦替代 Applet)


import javax.swing.*;
import java.awt.*;

public class FlagFrame extends JFrame {
    public FlagFrame() {
        setTitle("五星紅旗 - Swing");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(880, 480);
        setLocationRelativeTo(null);
        add(new FlagPanel());
    }
    
    static class FlagPanel extends JPanel {
        private final StarModel model = new StarModel();
        // 同前座標參數...
        
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            
            g2.setColor(Color.RED);
            g2.fillRect(80, 20, 700, 400);
            
            g2.setColor(Color.YELLOW);
            g2.fillPolygon(model.calculateX(bigStarX, bigStarR), model.calculateY(bigStarY, bigStarR), 10);
            for (int[] s : smallStars) {
                g2.fillPolygon(model.calculateX(s[0], s[2]), model.calculateY(s[1], s[2]), 10);
            }
        }
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new FlagFrame().setVisible(true));
    }
}

JavaFX 版 (現代圖形棧)


import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon;
import javafx.stage.Stage;

public class FlagFX extends Application {
    @Override
    public void start(Stage stage) {
        Pane root = new Pane();
        root.setPrefSize(880, 480);
        
        // 紅色背景矩形
        javafx.scene.shape.Rectangle bg = new javafx.scene.shape.Rectangle(80, 20, 700, 400);
        bg.setFill(Color.RED);
        root.getChildren().add(bg);
        
        // 星星路徑生成工具方法
        double bigX = 200, bigY = 70, bigR = 70;
        double[][] small = {{310,45,20},{350,90,20},{355,150,20},{300,200,20}};
        
        root.getChildren().add(createStar(bigX, bigY, bigR));
        for (double[] s : small) root.getChildren().add(createStar(s[0], s[1], s[2]));
        
        stage.setScene(new Scene(root));
        stage.setTitle("五星紅旗 - JavaFX");
        stage.show();
    }
    
    private Polygon createStar(double cx, double cy, double R) {
        Polygon star = new Polygon();
        star.setFill(Color.GOLD);
        // 同三角函數計算 10 點加入 star.getPoints().addAll(x,y...)
        return star;
    }
    
    public static void main(String[] args) { launch(args); }
}

生成圖片文件 (BufferedImage)


public void saveFlagAsPng(Path outputPath) throws IOException {
    int width = 880, height = 480;
    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    Graphics2D g2 = image.createGraphics();
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    
    // 同 paintComponent 繪製邏輯...
    
    g2.dispose();
    ImageIO.write(image, "PNG", outputPath.toFile());
}

幾何算法驗證與擴展

  • 標準比例:國旗法規定旗面長寬比 3:2,大星圓徑為旗高 1/10,小星圓徑為旗高 1/20,大星圓心距旗面左上角 5/30 旗高、5/30 旗寬,四小星圓心位置嚴格對應。上述代碼為演示坐標,生產用標準比例計算。
  • 旋轉變換:四小星每個頂點朝向大星圓心,可用 `AffineTransform.rotate()` 實現,而非硬編碼坐標。
  • 抗鋸齒:`Graphics2D` 開啟 `KEY_ANTIALIASING`,邊緣平滑。
  • 向量圖形:SVG/PDF 輸出用 Apache Batik 或 JavaFX `Path` 導出。

總結

五星紅旗繪製核心在於**正五角星頂點幾何計算**與**多星相對佈局**。AWT/Applet 代碼展示基礎繪圖流程:`Graphics.fillPolygon(x[], y[], n)`。現代開發建議使用 **Swing/JavaFX/BufferedImage** 替代 Applet,配合 `Graphics2D` 抗鋸齒、標準比例計算、旋轉變換,生成高質量旗幟圖形或圖片文件。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved