用Java实现一个向量场(一)

2014-11-24 08:12:24 · 作者: · 浏览: 3

在学习微分方程的时候,以前也写过类似的文章,可是效果不行,前几天写了一个,感觉不错,分享之。

先看效果(x*x -y -2):


再来代码:

[java]
package com.math.slopfields;

import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JFrame;

public class SlopFields extends JFrame {
protected static final int WIDTH = 800;
protected static final int HEIGHT = 600;
private java.awt.Dimension dimension = java.awt.Toolkit.getDefaultToolkit().
getScreenSize();


public SlopFields(String title, Grid g) {
super(title);
this.setSize(WIDTH, HEIGHT);
this.setLocation((dimension.width - WIDTH) / 2,
(dimension.height - HEIGHT) / 2);

HeartCanvas panel = new HeartCanvas(g);
this.add(panel);
}

public static void main(String[] args) {
double scale = 80;
double aa = 3;
double dd = 0.15;

Area area = new Area(Vector.build(-aa, aa), Vector.build(aa, -aa));
Vector grid = Vector.build(dd, dd);
CanCalc c = new CanCalc(){
public double doCalc(Vector v) {
return v.x*v.x - v.y - 2;
}

};
Grid g = new Grid(area, grid, c, scale);

SlopFields hart = new SlopFields("向量场", g);
hart.setVisible(true);
hart.setDefaultCloseOperation(hart.EXIT_ON_CLOSE);
}

}


class HeartCanvas extends javax.swing.JPanel {

private Grid grid;

public HeartCanvas(Grid g) {
this.grid = g;
this.grid.calcGrids();
this.grid.preDraw();
}

public void paintComponent(Graphics g) {
setBackground(Color.BLACK);
super.paintComponent(g);
g.setColor(Color.GREEN);
this.grid.draw(g);
}
}


class Grid {
public double scale = 100;
public double padding = 0.2;
public Vector offect = Vector.build(0.25, 0.25);

public Area area;
public Area[][] areas;

public Vector grid;
public int nx, ny;

private CanCalc calc;

public Grid(Area _area, Vector _grid, CanCalc _calc, double _scale) {
this.area = _area;
this.grid = _grid;
this.calc = _calc;
this.scale = _scale;
}

public void draw(Graphics g) {

int x = (int)area.ld.x;
int y = (int)area.ld.y;
Vector t = area.ru.add(area.ld.neg());
int width = (int)t.x;
int height = (int)t.y;


g.drawRect(x, y, width, height);
g.drawLine(x, (int)offect.y, x+width, (int)offect.y);
g.drawLine((int)offect.x, y, (int)offect.x, y+height);
for(Area[] al : areas) {
for(Area a : al) {
g.drawLine((int)a.ld.x, (int)a.ld.y, (int)a.ru.x, (int)a.ru.y);
}
}
}

public void preDraw() {
offect = offect.dotMul(this.scale).add(Vector.build(-area.ld.x*scale, area.ru.y*scale));
area = new Area(Vector.build(area.ld.x, -area.ru.y).dotMul(this.scale).add(offect),
Vector.build(area.ru.x, -area.ld.x).dotMul(this.scale).add(offect));
for(int i=0; i for(int j=0; j Area tmp = areas[i][j];
Vector va = Vector.build(tmp.ld.x, -tmp.ld.y).dotMul(this.scale).add(offect);