package org.openpixi.pixi.physics.collision.detectors; import org.openpixi.pixi.physics.*; import org.openpixi.pixi.physics.collision.util.*; import org.openpixi.pixi.physics.particles.Particle; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.Map.Entry; public class SweepAndPrune extends Detector{ private ArrayList<Pair<Particle, Particle>> overlappedPairs = new ArrayList<Pair<Particle, Particle>>(); private ArrayList<BoundingBox> boxlist = new ArrayList<BoundingBox>(); private ArrayList<SweepParticle> axisX = new ArrayList<SweepParticle>(); private ArrayList<SweepParticle> axisY = new ArrayList<SweepParticle>(); private ArrayList<Pair<BoundingBox, BoundingBox>> overlaps = new ArrayList<Pair<BoundingBox, BoundingBox>>(); //private ArrayList<Pair<Particle2D, Particle2D>> overlappedPairs = new ArrayList<Pair<Particle2D, Particle2D>>(); private Map<Pair<BoundingBox, BoundingBox>, OverlapCounter> overlapCounter = new HashMap<Pair<BoundingBox, BoundingBox>, OverlapCounter>(); //constructor public SweepAndPrune(ArrayList<Particle> parlist) { boxlist.clear(); axisX.clear(); axisY.clear(); overlaps.clear(); overlappedPairs.clear(); overlapCounter.clear(); for(int i = 0; i < parlist.size(); i++) { Particle par = (Particle) parlist.get(i); BoundingBox box = new BoundingBox(par); if(!boxlist.contains(box)) { boxlist.add(box); axisX.add(new SweepParticle(box, 0, true)); axisX.add(new SweepParticle(box, 0, false)); axisY.add(new SweepParticle(box, 1, true)); axisY.add(new SweepParticle(box, 1, false)); //System.out.println("Particles added"); } } } //adding a method for sorting the lists private void sortList(ArrayList<SweepParticle> list) { for(int i = 1; i < list.size(); i++) { SweepParticle sweepPar = list.get(i); double sweepParValue = sweepPar.updateGetValue(); int j = i - 1; while(j >= 0 && (list.get(j).updateGetValue() > sweepParValue)) { SweepParticle swapPar = list.get(j); //creating a pair of the possibly overlapping particles Pair<BoundingBox, BoundingBox> pairbox = new Pair<BoundingBox, BoundingBox>(sweepPar.bb, swapPar.bb); if(sweepPar.begin && !swapPar.begin) { //setting them into a list if(overlapCounter.containsKey(pairbox)) { overlapCounter.get(pairbox).overlaps++; } else { OverlapCounter newOverlapCounter = new OverlapCounter(); newOverlapCounter.overlaps = 1; overlapCounter.put(pairbox, newOverlapCounter); } } if(!sweepPar.begin && swapPar.begin) { if(overlapCounter.containsKey(pairbox)) { overlapCounter.get(pairbox).overlaps--; } } list.set(j + 1, swapPar); j = j - 1; } list.set(j + 1, sweepPar); //System.out.println("Particles swapped"); } } public void run() { //sorting the axes lists sortList(axisX); sortList(axisY); //System.out.println("Axes sorted"); //one needs to look at the counters (similar like with the remove method) Iterator<Entry<Pair<BoundingBox, BoundingBox>, OverlapCounter>> iterator = overlapCounter.entrySet().iterator(); while(iterator.hasNext()) { Entry<Pair<BoundingBox, BoundingBox>, OverlapCounter> entry = iterator.next(); OverlapCounter counter = entry.getValue(); Pair<BoundingBox, BoundingBox> pairbox = entry.getKey(); //System.out.println(counter.overlaps); if(counter.overlappedBoolean) { if(counter.overlaps < 2) { overlaps.remove(pairbox); counter.overlappedBoolean = false; } else if (counter.overlaps > 1) { } } else { if(counter.overlaps > 1) { overlaps.add(pairbox); counter.overlappedBoolean = true; } } if(counter.overlaps < 1) { iterator.remove(); } } } public ArrayList<Pair<Particle, Particle>> getOverlappedPairs() { overlappedPairs.clear(); for(int i = 0; i < overlaps.size(); i++) { BoundingBox box1 = (BoundingBox) overlaps.get(i).getFirst(); BoundingBox box2 = (BoundingBox) overlaps.get(i).getSecond(); Pair<Particle, Particle> pairpar = new Pair<Particle, Particle>(box1.particle, box2.particle); overlappedPairs.add(pairpar); } return overlappedPairs; } }