由于Java可以很轻易的完成比较复杂的数学运算,所以我们经常能看到物理领域的问题借助Java实现效果演示,下面我给出一个桌球碰撞的处理及绘制实例。
package org.test.mail;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Panel;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.p_w_picpath.BufferedImage;
/** *//**
* <p>
* Title: LoonFramework
* </p>
* <p>
* Description:Java桌球演示
* </p>
* <p>
* Copyright: Copyright (c) 2007
* </p>
* <p>
* Company: LoonFramework
* </p>
*
* @author chenpeng
* @email:[email]ceponline@yahoo.com.cn[/email]
* @version 0.1
*/
public class JavaBilliards extends Panel implements Runnable, MouseListener,
MouseMotionListener ...{
/** *//**
*
*/
private static final long serialVersionUID = -5019885590391523441L;
// 球
private double _ball;
// 缓存用背景
private Image _screen;
// 画布
private Graphics _graphics;
// 台桌
private Image _table;
private double c[];
private double d[];
private double e[];
private double f[];
private int countBall;
private int h;
private double i[];
private double j[];
private double k[];
private double l[];
private double m[];
private double n[];
private double o[];
private double p[];
private boolean q[];
private double r;
private int a;
private int u;
private int v;
private int w;
private int x;
private boolean y;
private int z;
private int A;
/** *//**
* 初始化
*
*/
public JavaBilliards() ...{
a = 0;
r = 10D;
z = 300;
A = 0;
setBounds(50, 50, 700, 350);
Frame frame = new Frame("Java桌球演示");
frame.add(this);
frame.setBounds(0, 0, 700, 380);
frame.setResizable(false);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() ...{
public void windowClosing(WindowEvent e) ...{
System.exit(0);
}
});
requestFocus();
initialize();
}
public void initialize() ...{
// 基础数据
base();
// 注入实例
immit();
// 缓存背景
_screen = new BufferedImage(this.getWidth(), this.getHeight(), 1);
// 背景图形
_graphics = _screen.getGraphics();
// 绘制台桌
makeTable();
// 设置监听
addMouseListener(this);
addMouseMotionListener(this);
// 启动
new Thread(this).start();
}
/** *//**
* 初始化数据
*
*/
public void base() ...{
// 球体
_ball = 16D;
c = (new double[] ...{ 40D, (double) (getWidth() - 40) });
d = (new double[] ...{ c[0], (double) getHeight() - c[0] });
e = (new double[] ...{ c[0] + 20D, (double) (getWidth() / 2), c[1] - 20D });
f = (new double[] ...{ d[0] + 20D, d[1] - 20D });
}
/** *//**
* 注入实例
*
*/
public void immit() ...{
countBall = 16;
i = new double[countBall];
j = new double[countBall];
k = new double[countBall];
l = new double[countBall];
m = new double[countBall];
n = new double[countBall];
o = new double[countBall];
p = new double[countBall];
q = new boolean[countBall];
// 打击对象
hitObject();
// 打击用球
hitBall();
}
/** *//**
* 打击用球数值
*
*/
public void hitBall() ...{
i[0] = (1.0D * (e[2] - e[0])) / 3D;
j[0] = this.getHeight() / 2;
k[0] = 0.0D;
l[0] = 0.0D;
q[0] = true;
}
/** *//**
* 打击对象
*
*/
public void hitObject() ...{
int il = 1;
h = countBall - 1;
// 求平方根
double dl = Math.sqrt(3.5D);
for (int j1 = 0; j1 < 5; j1++) ...{
double d2 = ((double) getWidth() * 2D) / 3D + (double) j1 * dl * r;
double d3 = (double) (getHeight() / 2) - (double) j1 * r;
for (int k1 = 0; k1 <= j1; k1++) ...{
i[il] = d2;
j[il] = d3;
k[il] = 0.0D;
l[il] = 0.0D;
q[il] = true;
d3 += 2D * r;
il++;
}
}
}
这么点代码居然不能一次都发了……
/** *//**
* 绘制台球桌
*
*/
public void makeTable() ...{
_table = new BufferedImage(this.getWidth(), this.getHeight(), 1);
Graphics g = _table.getGraphics();
g.setColor(Color.GRAY);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor((new Color(200, 100, 50)).darker());
g.fill3DRect((int) c[0], (int) d[0], (int) (c[1] - c[0]),
(int) (d[1] - d[0]), true);
g.setColor(Color.BLACK);
g.fill3DRect((int) e[0], (int) f[0], (int) (e[2] - e[0]),
(int) (f[1] - f[0]), false);
g.setColor(Color.GREEN.darker());
g.drawLine((int) ((1.0D * (e[2] - e[0])) / 3D), (int) f[0],
(int) ((1.0D * (e[2] - e[0])) / 3D), (int) f[1]);
g.fillOval((int) ((1.0D * (e[2] - e[0])) / 3D) - 2,
(int) ((f[1] + f[0]) / 2D) - 2, 4, 4);
g.drawArc((int) ((1.0D * (e[2] - e[0])) / 3D) - 20,
(int) ((f[1] + f[0]) / 2D) - 20, 40, 40, 90, 180);
g.setColor(Color.BLACK);
double d1 = _ball - 2D;
for (int i1 = 0; i1 < 3; i1++) ...{
for (int j1 = 0; j1 < 2; j1++) ...{
g.fillOval((int) (e[i1] - d1), (int) (f[j1] - d1),
(int) (2D * d1), (int) (2D * d1));
}
}
}
/** *//**
* 线程处理
*/
public void run() ...{
long timeStart;
timeStart = System.currentTimeMillis();
// 死循环反复处理
for (;;) ...{
long timeEnd = System.currentTimeMillis();
switch (a) ...{
default:
break;
case 1:
// 根据时间换算运动轨迹
conversion(timeEnd - timeStart);
// 过程处理
course();
break;
case 2:
conversion(timeEnd - timeStart);
// 过程处理
course();
boolean flag = true;
for (int i1 = 0; flag && i1 < countBall; i1++)
flag = k[i1] == 0.0D && l[i1] == 0.0D;
if (flag) ...{
a = 1;
// 击球
if (!q[0]) ...{
hitBall();
}
}
if (h == 0)
a = 3;
break;
case 3:
hitObject();
hitBall();
a = 0;
break;
}
repaint();
timeStart = timeEnd;
try ...{
Thread.sleep(10L);
} catch (InterruptedException e1) ...{
e1.printStackTrace();
}
}
}
public void course() ...{
// 限制区域
limit();
// 入袋处理
pocket();
// 运动演算
play();
for (int i1 = 0; i1 < countBall; i1++)
if (q[i1]) ...{
i[i1] = m[i1];
j[i1] = n[i1];
}
}
/** *//**
* 变换时间为动作数据
*
* @param value
*/
public void conversion(long value) ...{
double d1 = (double) value / 1000D;
for (int i1 = 0; i1 < countBall; i1++)
if (q[i1]) ...{
m[i1] = i[i1] + k[i1] * d1;
n[i1] = j[i1] + l[i1] * d1;
k[i1] *= 0.98999999999999999D;
l[i1] *= 0.98999999999999999D;
if (Math.abs(Math.hypot(k[i1], l[i1])) < 2D) ...{
k[i1] = 0.0D;
l[i1] = 0.0D;
}
}
}
public void pocket() ...{
for (int i1 = 0; i1 < countBall; i1++)
if (q[i1]) ...{
for (int j1 = 0; j1 < 3; j1++) ...{
for (int k1 = 0; k1 < 2; k1++)
if (Math.hypot(e[j1] - i[i1], f[k1] - j[i1]) < _ball) ...{
q[i1] = false;
if (i1 != 0) ...{
h--;
}
k[i1] = 0.0D;
l[i1] = 0.0D;
}
}
}
}
public void play() ...{
for (int i1 = 0; i1 < countBall; i1++)
if (q[i1]) ...{
for (int j1 = i1 + 1; j1 < countBall; j1++) ...{
boolean flag;
if (q[j1] && (flag = randball(i1, j1))) ...{
for (int k1 = 0; k1 < 10 && flag; k1++) ...{
m[i1] = (m[i1] + i[i1]) / 2D;
n[i1] = (n[i1] + j[i1]) / 2D;
m[j1] = (m[j1] + i[j1]) / 2D;
n[j1] = (n[j1] + j[j1]) / 2D;
flag = randball(i1, j1);
}
if (flag) ...{
m[i1] = i[i1];
n[i1] = j[i1];
m[j1] = i[j1];
n[j1] = j[j1];
}
double d1 = m[j1] - m[i1];
double d2 = n[j1] - n[i1];
double d3 = Math.hypot(m[i1] - m[j1], n[i1] - n[j1]);
double d4 = d1 / d3;
double d5 = d2 / d3;
o[j1] = k[j1] - k[j1] * d4 * d4;
o[j1] -= l[j1] * d4 * d5;
o[j1] += k[i1] * d4 * d4;
o[j1] += l[i1] * d4 * d5;
p[j1] = l[j1] - l[j1] * d5 * d5;
p[j1] -= k[j1] * d4 * d5;
p[j1] += k[i1] * d4 * d5;
p[j1] += l[i1] * d5 * d5;
o[i1] = k[i1] - k[i1] * d4 * d4;
o[i1] -= l[i1] * d4 * d5;
o[i1] += k[j1] * d4 * d4;
o[i1] += l[j1] * d4 * d5;
p[i1] = l[i1] - l[i1] * d5 * d5;
p[i1] -= k[i1] * d4 * d5;
p[i1] += k[j1] * d4 * d5;
p[i1] += l[j1] * d5 * d5;
k[i1] = o[i1];
l[i1] = p[i1];
k[j1] = o[j1];
l[j1] = p[j1];
}
}
}
}
public boolean randball(int i1, int j1) ...{
// hypot随机决定两值之一
return Math.hypot(m[i1] - m[j1], n[i1] - n[j1]) < 2D * r;
}
/** *//**
* 限制区域
*
*/
public void limit() ...{
for (int i = 0; i < countBall; i++)
if (q[i]) ...{
if (m[i] - r < e[0]) ...{
m[i] = e[0] + r;
k[i] *= -1D;
} else if (m[i] + r > e[2]) ...{
m[i] = e[2] - r;
k[i] *= -1D;
}
if (n[i] - r < f[0]) ...{
n[i] = f[0] + r;
l[i] *= -1D;
} else if (n[i] + r > f[1]) ...{
n[i] = f[1] - r;
l[i] *= -1D;
}
}
}
public void makeScreen(Graphics screenGraphics) ...{
screenGraphics.drawImage(_table, 0, 0, null);
if (q[0]) ...{
_graphics.setColor(Color.WHITE);
_graphics.fillOval((int) (i[0] - r), (int) (j[0] - r),
(int) (r * 2D), (int) (r * 2D));
}
screenGraphics.setColor(Color.RED);
for (int i1 = 1; i1 < countBall; i1++)
if (q[i1])
screenGraphics.fillOval((int) (i[i1] - r), (int) (j[i1] - r),
(int) (r * 2D), (int) (r * 2D));
screenGraphics.setColor(Color.BLACK);
for (int j1 = 0; j1 < countBall; j1++)
if (q[j1]) ...{
screenGraphics.drawOval((int) (i[j1] - r), (int) (j[j1] - r),
(int) (r * 2D), (int) (r * 2D));
}
if (a == 1)...{
makeHelper(screenGraphics);
}
if (a == 0) ...{
int k1 = getWidth() / 2 - 85;
int l1 = getHeight() / 2;
screenGraphics.setColor(Color.BLACK);
screenGraphics.drawString("点击画面开始", k1 + 2, l1 + 2);
if ((System.currentTimeMillis() / 1000L & 1L) == 0L)...{
screenGraphics.setColor(Color.YELLOW);
}
else...{
screenGraphics.setColor(Color.CYAN);
}
screenGraphics.drawString("点击画面开始", k1, l1);
}
}
/** *//**
* 绘制球杆及辅助线
*
* @param screenGraphics
*/
public void makeHelper(Graphics screenGraphics) ...{
double d1 = Math.hypot(i[0] - (double) u, j[0] - (double) v);
double d2 = ((double) u - i[0]) / d1;
double d3 = ((double) v - j[0]) / d1;
double d4 = y ? n() / 10D : 1.0D;
double d5 = i[0] + d2 * (r + d4);
double d6 = i[0] + d2 * (r + (double) z + d4);
double d7 = j[0] + d3 * (r + d4);
double d8 = j[0] + d3 * (r + (double) z + d4);
screenGraphics.setColor(Color.ORANGE);
screenGraphics.drawLine((int) d5, (int) d7, (int) d6, (int) d8);
int i1 = 0;
int j1 = y ? (int) (150D * (d4 / 1000D)) : 15;
double d9;
double d10 = (d9 = 30D) * d2;
double d11 = d9 * d3;
double d12 = i[0] + (double) A * d2;
double d13 = j[0] + (double) A * d3;
A--;
A %= d9;
screenGraphics.setColor(Color.WHITE);
for (; i1 < j1; i1++) ...{
if (d12 < e[0]) ...{
d12 = e[0] - d12;
d12 = e[0] + d12;
d10 *= -1D;
} else if (d12 > e[2]) ...{
d12 -= e[2];
d12 = e[2] - d12;
d10 *= -1D;
}
if (d13 < f[0]) ...{
d13 = f[0] - d13;
d13 = f[0] + d13;
d11 *= -1D;
} else if (d13 > f[1]) ...{
d13 -= f[1];
d13 = f[1] - d13;
d11 *= -1D;
}
screenGraphics.fillOval((int) d12 - 2, (int) d13 - 2, 4, 4);
d12 -= d10;
d13 -= d11;
}
}
public double n() ...{
if (y) ...{
return Math.min(1000D, 10D * Math.hypot(i[0] - (double) w, j[0]
- (double) x));
} else ...{
return Math.min(1000D, 10D * Math.hypot(u - w, v - x));
}
}
public void update(Graphics g) ...{
paint(g);
}
public void paint(Graphics g) ...{
makeScreen(_graphics);
g.drawImage(_screen, 0, 0, null);
}
public void mousePressed(MouseEvent mouseevent) ...{
y = true;
}
public void mouseReleased(MouseEvent mouseevent) ...{
if (a == 1) ...{
double d1 = Math.hypot(i[0] - (double) u, j[0] - (double) v);
double d2 = (i[0] - (double) u) / d1;
double d3 = (j[0] - (double) v) / d1;
double d4;
if ((d4 = n()) > 0.0D) ...{
a = 2;
k[0] = d4 * d2;
l[0] = d4 * d3;
}
}
y = false;
}
public void mouseClicked(MouseEvent mouseevent) ...{
if (a == 0)
a = 1;
}
public void mouseEntered(MouseEvent mouseevent) ...{
}
public void mouseExited(MouseEvent mouseevent) ...{
}
public void mouseMoved(MouseEvent mouseevent) ...{
w = mouseevent.getX();
x = mouseevent.getY();
u = w;
v = x;
}
public void mouseDragged(MouseEvent mouseevent) ...{
w = mouseevent.getX();
x = mouseevent.getY();
}
public static void main(String args[]) ...{
new JavaBilliards();
}
}
运行结果如下:
PS:本来今天想写个关于javamail方面的,后来觉得要写的东西太多临时改主意了……