由于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方面的,后来觉得要写的东西太多临时改主意了……