public Scene(int width, int height, int num_photons_per_light, double exposure) { super(width, height); initialize_geometry(); initialize_lights(); if (geometries == null) { throw new Error("ERROR: geometries needs to be initialized."); } if (lights == null) { throw new Error("ERROR: lights needs to be initialized."); } // Calculate the Irradiance. irradiance = new IrradianceCache(width, height); int GRANULARITY = 10000; int numLights = lights.length; for (int light = 0; light < numLights; light++) { System.out.println("Light " + light); current_light = lights[light]; for (int j = 0; j < num_photons_per_light; j++) { if (j % GRANULARITY == (GRANULARITY - 1)) System.out.println("" + (j + 1) / GRANULARITY + " * " + GRANULARITY + " beams done."); shootPhoton(); } } irradiance.scale_exposure(exposure); }
@Override public Color getColor(double x, double y) { return irradiance.getColor(x, y); }
// Helps to reconfigure the coordinates. // Returns the total attenuation. private double light_line_helper( double x1, double x2, double y1, double y2, boolean rotated, boolean invert1, photonColor photon_start) { // Left End point calculations. int x1_int = (int) x1; int y1_int = (int) y1; double per_x1_c = x1 - x1_int; double per_y1_c = y1 - y1_int; double per_x1 = 1 - per_x1_c; double per_y1 = 1 - per_y1_c; double scalar_1 = per_x1 * per_y1; irradiance.addIrradiance(x1_int, y1_int, photon_start, scalar_1, rotated); scalar_1 = per_x1 * per_y1_c; irradiance.addIrradiance(x1_int, y1_int + 1, photon_start, scalar_1, rotated); // Right End point calculations. int x2_int = (int) x2; int y2_int = (int) y2; double per_x2_c = x2 - x2_int; double per_y2_c = y2 - y2_int; double per_y2 = 1 - per_y2_c; double scalar_2 = per_x2_c * per_y2_c; irradiance.addIrradiance(x2_int + 1, y2_int + 1, photon_start, scalar_2, rotated); scalar_2 = per_x2_c * per_y2; irradiance.addIrradiance(x2_int + 1, y2_int, photon_start, scalar_2, rotated); // Draw the main body. // ASSERT this is positive. double dx = x2 - x1; double dy = y2 - y1; double distance = BryceMath.distance(x1, y1, x2, y2); for (int x = x1_int + 1; x <= x2_int; x++) { double percentage = (x - x1) / dx; double y = y1 + dy * percentage; int y_int = (int) y; double per_y_c = y - y_int; double per_y = 1 - per_y_c; // An within pixel accuracy approximation for the attenuation. // For more prescision, use the actual distance. double partial_distance = invert1 ? (1 - percentage) * distance : percentage * distance; double attenuation = current_light.attenuation(partial_distance); irradiance.addIrradiance(x, y_int, photon_start, per_y * attenuation, rotated); irradiance.addIrradiance(x, y_int + 1, photon_start, per_y_c * attenuation, rotated); } return current_light.attenuation(distance); }