Search code examples
javaswingmathgraph

Issue with graphing a quadratic function using Swing graphics


I'm trying to create a simple function grapher using the swing gui stuff, but for some reason, the graphed function consistently draws a weird line as it reaches the vertex.


public class main {
    public static void main(String[] args) {
        new graphFrame();
    }
}


import java.awt.Dimension;
import java.awt.*;

import javax.swing.JPanel;

public class graphPanel extends JPanel {
    int h = 500;
    int w = 500;

    int originX = w/2;
    int originY = h/2;

    graphPanel() {
        this.setPreferredSize(new Dimension(h, w));
    }

    public void paintComponent(Graphics g) {
        double scale = 10;

        // Creates the x and y axis
        Graphics2D g1 = (Graphics2D) g;

        g1.drawLine(0, h/2, w, h/2);
        g1.drawLine(w/2, 0, w/2, h);

        double a = 5;
        double b = -7;
        double c = 2;

        // Draws function
        Graphics2D g2 = (Graphics2D) g;
        g2.setStroke(new BasicStroke(2));
        g2.setColor(Color.red);

        Polygon p1 = new Polygon();
        for (int x = -w; x <= w; ++x) {
            p1.addPoint(originX + x*scale, originY - scale * ((int) Math.round(a*(x*x)+b*x+c)));
          }
          
        g2.drawPolyline(p1.xpoints, p1.ypoints, p1.npoints);
    }
}

import javax.swing.JFrame;

public class graphFrame extends JFrame {
    graphPanel panel;

    graphFrame() {
        panel = new graphPanel();

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.add(panel);
        this.pack();
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }
}

This is just being added to a JFrame, but I didn't think that the JFrame code would be relevant.

For example:

Actual Expected (Desmos for reference)

I thought that might had to do with the scaling of the equation, because it rounds the integer, but even if you multiply the y and x by 10 with the scale int, it still has that weird line thing towards the vertex. I moved the scale multiplication part that gets rounded but that didn't help either. I'm stuck.

Thank you in advance for any suggestions!


Solution

  • Thank you tgdavies for your help.

    By changing the for loop to a double, you can get more precision with each point added. Also changing where the rounding into integer part happens to envelop the whole equation.

    This:

    for (double x = -w; x <= w; x += 0.1) {
                p1.addPoint((int) Math.round(originX + x*scale), (int)Math.round(originY - scale * (a*(x*x)+b*x+c)));
            }
    

    Instead of :

    for (int x = -w; x <= w; ++x) {
                p1.addPoint(originX + x*scale, originY - scale * ((int) Math.round(a*(x*x)+b*x+c)));
                System.out.println(originY - scale * ((int) Math.round(a*(x*x)+b*x+c)));
              }
    

    IT WORKS! Working parabola