算法4第6章碰撞检测实现

这个博客介绍了如何采用事件驱动模型来模拟小球的碰撞。通过预测所有可能的碰撞事件并存储到优先队列中,当碰撞发生时,重新计算小球的速度和方向,并更新可能的碰撞事件。此外,还设置了重绘事件来模拟时钟和更新小球位置。博客中包含了一个名为`CollisionSystem`的类,用于处理碰撞系统,包括小球与小球、小球与墙的碰撞检测以及碰撞后的速度调整。
摘要由CSDN通过智能技术生成

 碰撞检测
 采用事件驱动模型来模拟小球的运动及碰撞,首先预测所有的碰撞事件,按碰撞时间存入优先队列,
 碰撞发生时重新计算发生碰撞的小球的速度,方向,重新预测该小球可能发生的的碰撞事件存入优先队列
 同时定义一个重复的事件存入优先队列,用来模拟时钟及重绘每个小球的位置。
 遍历优先队列模型小球的运动和碰撞,示意图如下:
public class CollisionSystem {
    private static final double HZ = 0.5;    // number of redraw events per clock tick

    private MinPQ<Event> pq;          // the priority queue
    private double t  = 0.0;          // simulation clock time
    private Particle[] particles;     // the array of particles

    /**
     * Initializes a system with the specified collection of particles.
     * The individual particles will be mutated during the simulation.
     *
     * @param  particles the array of particles
     */
    public CollisionSystem(Particle[] particles) {
        this.particles = particles.clone();   // defensive copy
    }

    // updates priority queue with all new events for particle a
    //预测可能与小球a发生的所有碰撞事件存入优先队列
    private void predict(Particle a, double limit) {
        if (a == null) return;

        // particle-particle collisions
        for (int i = 0; i < particles.length; i++) {
            //预测小球a与小球particles[i]发生碰撞的时间,如果时间有效存入优先队列
            double dt = a.timeToHit(particles[i]);
            if (t + dt <= limit)
                pq.insert(new Event(t + dt, a, particles[i]));
        }

        // particle-wall collisions
        //预测小球与墙发生碰撞的时间,如果时间有效存入优先队列
        double dtX = a.timeToHitVerticalWall();
        double dtY = a.timeToHitHorizontalWall();
        if (t + dtX <= limit) pq.insert(new Event(t + dtX, a, null));
        if (t + dtY <= limit) pq.insert(new Event(t + dtY, null, a));
    }

    // redraw all particles
    private void redraw(double limit) {
        StdDraw.clear();
        for (int i = 0; i < particles.length; i++) {
            particles[i].draw();
        }
        StdDraw.show();
        StdDraw.pause(20);
        if (t < limit) {
            pq.insert(new Event(t + 1.0 / HZ, null, null));
        }
    }

      
    /**
     * Simulates the system of particles for the specified amount of time.
     *
     * @param  limit the amount of time
     */
    public void simulate(double limit) {
        
        // initialize PQ with collision events and redraw event
        pq = new MinPQ<Event>();
        //预测每个小球可能的碰撞事件
        for (int i = 0; i < particles.length; i++) {
            predict(particles[i], limit);
        }
        //模拟时钟,重绘小球位置
        pq.insert(new Event(0, null, null));        // redraw event


        // the main event-driven simulation loop
        while (!pq.isEmpty()) {

            // get impending event, discard if invalidated
            Event e = pq.delMin();
            if (!e.isValid()) continue;
            Particle a = e.a;
            Particle b = e.b;

            // physical collision, so update positions, and then simulation clock
            for (int i = 0; i < particles.length; i++)
                particles[i].move(e.time - t); //移动小球的位置
            t = e.time;

            // process event
            if      (a != null &

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值