0

[Java] Vẽ đồ thị hàm số bằng JPanel đơn giản

Chào các bạn, hồi học trung học chắc hẳn ai cũng từng phải vẽ đồ thị hàm số rồi nhỉ. Nay mình sẽ ứng dụng java và JPanel vào vẽ đồ thị nhé.

1 Tạo class

Đầu tiên các bạn tạo một class Java là GraphPanel.javaextends JPanel vào giúp mình nhé

public class GraphPanel extends JPanel {}

2 Tạo khung frame

Các bạn tạo hàm main trong GraphPanel.java. Tạo new 1 JFrame với kích thước 400 x 400 như code bên dưới đây

public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new GraphPanel());
        frame.setSize(400, 400);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

3 Thêm paintComponent

Trong GraphPanel.java các bạn thêm hàm paintComponent như bên dưới, phương thức này được override từ lớp JPanel
Tiếp đó trong đoạn code chúng ta sẽ sử dụng Graphics2D, đây là một lớp thừa kế từ lớp Graphics , cung cấp cho chúng ta các công cụ để vẽ đồ hoạ hình học.

  • width: độ rộng của JFrame
  • height: độ cao của JFrame
  • margin : là kích thước lề JFrame (bạn nào biết về css sẽ hiểu rõ margin hơn)
@Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;

        int width = getWidth();
        int height = getHeight();
        int margin = 50;
    }

4 Tạo lưới (Phần này bạn có thể bỏ qua nếu không thích)

Trong đoạn code này chúng ta sẽ in các đường thẳng từ trên xuống dưới và từ trái sang phải. Kết quả thu được, các bạn chạy thử trải nghiệm nhé.

        // paintComponent
        // Vẽ lưới
        g2.setPaint(Color.LIGHT_GRAY);
        for (int i = 0; i < width; i += 50) {
            g2.draw(new Line2D.Double(i, 0, i, height));
        }
        for (int i = height; i > 0; i -= 50) {
            g2.draw(new Line2D.Double(0, i, width, i));
        }

5 Vẽ trục X và Trục Y

  • Chúng ta dùng phương thức g2.drawLine2D.Double để thực hiện vẽ các đường thẳng trục X và trục Y.
  • Đường thẳng được tạo thành từ 2 điểm nối với nhau nên tham số của Line2D.Double sẽ là :
    • x1, y1 : toạ độ x, y của điểm đầu
    • x2, y2 : toạ độ x, y của điểm cuối

Cuối cùng chúng ta thêm ký tự X , Y vào trục bằng phương thức g.drawString

        // Xác định điểm đầu và điểm cuối của trục toạ độ Y
        int x1 = width / 2;
        int y1 = margin;
        int x2 = width / 2;
        int y2 = height - margin;

        // Xác định điểm đầu và điểm cuối của trục toạ độ X
        int x3 = margin;
        int y3 = height / 2;
        int x4 = width - margin;
        int y4 = height / 2;

        // điểm trung tâm
        int centerX = width / 2;
        int centerY = height / 2;
        
        // Vẽ trục X và Y
        g2.setPaint(Color.BLACK);
        g2.draw(new Line2D.Double(x1, y1, x2, y2));
        g2.draw(new Line2D.Double(x3, y3, x4, y4));
        
        // Vẽ mũi tên cho trục X
        g2.setPaint(Color.RED);
        g2.draw(new Line2D.Double(x4, y4, x4 - 10, y4 - 5));
        g2.draw(new Line2D.Double(x4, y4, x4 - 10, y4 + 5));
        g.drawString("X", x4 - 10, y4 - 10);

        // Vẽ mũi tên cho trục Y
        g2.setPaint(Color.RED);
        g2.draw(new Line2D.Double(x1, y1, x1 - 5, y1 + 10));
        g2.draw(new Line2D.Double(x1, y1, x1 + 5, y1 + 10));
        g.drawString("Y", x1 - 10, y1);

6 Vẽ đồ thị parabol

Tại bước này chúng ta sẽ tính toán từng điểm trên đồ thị và nối chúng vào với nhau.

  • Tại đây mình tạo giá trị firstDot để khi chỉ có một điểm thì mình sẽ vẽ điểm thay vì nối đường thẳng

  • lastXlastY mình sẽ lưu lại điểm trước đó

  • Mình chạy loop từ giá trị từ 100 đến -100 với step i+=10 (Phần này các bạn có thể tuỳ chỉnh theo ý thích)

  • g2.fill(new Ellipse2D.Double(x - 2, y - 2, 4, 4)) đoạn này để mình vẽ ra điểm (chỉ chạy duy nhất 1 lần khi bắt đầu vẽ)

  • g2.draw(new Line2D.Double(lastX, lastY, x, y)); đoạn này mình nối 2 điểm : điểm trước đó(lastX, lastY) và điểm mình vừa tính toán(x,y)

  • Giá trị 0.01 mình nhân vào để phóng to đồ thị ra (các bạn có thể thử bỏ đi, khi đó các bạn sẽ thấy đồ thị hơi khó nhìn)

  • Hàm parabol trả về giá trị x^2 mình sẽ trình này trong mục sau

        // Vẽ các điểm dữ liệu
        g2.setPaint(Color.BLUE);
        boolean firstDot = true;
        double lastX = 0.0;
        double lastY = 0.0;
        for (int i = -100; i <= 100; i+=10) {
            double x = centerX + i ;
            double y = centerY - (0.01 * this.parabol(i));
            System.out.println("index : " + i + " ( x : " + x + " y : " + y + " ) ");
            if(firstDot) {
                g2.fill(new Ellipse2D.Double(x - 2, y - 2, 4, 4));
                firstDot =  false;
            } else {
                g2.draw(new Line2D.Double(lastX, lastY, x, y));
            }
            lastX = x;
            lastY = y;
        } 
    

7 Hàm parabol

Bạn có thể copy hàm dưới đây và chạy thử chương trình xem Jpanel vẽ đồ thị nhé

// y = x^2
    private double parabol(double x) {
        return x*x;
    }

Dưới đây là hàm x * sin(x^2) + 1 . Các bạn thử thay vào và xem đồ thị của mình chạy nhé

// y = x * sin(x^2) + 1
    private double ASinX2PlusOne(double x) {
        return (x * Math.sin(x*x) + 1);
    }

Bài viết này mình hướng dẫn làm vẽ đồ thị cơ bản bằng JPanel, Cảm ơn các bạn đã đọc


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.