簡體   English   中英

Java簡單繪圖器小程序

[英]Java Simple Grapher Applet

我正在嘗試用Java創建一個簡單的函數抽屜。 我正在使用ScriptEngine API從字符串中解析方程式,但是在繪制時它變得很慢。 還有另一種方法可以做同樣的事情嗎? 這是代碼:

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));
}

好吧,您可以隨時嘗試我的代碼,它簡單,快速,優雅。它還可以使用外部解析器繪制任何圖形。

    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);



}

}

一種低掛的結果可能是在drawEquation()方法的for循環步驟中增加該值。 選擇此值時,請考慮到水平方向上最大〜2K至3K像素。 但是,您要在X軸上迭代2萬多個點。 首先嘗試x0 + = 0.01,然后根據需要進行調整。 這可能會導致您的程序以1/10的時間運行。

如果將ScriptEngineManager mgr對象作為成員變量並創建一次(在您的類的構造函數中),它將更快得多。

  • 僅當輸入對話框中的文本更改時(而不是每個繪圖中),才從drawEquation調用解析和計算。 您可以將計算值保存在兩個數組中(一個數組用於x,另一個數組用於y值)。

作為一般規則(對於我知道的每個圖形引擎),onDraw方法應該小而快速。

  • 不要在onDraw中執行對象創建和初始化。 這為垃圾收集器提供了大量工作。
  • 如果之前可能執行過大量計算,請不要在onDraw中執行大量計算。

編輯:僅計算和繪制需要繪制的點。 您需要知道Graphic對象的寬度,計算for循環的增量值,並且僅具有g.width()次迭代。 更多的迭代只是一種浪費-您在同一屏幕位置上繪制了許多點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM