private void photonHitAtom() {
		if (photons == null || photons.isEmpty())
			return;
		Photon p;
		double s2;
		List<Photon> tmpList = null;
		double dx, dy;
		for (int k = 0; k < numberOfAtoms; k++) {
			if (photons.isEmpty())
				break; // no more photons
			s2 = atom[k].sigma * atom[k].sigma * 0.25;
			synchronized (photons) {
				for (Iterator it = photons.iterator(); it.hasNext();) {
					p = (Photon) it.next();
					dx = p.x - atom[k].rx;
					dy = p.y - atom[k].ry;
					if (dx * dx + dy * dy < s2) {
						if (photonicExcitor == null)
							photonicExcitor = new PhotonicExcitor(this);
						Photon p2 = photonicExcitor.interact(p, atom[k]);
						if (p2 == p) {
							p.setModel(null);
							it.remove();
							notifyModelListeners(new ModelEvent(this, "Photon absorbed", null, p));
						} else if (p2 != null) {
							if (tmpList == null)
								tmpList = new ArrayList<Photon>();
							tmpList.add(p2);
							// notifyModelListeners(new ModelEvent(this, "Photon emitted", null, p2));
							// postone to be handled by RectangularBoundary when the photon exits
						} else {
							// the photon wasn't absorbed. Should it shine through, or should it be scattered?
							if (Math.random() < quantumRule.getScatterProbability())
								p.setAngle((float) (p.getAngle() + Math.PI * (1 + 0.2 * (0.5 - Math.random()))));
						}
					}
				}
				if (tmpList != null) {
					photons.addAll(tmpList);
					tmpList.clear();
				}
			}
		}
	}