加入收藏 | 设为首页 | 会员中心 | 我要投稿 东莞站长网 (https://www.0769zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

用Java达成一个向量场

发布时间:2021-11-23 15:28:42 所属栏目:教程 来源:互联网
导读:在学习微分方程的时候,以前也写过类似的文章,可是效果不行,前几天写了一个,感觉不错,分享之。 先看效果(x*x -y -2): 再来代码: package com.math.slopfields; import Java.awt.Color; import java.awt.Graphics; import javax.swing.JFrame; public

在学习微分方程的时候,以前也写过类似的文章,可是效果不行,前几天写了一个,感觉不错,分享之。
 
先看效果(x*x -y -2):
 
 
 
 
 
再来代码:
 
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<ny; i++){  
            for(int j=0; j<nx; j++) {  
                Area tmp = areas[i][j];  
                Vector va = Vector.build(tmp.ld.x, -tmp.ld.y).dotMul(this.scale).add(offect);  
                Vector vb = Vector.build(tmp.ru.x, -tmp.ru.y).dotMul(this.scale).add(offect);  
                areas[i][j] = new Area(va, vb);   
            }  
        }  
    }  
      
      
    private void fixArea() {  
        Vector tn1 = area.ld.dotDiv(grid).intVal().abs();  
        area.ld = grid.dotMul(tn1).neg();  
          
        Vector tn2 = area.ru.dotDiv(grid).intVal().abs();  
        area.ru = grid.dotMul(tn2);  
          
        tn1 = tn1.add(tn2);  
        nx = (int)tn1.x;  
        ny = (int)tn1.y;  
    }  
      
    private Slop[][] initSlop(CanCalc calc) {  
        fixArea();  
        Slop[][] slops = new Slop[nx][ny];  
          
        Vector now = area.ld.clone();  
        now.y += grid.y/2;  
        for(int i=0; i<ny; i++) {  
            now.x = area.ld.x + grid.x/2;  
            for(int j=0; j<nx; j++) {  
                slops[i][j] = new Slop(now.clone(), calc.doCalc(now));  
                now.x += grid.x;  
            }  
            now.y += grid.y;  
        }  
        return slops;  
    }  
      
    public Area[][] calcGrids() {  
        Slop[][] slops = initSlop(calc);  
        areas = new Area[nx][ny];  
        for(int i=0; i<nx; i++) {  
            for(int j=0; j<ny; j++) {  
                Vector tmp = null;  
                Slop s = slops[i][j];  
                if(s.slop == grid.slop()) {  
                    tmp = grid.dotDiv(2);  
                }else if(s.slop == -grid.slop()){  
                    tmp = grid.dotDiv(2).dotMul(Vector.dr);  
                }else if(s.slop==0){  
                    tmp = Vector.build(grid.x/2, 0);  
                }else if(s.slop<grid.slop() && s.slop>-grid.slop()) {  
                    tmp = Vector.build(grid.x/2, (grid.x/2)*s.slop);  
                }else {  
                    tmp = Vector.build((grid.y/2)/s.slop, grid.y/2);  
                }  
                tmp = tmp.dotMul(1-this.padding);  
                  
                areas[i][j] = new Area(s.point.add(tmp.neg()), s.point.add(tmp));  
            }  
        }  
        return areas;  
    }  
}  
  
interface CanCalc {  
    public double doCalc(Vector v);  
}  
  
class Slop{  
    public Vector point;  
    public double slop;  
    public Slop(Vector _point, double _slop) {  
        this.point = _point;  
        this.slop = _slop;  
    }  
    public String toString() {  
        return String.format("{%s, %.2f}", point, slop);  
    }  
}  
  
class Area {  
    public Vector ld;  
    public Vector ru;  
      
    public Area(Vector _ld, Vector _ru) {  
        this.ld = _ld;  
        this.ru = _ru;  
    }  
  
    public String toString() {  
        return String.format("[%s-%s]", this.ld, this.ru);  
    }  
      
    public Area scale(double d) {  
        return new Area(this.ld.dotMul(d), this.ru.dotMul(d));  
    }  
      
    public Area add(Vector v) {  
        return new Area(this.ld.add(v), this.ru.add(v));  
    }  
}  
  
  
  
class Vector {  
    public static final double infinite = Double.MAX_VALUE;  
      
    public double x;  
    public double y;  
  
    public static final Vector zero = Vector.build(0, 0);  
    public static final Vector up = Vector.build(0, 1);  
    public static final Vector down = Vector.build(0, -1);  
    public static final Vector left = Vector.build(-1, 0);  
    public static final Vector right = Vector.build(1, 0);  
    public static final Vector ul = Vector.build(-1, 1);  
    public static final Vector ur = Vector.build(1, 1);  
    public static final Vector dl = Vector.build(-1, -1);  
    public static final Vector dr = Vector.build(1, -1);  
      
    public static Vector build(double x, double y) {  
        return new Vector(x, y);  
    }  
      
    public Vector clone() {  
        return Vector.build(this.x, this.y);  
    }  
      
    public double slop() {  
        if(this.x == 0) {  
            return Vector.infinite;  
        }  
        return this.y / this.x;  
    }  
      
    public Vector(double _x, double _y) {  
        this.x = _x;  
        this.y = _y;  
    }  
      
    public Vector intVal() {  
        return new Vector((int)this.x, (int)this.y);  
    }  
      
    public Vector abs() {  
        return Vector.build((x>=0?x:-x), (y>=0?y:-y));  
    }  
      
    public Vector add(Vector v) {  
        return new Vector(this.x+v.x, this.y+v.y);  
    }  
      
    public Vector neg() {  
        return new Vector(-this.x, -this.y);  
    }  
      
    public Vector mul(double m) {  
        return new Vector(m*this.x, m*this.y);  
    }  
      
    public Vector dotMul(Vector m) {  
        return new Vector(this.x * m.x, this.y * m.y);  
    }  
    public Vector dotMul(double m) {  
        return Vector.build(this.x*m, this.y*m);  
    }  
      
    public Vector dotDiv(Vector m) {  
        return new Vector(this.x/m.x, this.y/m.y);  
    }  
      
    public Vector dotDiv(double d) {  
        return Vector.build(this.x/d, this.y/d);  
    }  
      
    public String toString() {  
        return String.format("<%.2f, %.2f>", x, y);  
    }  
      
}  
配置代码,可以查看不同的效果:
 
      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;  
    }  
      
};  

(编辑:东莞站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读