java - 将方程绘制到笛卡尔平面

标签 java graph plot 2d equation

我正在尝试将二变量方程绘制到笛卡尔平面上。这是我的问题,在下面的代码中,如果我注释掉一个 for 循环并让另一个运行,则图形的绘图(x 的负数或正数)是正确的,但如果我运行两个 for 循环,它们似乎会改变每个循环其他和图表显示错误。我已经尝试了 for 循环的每种组合,向前循环,向后循环,似乎没有解决它。

我注释掉了这些循环在类“public class DrawingComponent extends JComponent”末尾的位置,其中写着“//如果每个循环独立运行,那么这两个循环可以正常工作”

public class GraphingCalc extends JFrame {

    private static final int FRAME_WIDTH = 450;
    private static final int FRAME_HEIGHT = 400;


    private static final double INITIAL_BALANCE = 1000;

    private JLabel rateLabel;
    private JTextField rateField;
    public JButton button ;
    private JLabel resultLabel;

    private JPanel basePanel;
    private JPanel topPanel; // will contain rateLabel, rateField, and buton
    private JPanel bottomPanel; // will contain drawingComponent 


    JComponent drawingComponent;

    Rectangle box;
    //////////////////////////////
    Graph graphObj;
    double xCoord; 
    int yCoord_size;
    double xRate;
    double[] yCoord;
    //////////////////////////////

    public GraphingCalc() {


        createTextField();


        drawingComponent = new DrawingComponent();      
        box = new Rectangle(100, 100, 20, 30);
        graphObj = new Graph();
        xCoord = 0;

        yCoord_size = 400;
        xRate = 0.101;

        yCoord = new double[yCoord_size];

        createButton();

        createPanel();

        setSize(FRAME_WIDTH, FRAME_HEIGHT);
    }

    private void createTextField() {

        rateLabel = new JLabel("Equation: ");

        final int FIELD_WIDTH = 10;
        rateField = new JTextField(FIELD_WIDTH);

    }



public void createButton() {

        button = new JButton("Plot");

         class AddInterestListener implements ActionListener {

            public void actionPerformed(ActionEvent event) {

                if(event.getSource() == button) {

                    //System.out.println("Boo");
                    graphObj.setEq(rateField.getText());

                }
                else {

                }

                //yCoord = Arrays.copyOf(graphObj.setY(), 10);
                yCoord = graphObj.getY(drawingComponent.getSize().width);

                //for(int i=0; i<10; i++)
                    //System.out.println("yCoord: " + yCoord[i] +"\n");

                revalidate();
                repaint();


            }
        }
        ActionListener listener = new AddInterestListener();
        button.addActionListener(listener);
    } 

public class DrawingComponent extends JComponent {

    public void paintComponent(Graphics g) {

            //////////////////////////
            // int scale 
            // multiply coord values by this
            // scale
            /////////////////////////
            Graphics2D g2 = (Graphics2D) g;

            g2.setStroke(new BasicStroke(1f));
            //g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            int drawArea_width = getSize().width;
            int drawArea_height = getSize().height;

            /////////////////////
            // x axis
            g2.draw(new Line2D.Double( 0, drawArea_height/2, drawArea_width ,drawArea_height/2 ));
            Font font = new Font("Times New Roman", Font.PLAIN, 10);
            g2.setFont(font);

            //positive x axis values

            for(int i = 1; i < 20; i++) {

                String num = Integer.toString(i);
                if(i >= 10) {
                    g2.draw(new Line2D.Double((drawArea_width/2 -19 ) + i*12 , (drawArea_height/2) -2 , (drawArea_width/2 -19 ) + i*12 , (drawArea_height/2) + 2 ));
                    g2.drawString(num, (drawArea_width/2 -22 ) + i*12  , (drawArea_height/2) + 15 );
                }

                else {
                    g2.draw(new Line2D.Double((drawArea_width/2) + i*10 , (drawArea_height/2) -2 , (drawArea_width/2) + i*10 , (drawArea_height/2) + 2 ));
                    g2.drawString(num, (drawArea_width/2 -1) + i*10 , (drawArea_height/2) + 15 );
                }
            }
            //


            //negative x axis values
            for(int i = 20; i > 0; i--) {

                String num = Integer.toString(i);
                if(i <= 9) {

                    g2.draw(new Line2D.Double((drawArea_width/2 ) - i*13 , (drawArea_height/2) -2 , (drawArea_width/2 ) - i*13 , (drawArea_height/2) + 2 ));
                    g2.drawString("-" + num, (drawArea_width/2 - 4) - i*15 , (drawArea_height/2) + 15 );
                }

                else {

                    g2.draw(new Line2D.Double((drawArea_width/2 + 16 ) - i*15 , (drawArea_height/2) -2 , (drawArea_width/2 + 16 ) - i*15 , (drawArea_height/2) + 2 ));
                    g2.drawString("-" + num, (drawArea_width/2 + 16 ) - i*17  , (drawArea_height/2) + 15 );
                }
            }
            //


            //////////////////////

            //y axis
            g2.draw(new Line2D.Double( drawArea_width/2, 0, drawArea_width/2, drawArea_height ));


            g2.setStroke(new BasicStroke(1.20f));



            // This two loops work fine if each one is run independently

            xCoord = 0;
            for(int i = 0; i < yCoord_size/2 ; i++) {

                //g2.draw(new Line2D.Double((drawArea_width/2 ) + xCoord , yCoord[i] + (drawArea_height/2), (drawArea_width/2 ) + xCoord , yCoord[i] + (drawArea_height/2) ) );
                g2.draw(new Ellipse2D.Double((drawArea_width/2 ) + xCoord , yCoord[i] + (drawArea_height/2), 1, 1));
                xCoord-= xRate;
            } 

            /*
            for(int i = yCoord_size/2; i < yCoord_size ; i++) {

                //g2.draw(new Line2D.Double((drawArea_width/2 ) + xCoord , yCoord[i] + (drawArea_height/2), (drawArea_width/2 ) + xCoord , yCoord[i] + (drawArea_height/2) ) );
                g2.draw(new Ellipse2D.Double((drawArea_width/2 ) + xCoord , yCoord[i] + (drawArea_height/2), 1, 1));
                xCoord+= xRate;
            }
            */

        }       
}


    private void createPanel() {

        basePanel = new JPanel();
        topPanel = new JPanel();

        basePanel.setLayout(new BorderLayout());

        topPanel.add(rateLabel);
        topPanel.add(rateField);
        topPanel.add(button);


        basePanel.add(topPanel, BorderLayout.NORTH);
        basePanel.add(drawingComponent, BorderLayout.CENTER);

        add(basePanel);     
    }
}




public class Graph {

    int yCoord_size;
    double xRate;
    String equation;
    double[] yCoord;
    static double num;

    public Graph() {

        yCoord_size = 400;
        xRate = 0.101;

        equation = "";
        num = 0;
        yCoord = new double[yCoord_size];

        for(int i=0; i <10; i++)
            yCoord[i] = 0;
    }

    public void setEq(String eq) {

        equation = eq;

        //System.out.println("eq is: " + eq);


    }

    public double equationStrToVal(String eq, double inX){  

        double total = 0.0;
        double x = inX;
        String[] tokens;
        tokens = eq.split(" ");

        for(int i=0; i<tokens.length; i++){

            if(tokens[i].equalsIgnoreCase("x")){

                total+= x;
            }

            //addition
            else if(tokens[i].equals("+")){
                if(tokens[i+1].equalsIgnoreCase("x"))
                    total+= x;
                else
                    total+= stringToDouble( tokens[i+1]);
                i++;
            }

            //multiplication
            else if(tokens[i].equals("*")){
                if(tokens[i+1].equalsIgnoreCase("x"))
                    total*= x;
                else
                    total*=stringToDouble( tokens[i+1]);
                i++;
            }

            //raised to a power

        }

        return total;
        //System.out.println("The result is: " + total);
    }

    public double[] getY(int screen_width) {

        double j = 0.0;

        //for(int i=0 ; i < screen_width/2; i++, j-=0.05) 
        for(int i=0 ; i < yCoord_size/2; i++, j-=xRate) 
            yCoord[i] =  -1 * equationStrToVal(equation, j);

        j = 0;

        //for(int i=screen_width/2 ; i<screen_width ; i++, j+=0.05)
        for(int i= yCoord_size/2 ; i< yCoord_size ; i++, j+=xRate)
            yCoord[i] = -1 * equationStrToVal(equation, j);     


        return yCoord;
    }

    static double stringToDouble(String num){


        return ( Double.valueOf(num.trim()).doubleValue());

    }

}

public class GraphingCalcViewer {

    public static void main(String[] args) {

        JFrame frame = new GraphingCalc();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

}

最佳答案

如果注释掉一个循环,则另一个循环始终以 xCoord = 0 开始;

如果运行两个循环,第二个循环将从当前的 xCoord.value 开始

看起来你必须设置“xCoord = 0;”在第二个循环之前;

关于java - 将方程绘制到笛卡尔平面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10776728/

相关文章:

plot - 水平(横向)直方图 - gnuplot

python - 在一个 barplot 中绘制字典字典

matlab - 绘制 3D 线,matlab

java - 像这样使用计时器的目的是什么?

Java:线程安全的 RandomAccessFile

java - 可滚动、不可编辑、可更新的文本

algorithm - 生成随机流网络

java - 让 RecyclerView 像 Whatsapp 一样更新

python - 创建动态图 python NetworkX

algorithm - 为图表的 Y 轴选择有吸引力的线性比例