YiYuan(double a,double b,double c,double d){ this.a=a; this.b=b; this.c=c; this.d=d; } public double valueAt(double x){ return (a*x*x+b*x+c)/d; } } private static class Sin implements Plotable{ private double a; private double b;
Sin(double a,double b){ this.a=a; this.b=b; } public double valueAt(double x){ return a*Math.sin(x/b); } } } 下面是画板代码:package graphtools;import java.awt.*; import java.util.*; import java.awt.geom.*; /** * @DarkLord * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */ public class PlotPanel extends Panel { private final double start; private final double end; private final double pace; private Dimension size; private final Color[] color; private final Plotable[] function; private final java.util.List[] list; private int pointPainted=0;
public PlotPanel(Plotable[] plotFunction,Color[] color,double start,double end,double pace){ this.start=start; this.end=end; this.pace=pace; this.function=plotFunction; this.color=color; list=new ArrayList[plotFunction.length]; for(int i=0;i<list.length;i++) list[i]=new ArrayList(); } public Dimension getPreferredSize() { return new Dimension(600,500); }
public void startPlot(){ EventQueue.invokeLater(new Runnable(){ public void run(){ double step=getStart(); int count=1; while(step<=getEnd()){ double x=step; for(int i=0;i<list.length;i++){ double y=(-1)*function[i].valueAt(x); list[i].add(new Point2D.Double(x,y)); }
} public void update(Graphics2D gg){ for(int j=pointPainted;j<list[0].size()-1;j++) plotPoints(gg,j); } } 下面是Plotable接口代码:package graphtools;/** * @DarkLord * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */ public interface Plotable { public double valueAt(double x); }
如果只是想在屏幕上显示一下的话,用0.1的步长就足够了。画出的图形和用0.001为步长值所画出来的看起来是一样的。
gg.draw(new Line2D.Double(px,py,px,py));来画图,这实际上是一个点一个点的画图了,不应该这么写。把程序改成这样:
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D gg = (Graphics2D) g; //将坐标原点移动到ShowPanel的中心点
double tpx = this.getWidth() / 2;
double tpy = this.getHeight() / 2;
gg.translate(tpx, tpy); gg.setColor(Color.red);
double py0 = Double.MIN_VALUE;
double startx = -100.0d;
while (startx <= 100.0d) {
double px = startx;
double py = a * px * px + b * px + c;
py = (-1) * py / 50;
if (py0 != Double.MIN_VALUE) {
gg.draw(new Line2D.Double(px-Demo.inch, py0, px, py));
}
py0 = py;
startx += Demo.inch;
}
}即使用步长值inch=10d; 画出来的图形也已经很平滑了。
改用awt的Frame 和Panel 就OK了!下面是我改好的程序,与大家分享。不过仍有个小问题,不知为什么有时画一遍就OK,有时却画两遍,还请大家帮忙!!!下面这个是主程序:package graphtools;
import java.awt.*;
import java.awt.event.*;
/**
* @DarkLord
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class PlotGraph { public static void main(String[] args) {
Plotable[] function={
new YiYuan(1.0d,0.0d,-400.0d,50.0d),
new YiYuan(-1.0d,0.0d,+400.0d,50.0d),
new Sin(50.0d,30.0d),
new Sin(-50.0d,30.0d)
};
Color[] color={Color.red,Color.green,Color.blue,Color.cyan};
final PlotPanel pp=new PlotPanel(function,color,-100.0d,100.0d,0.01d);
final Frame f=new Frame("Ploting Mathematic Graph");
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
f.add(pp);
f.pack();
EventQueue.invokeLater(new Runnable(){
public void run(){
f.setVisible(true);
pp.startPlot();
}
});
}
private static class YiYuan implements Plotable{
private double a;
private double b;
private double c;
private double d;
YiYuan(double a,double b,double c,double d){
this.a=a;
this.b=b;
this.c=c;
this.d=d;
}
public double valueAt(double x){
return (a*x*x+b*x+c)/d;
}
}
private static class Sin implements Plotable{
private double a;
private double b;
Sin(double a,double b){
this.a=a;
this.b=b;
}
public double valueAt(double x){
return a*Math.sin(x/b);
}
}
}
下面是画板代码:package graphtools;import java.awt.*;
import java.util.*;
import java.awt.geom.*;
/**
* @DarkLord
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class PlotPanel extends Panel {
private final double start;
private final double end;
private final double pace;
private Dimension size;
private final Color[] color;
private final Plotable[] function;
private final java.util.List[] list;
private int pointPainted=0;
public PlotPanel(Plotable[] plotFunction,Color[] color,double start,double end,double pace){
this.start=start;
this.end=end;
this.pace=pace;
this.function=plotFunction;
this.color=color;
list=new ArrayList[plotFunction.length];
for(int i=0;i<list.length;i++)
list[i]=new ArrayList();
}
public Dimension getPreferredSize() {
return new Dimension(600,500);
}
public void startPlot(){
EventQueue.invokeLater(new Runnable(){
public void run(){
double step=getStart();
int count=1;
while(step<=getEnd()){
double x=step;
for(int i=0;i<list.length;i++){
double y=(-1)*function[i].valueAt(x);
list[i].add(new Point2D.Double(x,y));
}
if(++count%100==0)
repaint();
step+=pace;
}
}
});
}
public void plotPoint(Graphics2D gg,Color color,java.util.List ls,int i){
gg.setColor(color);
Point2D.Double p=(Point2D.Double)ls.get(i);
gg.draw(new Line2D.Double(p,p));
}
public void plotPoints(Graphics2D gg,int i){
for(int j=0;j<list.length;j++)
plotPoint(gg,color[j],list[j],i);
pointPainted++;
}
public void plotAxis(Graphics2D gg,Color color){
gg.setColor(color);
Line2D linex=new Line2D.Double(-200.0,0.0,200.0,0.0);
Line2D liney=new Line2D.Double(0.0,200.0,0.0,-200.0);
Line2D l1=new Line2D.Double(200.0,0.0,195.0,5.0);
Line2D l2=new Line2D.Double(200.0,0.0,195.0,-5.0);
Line2D l3=new Line2D.Double(0.0,-200.0,-5.0,-195.0);
Line2D l4=new Line2D.Double(0.0,-200.0,5.0,-195.0);
gg.draw(linex);
gg.draw(liney);
gg.draw(l1);
gg.draw(l2);
gg.draw(l3);
gg.draw(l4);
gg.drawString("x",195,15);
gg.drawString("y",-15,-190);
gg.draw3DRect(-210,-210,420,420,true);
}
public double getStart(){
return start;
}
public double getEnd(){
return end;
}
public void paint(Graphics g){
Graphics2D gg=(Graphics2D)g;
size=getSize();
gg.translate(size.width/2,size.height/2);
plotAxis(gg,Color.black);
for(int j=0;j<list[0].size()-1;j++)
plotPoints(gg,j);
}
public void update(Graphics2D gg){
for(int j=pointPainted;j<list[0].size()-1;j++)
plotPoints(gg,j);
}
}
下面是Plotable接口代码:package graphtools;/**
* @DarkLord
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public interface Plotable {
public double valueAt(double x);
}