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

Java 2D 繪圖進階:Arc2D 繪製圓弧、扇形與弧形完整指南

     編輯:Java 綜合教學

Java 2D 繪圖進階:Arc2D 繪製圓弧、扇形與弧形完整指南

Arc2D 核心概念

java.awt.geom.Arc2D 是 Shape 介面實作,表示橢圓弧段。提供三種閉合類型(Arc2D.OPEN、CHORD、PIE),支援浮點(Arc2D.Float)與雙精度(Arc2D.Double)兩種精度。

三種弧類型視覺化差異

常數名稱閉合方式視覺效果適用場景
Arc2D.OPEN開放弧不閉合,僅繪製弧線單純曲線進度條弧、儀表盤指標
Arc2D.CHORD弦封閉弧首尾兩點連直線(弦)弓形區域月亮形狀、切片區域
Arc2D.PIE扇形封閉弧首尾各連圓心形成扇形餅圖切片統計圖表、圓餅圖

建構子與核心參數

// 以矩形邊界定義橢圓,角度單位為度
Arc2D.Double arc = new Arc2D.Double(
    x, y, width, height,  // 外接矩形(決定橢圓大小位置)
    startAngle,           // 起始角度(3點鐘方向為 0°,逆時針為正)
    arcAngle,             // 掃過角度(正數逆時針,負數順時針)
    type                  // Arc2D.OPEN | CHORD | PIE
);

完整示範程式:三種弧類型對比

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

public class ArcTypesDemo extends JPanel {
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
                             RenderingHints.VALUE_ANTIALIAS_ON);
        
        int x = 50, y = 50, w = 200, h = 150;
        int start = 45, extent = 135;
        
        // 1. OPEN - 開放弧
        Arc2D openArc = new Arc2D.Double(x, y, w, h, start, extent, Arc2D.OPEN);
        g2d.setColor(Color.BLUE);
        g2d.setStroke(new BasicStroke(3));
        g2d.draw(openArc);
        g2d.drawString("OPEN (開放弧)", x, y - 10);
        
        // 2. CHORD - 弦封閉
        y += 200;
        Arc2D chordArc = new Arc2D.Double(x, y, w, h, start, extent, Arc2D.CHORD);
        g2d.setColor(new Color(0x2ECC71)); // 翠綠
        g2d.draw(chordArc);  // 僅畫邊框
        // g2d.fill(chordArc); // 填充內部
        g2d.drawString("CHORD (弦封閉)", x, y - 10);
        
        // 3. PIE - 扇形封閉
        y += 200;
        Arc2D pieArc = new Arc2D.Double(x, y, w, h, start, extent, Arc2D.PIE);
        g2d.setColor(new Color(0xE74C3C)); // 紅
        g2d.fill(pieArc);  // 填充扇形
        g2d.drawString("PIE (扇形)", x, y - 10);
        
        // 4. 疊加展示:同一橢圓不同角度範圍
        x = 350; y = 50;
        g2d.setStroke(new BasicStroke(2));
        for (int i = 0; i < 4; i++) {
            Arc2D arc = new Arc2D.Double(x, y, 120, 120, i * 90, 80, Arc2D.PIE);
            g2d.setColor(new Color(
                (int)(Math.random() * 200) + 55,
                (int)(Math.random() * 200) + 55,
                (int)(Math.random() * 200) + 55
            ));
            g2d.fill(arc);
        }
        g2d.drawString("PIE 疊加(模擬餅圖)", x, y - 10);
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("Arc2D 三種類型對比");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new ArcTypesDemo());
            frame.setSize(600, 700);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}

進階應用:繪製圓餅圖

public class PieChartDemo extends JPanel {
    private static class Slice {
        double value;
        Color color;
        String label;
        Slice(double v, Color c, String l) { value = v; color = c; label = l; }
    }
    
    private final Slice[] slices = {
        new Slice(30, new Color(0x3498DB), "Java 30%"),
        new Slice(25, new Color(0xE74C3C), "Python 25%"),
        new Slice(20, new Color(0x2ECC71), "JavaScript 20%"),
        new Slice(15, new Color(0xF39C12), "C++ 15%"),
        new Slice(10, new Color(0x9B59B6), "Go 10%")
    };
    
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
                             RenderingHints.VALUE_ANTIALIAS_ON);
        
        int cx = 300, cy = 250, r = 150;
        double total = 0;
        for (Slice s : slices) total += s.value;
        
        double currentAngle = -90; // 從 12 點鐘方向開始
        for (Slice slice : slices) {
            double extent = (slice.value / total) * 360;
            Arc2D.Double pie = new Arc2D.Double(
                cx - r, cy - r, 2*r, 2*r,
                currentAngle, extent, Arc2D.PIE
            );
            g2d.setColor(slice.color);
            g2d.fill(pie);
            g2d.setColor(Color.WHITE);
            g2d.draw(pie); // 白色分隔線
            
            // 標籤位置:扇形中點方向
            double labelAngle = Math.toRadians(currentAngle + extent/2);
            int lx = (int)(cx + (r * 0.7) * Math.cos(labelAngle));
            int ly = (int)(cy + (r * 0.7) * Math.sin(labelAngle));
            g2d.drawString(slice.label, lx - 30, ly + 5);
            
            currentAngle += extent;
        }
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("程式語言熱門度圓餅圖");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new PieChartDemo());
            frame.setSize(600, 550);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}

關鍵技術細節

  1. 角度制:Java 2D 採用度數,0° 為 3 點鐘方向,逆時針為正。數學慣例(順時針、Y 向上)需自行換算。
  2. 邊界矩形:x,y,width,height 定義橢圓外接矩形,非圓心座標。圓心為 (x+w/2, y+h/2)。
  3. 填充 vs 描邊:fill() 填充內部區域,draw() 僅繪製邊框。PIE 型填充包含圓心區域。
  4. 精度選擇:Arc2D.Float(單精度,記憶體省)vs Arc2D.Double(雙精度,計算準),一般 UI 用 Float 足夠。

常見問題排查

  • 弧不顯示:檢查 width/height > 0、arcAngle != 0、座標是否在可視區域內。
  • 角度方向反了:記住 Java 2D Y 軸向下,逆時針為正;若需順時針,arcAngle 取負值。
  • 扇形邊緣鋸齒:啟用 RenderingHints.KEY_ANTIALIASING。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved