vector<Particle> Lightcone::getSegment(Snapshot& snap, double rMax,
		double rMin) {
	printf("Generating segment (rMax, rMin) (%.0f, %.0f) . . . \n", rMax, rMin);
	vector<Particle> inSegment;
	// First find the observer collision box
	// Define the 8 points that enclose the lightcone in rotated reference frame
	vector<Particle> points;
	double d = rMax * tan(mOpening);
	//	// correction to d
	//	if (d > rMax) {
	//		d = rMax;
	//	}
	double dp = rMin * sin(mOpening);
	double rp = rMin * cos(mOpening);
	//printf("d:d':r' (%.0f:%.0f:%.0f)\n", d, dp, rp);
	points.push_back(Particle(-d, -d, rMax));
	points.push_back(Particle(-d, d, rMax));
	points.push_back(Particle(d, -d, rMax));
	points.push_back(Particle(d, d, rMax));
	points.push_back(Particle(-dp, -dp, rp));
	points.push_back(Particle(-dp, dp, rp));
	points.push_back(Particle(dp, -dp, rp));
	points.push_back(Particle(dp, dp, rp));
	reverseRotation(points);
	shiftPointsByObserver(points, true);
	Box obsBox = makeBoxFromParticles(points);

	// Full sky map
	if (mOpening > M_PI / 2) {
		obsBox = Box(mObserver.x - rMax, mObserver.y - rMax, mObserver.z - rMax,
				2 * rMax);
	}

	printf(
			"Original Observer box at [%.2f, %.2f, %.2f] with size [%.2f, %.2f, %.2f], ",
			obsBox.x, obsBox.y, obsBox.z, obsBox.w, obsBox.h, obsBox.d);
	// Calculate the offset range need in each direction
	int xOffMin, xOffMax, yOffMin, yOffMax, zOffMin, zOffMax;
	xOffMin = (obsBox.x / BOX_WIDTH) - 1;
	xOffMax = ((obsBox.x + obsBox.w) / BOX_WIDTH) + 1;
	//	printf("x Offset (Min:Max)(%d:%d) \n", xOffMin, xOffMax);

	yOffMin = (obsBox.y / BOX_WIDTH) - 1;
	yOffMax = ((obsBox.y + obsBox.h) / BOX_WIDTH) + 1;
	//	printf("y Offset (Min:Max)(%d:%d) \n", yOffMin, yOffMax);

	zOffMin = (obsBox.z / BOX_WIDTH) - 1;
	zOffMax = ((obsBox.z + obsBox.d) / BOX_WIDTH) + 1;
	//	printf("z Offset (Min:Max)(%d:%d) \n", zOffMin, zOffMax);

	// Create snapshot boxes from offset and test if they collide with segment
	vector<Particle> validOffsets;
	for (int i = xOffMin; i <= xOffMax; i++) {
		for (int j = yOffMin; j <= yOffMax; j++) {
			for (int k = zOffMin; k <= zOffMax; k++) {
				// Create the box
				Box virtualSnap = Box(i * BOX_WIDTH, j * BOX_WIDTH,
						k * BOX_WIDTH, BOX_WIDTH);
				if (collide(obsBox, virtualSnap)) {
					validOffsets.push_back(Particle(i, j, k));
				}
			}
		}
	}
	printf("%lu boxes are required.\n", validOffsets.size());

	// Check lightcone
	inSegment = snap.getCone(rMax, rMin, mTheta, mPhi, mOpening, mObserver,
			validOffsets);

	if (inSegment.size() == 0) {
		printf("[Error] Segment returns 0 particles!\n");
	}
	printf(" Segment Size: %lu\n", inSegment.size());
	return inSegment;
}