简体   繁体   English

Java简单绘图器小程序

[英]Java Simple Grapher Applet

I'm trying to make a simple function drawer in Java. 我正在尝试用Java创建一个简单的函数抽屉。 I'm using the ScriptEngine API to parse the equation from a string, but it gets very slow while drawing. 我正在使用ScriptEngine API从字符串中解析方程式,但是在绘制时它变得很慢。 Is there another way to do the same thing? 还有另一种方法可以做同样的事情吗? Here is the code: 这是代码:

private String v;
@Override
public void init(){
    setSize(600,600);
    v = JOptionPane.showInputDialog("Input function:");
}
@Override
public void paint(Graphics g){
    drawQuadrants(g);
    drawEquation(g);
}
private void drawEquation(Graphics g) {
    g.setColor(Color.BLUE);
    ScriptEngineManager mgr = new ScriptEngineManager();
    ScriptEngine engine = mgr.getEngineByName("JavaScript");
    v = v.replace("sin", "Math.sin")
    .replace("cos", "Math.cos")
    .replace("sen", "Math.sin")
    .replace("tan", "Math.tan")
    .replace("tg", "Math.tan")
    .replace("log", "Math.log")
    .replace("Log(x)","(Math.log(x)/Math.LN10)");
    for(double x0 = -10;x0<=10;x0+=0.001){
        engine.put("x", x0);
        try {
            double y0 = (Double)engine.eval(v);
            drawPoint(g,x0,-y0);
        } catch (HeadlessException | ScriptException e) {
            e.printStackTrace();
        }
    }
}
private void drawQuadrants(Graphics g) {
    g.setColor(Color.BLACK);
    g.drawLine(0, 300, 600, 300);
    g.drawLine(300, 0, 300, 600);
    g.setFont(new Font("Arial",Font.BOLD,15));
    g.drawString("x", 580, 320);
    g.drawString("y", 280, 20);
    for(int l = 0;l<=600;l+=30){
        g.drawLine(l, 297, l, 303);
    }
    for(int l = 0;l<=600;l+=30){
        g.drawLine(297, l, 303, l);
    }
}
private void drawPoint(Graphics g, double x0, double y0) {
    int newx0 = (int)map((float)x0, (float)-10, (float)10, (float)0.0, (float)600.0);
    int newy0 = (int)map((float)y0, (float)-10, (float)10, (float)0.0, (float)600.0);
    g.drawOval(newx0, newy0, 1, 1);
}
public static final float map(float value, float start1, float stop1, float start2, float stop2)
{
    return start2 + (stop2 - start2) * ((value - start1) / (stop1 - start1));
}

Well you could always try my code,it is simple fast and elegant.It can also plot any graph by using an external parser. 好吧,您可以随时尝试我的代码,它简单,快速,优雅。它还可以使用外部解析器绘制任何图形。

    import javax.swing.*;
    import java.awt.*;
     import java.util.Scanner;
       import net.objecthunter.exp4j.*;

     class math extends JFrame
     {
       public static void main(String args[])
      {
    math m=new math();
    m.setVisible(true);
    m.setLocationRelativeTo(null);


}

public void paintallies(Graphics G1,double sf)
{int i;
 Graphics2D g21=(Graphics2D) G1;
 g21.setColor(Color.GREEN);
    for(i=0;i<=600;i=(int) (i+sf))
    {
        g21.drawLine(i,0,i,600);
        g21.drawLine(0,i,600,i);

    }

}
public void paintaxes(Graphics G1)
{
    Graphics2D g21=(Graphics2D) G1;
    g21.setColor(Color.BLACK);
    g21.drawLine(300,0,300,600);//y axis

    g21.drawLine(0,300,600,300); //x axis

}


public void paint(Graphics G)
{
    int i;
    double j,k;

    Scanner s=new Scanner(System.in);
    System.out.println("Enter input");
    String input=s.nextLine();
    System.out.println("Enter scale factor");
    double sf=s.nextDouble();
    double sff=300/sf;
    double kf=sff;
    double count=0;






    Graphics g2=(Graphics) G;
    paintallies(G,sf);
    paintaxes(G);

    g2.translate(300,300);
    do
    {
        kf=kf-(1/sf);
        count++;

    }while(kf>=0);
    double counts=2*count;


    Color c=Color.RED;
    g2.setColor(c.darker());

    double yarr[]=new double[(int)counts];
    double xarr[]=new double[(int)counts];



    Expression E=new ExpressionBuilder(input).variables("x").build();


     j=-sff; k=-sff;
    for(i=0;i<counts;i++)
    {

        xarr[i]=j;
        j=j+(1/sf);


        E.setVariable("x",k);
        yarr[i]=E.evaluate();
        k=k+(1/sf);

        xarr[i]=sf*xarr[i];
        yarr[i]=-sf*yarr[i];

    }

    for(i=0;i<counts;i++)
    {
        if(i==counts-1)
        {
            break;
        }
        else
        {
        g2.drawLine((int)xarr[i],(int)yarr[i],(int)xarr[i+1],(int)yarr[i+1]);

        }
    }


}






math()
{
    super("Grapher");
    setSize(600,600);
    setResizable(true);



}

} }

One low-hanging fruit may be to increase the value in the for-loop step in the drawEquation() method. 一种低挂的结果可能是在drawEquation()方法的for循环步骤中增加该值。 When choosing this value, take into consideration that you have ~ 2K to 3K pixels max horizontally. 选择此值时,请考虑到水平方向上最大〜2K至3K像素。 Yet, you're iterating over 20K points on the X axis. 但是,您要在X轴上迭代2万多个点。 Try x0+=0.01 first, then adjust as needed. 首先尝试x0 + = 0.01,然后根据需要进行调整。 This may cause your program to run in 1/10th the time. 这可能会导致您的程序以1/10的时间运行。

It would be much faster if you - make ScriptEngineManager mgr object as member variable and create it once (in constructor of your class) 如果将ScriptEngineManager mgr对象作为成员变量并创建一次(在您的类的构造函数中),它将更快得多。

  • invoke parsing and calcuations from drawEquation only when text in input dialog changes, not in every draw. 仅当输入对话框中的文本更改时(而不是每个绘图中),才从drawEquation调用解析和计算。 You could save computed values in two arrays (one array for x, another one for y values). 您可以将计算值保存在两个数组中(一个数组用于x,另一个数组用于y值)。

As general rule (for every graphic engime I do know), onDraw method should be small and fast. 作为一般规则(对于我知道的每个图形引擎),onDraw方法应该小而快速。

  • do not perform object cration and initalization in onDraw. 不要在onDraw中执行对象创建和初始化。 That crates A LOT of work for garbage collector. 这为垃圾收集器提供了大量工作。
  • do not perform extensive computation in onDraw, if those computation may be performed before. 如果之前可能执行过大量计算,请不要在onDraw中执行大量计算。

EDIT: Calculate and draw only points you need to draw. 编辑:仅计算和绘制需要绘制的点。 You need to know width of your Graphic objects, compute increment value of the for loop and have only g.width() number of iterations. 您需要知道Graphic对象的宽度,计算for循环的增量值,并且仅具有g.width()次迭代。 More iterations is just a waste- you are drawing many points in the same screen location. 更多的迭代只是一种浪费-您在同一屏幕位置上绘制了许多点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM