350 lines
11 KiB
Java
350 lines
11 KiB
Java
/*
|
|
* Author: Cedric Holzl - Mohamed Khadri
|
|
* Sciper: 257844 - 261203
|
|
*/
|
|
package ch.epfl.alpano;
|
|
|
|
import static ch.epfl.alpano.Preconditions.checkBounds;
|
|
import java.util.Arrays;
|
|
|
|
/**
|
|
* Panorama data holder computed using PanoramaComputer class using given
|
|
* panorama parameters
|
|
*
|
|
* @see PanoramaComputer
|
|
* @see PanoramaParameters
|
|
* @see Panorama.Builder
|
|
*/
|
|
public final class Panorama {
|
|
|
|
private final float[] distance;
|
|
private final float[] longitude;
|
|
private final float[] latitude;
|
|
private final float[] altitude;
|
|
private final float[] slope;
|
|
private final PanoramaParameters parameters;
|
|
|
|
/**
|
|
* Panorama constructor
|
|
*
|
|
* @param parameters
|
|
* : the PanoramaParameters
|
|
* @param distance
|
|
* : float table containing the distances
|
|
* @param longitude
|
|
* : float table containing the longitudes
|
|
* @param latitude
|
|
* : float table containing the latitudes
|
|
* @param altitude
|
|
* : float table containing the altitudes
|
|
* @param slope
|
|
* : float table containing the slopes
|
|
*/
|
|
private Panorama(PanoramaParameters parameters, float[] distance,
|
|
float[] longitude, float[] latitude, float[] altitude,
|
|
float[] slope) {
|
|
|
|
this.distance = distance;
|
|
this.longitude = longitude;
|
|
this.latitude = latitude;
|
|
this.altitude = altitude;
|
|
this.slope = slope;
|
|
this.parameters = parameters;
|
|
}
|
|
|
|
/**
|
|
* Returns the parameters of the panorama
|
|
*
|
|
* @return the PanoramaParameters of the panorama
|
|
*/
|
|
public PanoramaParameters parameters() {
|
|
return this.parameters;
|
|
}
|
|
|
|
/**
|
|
* Returns the distance given a certain index x,y
|
|
*
|
|
* @param x
|
|
* horizontal index
|
|
* @param y
|
|
* : vertical index
|
|
* @return the distance given x,y
|
|
* @throws IndexOutOfBoundsException
|
|
* if x or y are out of bounds
|
|
*/
|
|
public float distanceAt(int x, int y) {
|
|
checkBounds(parameters().isValidSampleIndex(x, y));
|
|
return this.distance[parameters().linearSampleIndex(x, y)];
|
|
}
|
|
|
|
/**
|
|
* Returns the distance given a certain index x,y
|
|
*
|
|
* @param x
|
|
* horizontal index
|
|
* @param y
|
|
* : vertical index
|
|
* @param d
|
|
* : the default distance
|
|
* @return the distance given x,y or the default distance if x or y are out
|
|
* of bounds
|
|
*/
|
|
public float distanceAt(int x, int y, float d) {
|
|
if (parameters().isValidSampleIndex(x, y))
|
|
return this.distance[parameters().linearSampleIndex(x, y)];
|
|
else
|
|
return d;
|
|
}
|
|
|
|
/**
|
|
* Returns the latitude given a certain index x,y
|
|
*
|
|
* @param x
|
|
* horizontal index
|
|
* @param y
|
|
* : vertical index
|
|
* @return the latitude given x,y
|
|
* @throws IndexOutOfBoundsException
|
|
* if x or y are out of bounds
|
|
*/
|
|
public float latitudeAt(int x, int y) {
|
|
checkBounds(parameters().isValidSampleIndex(x, y));
|
|
return this.latitude[parameters().linearSampleIndex(x, y)];
|
|
}
|
|
|
|
/**
|
|
* Returns the longitude given a certain index x,y
|
|
*
|
|
* @param x
|
|
* horizontal index
|
|
* @param y
|
|
* : vertical index
|
|
* @return the longitude given x,y
|
|
* @throws IndexOutOfBoundsException
|
|
* if x or y are out of bounds
|
|
*/
|
|
public float longitudeAt(int x, int y) {
|
|
checkBounds(parameters().isValidSampleIndex(x, y));
|
|
return this.longitude[parameters().linearSampleIndex(x, y)];
|
|
}
|
|
|
|
/**
|
|
* Returns the altitude given a certain index x,y
|
|
*
|
|
* @param x
|
|
* horizontal index
|
|
* @param y
|
|
* : vertical index
|
|
* @return the altitude given x,y
|
|
* @throws IndexOutOfBoundsException
|
|
* if x or y are out of bounds
|
|
*/
|
|
public float elevationAt(int x, int y) {
|
|
checkBounds(parameters().isValidSampleIndex(x, y));
|
|
return this.altitude[parameters().linearSampleIndex(x, y)];
|
|
}
|
|
|
|
/**
|
|
* Returns the slope given a certain index x,y
|
|
*
|
|
* @param x
|
|
* horizontal index
|
|
* @param y
|
|
* : vertical index
|
|
* @return the slope given x,y
|
|
* @throws IndexOutOfBoundsException
|
|
* if x or y are out of bounds
|
|
*/
|
|
public float slopeAt(int x, int y) {
|
|
checkBounds(parameters().isValidSampleIndex(x, y));
|
|
return this.slope[parameters().linearSampleIndex(x, y)];
|
|
}
|
|
|
|
/**
|
|
* Panorama Builder:
|
|
*
|
|
* Gathers data for a Panorama and builds it.
|
|
*
|
|
* @see Panorama
|
|
* @see PanoramaComputer
|
|
*/
|
|
public final static class Builder {
|
|
|
|
private float[] distance;
|
|
private float[] longitude;
|
|
private float[] latitude;
|
|
private float[] altitude;
|
|
private float[] slope;
|
|
private final PanoramaParameters parameters;
|
|
|
|
/**
|
|
* Constructor of a panorama builder
|
|
*
|
|
* @param pp
|
|
* : the panorama parameters
|
|
* @throws NullPointerException
|
|
* if the PanoramaParameters object is null
|
|
*/
|
|
public Builder(PanoramaParameters pp) {
|
|
|
|
this.parameters = pp;
|
|
int size = pp.width() * pp.height();
|
|
this.distance = new float[size];
|
|
this.longitude = new float[size];
|
|
this.latitude = new float[size];
|
|
this.altitude = new float[size];
|
|
this.slope = new float[size];
|
|
Arrays.fill(distance, Float.POSITIVE_INFINITY);
|
|
}
|
|
|
|
/**
|
|
* Enters the distance into the table at a given index
|
|
*
|
|
* @param x
|
|
* : horizontal index
|
|
* @param y
|
|
* : vertical index
|
|
* @param distance
|
|
* : the value to enter in the table
|
|
* @return the builder (itself)
|
|
* @throws IllegalStateException
|
|
* if the Panorama has already been created
|
|
* @throws IndexOutOfBoundsException
|
|
* if x or y are out of bounds
|
|
* @see checkBuilder
|
|
*/
|
|
public Builder setDistanceAt(int x, int y, float distance) {
|
|
checkBuilder();
|
|
checkBounds(this.parameters.isValidSampleIndex(x, y));
|
|
this.distance[this.parameters.linearSampleIndex(x, y)] = distance;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Enters the longitude into the table at a given index
|
|
*
|
|
* @param x
|
|
* : horizontal index
|
|
* @param y
|
|
* : vertical index
|
|
* @param longitude
|
|
* : the value to enter in the table
|
|
* @return the builder (itself)
|
|
* @throws IllegalStateException
|
|
* if the panorama has already been created
|
|
* @throws IndexOutOfBoundsException
|
|
* if x or y are out of bounds
|
|
* @see checkBuilder
|
|
*/
|
|
public Builder setLongitudeAt(int x, int y, float longitude) {
|
|
checkBuilder();
|
|
checkBounds(this.parameters.isValidSampleIndex(x, y));
|
|
this.longitude[this.parameters.linearSampleIndex(x, y)] = longitude;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Enters the latitude into the table at a given index
|
|
*
|
|
* @param x
|
|
* : horizontal index
|
|
* @param y
|
|
* : vertical index
|
|
* @param latitude
|
|
* : the value to enter in the table
|
|
* @return the builder (itself)
|
|
* @throws IllegalStateException
|
|
* if the panorama has already been created
|
|
* @throws IndexOutOfBoundsException
|
|
* if x or y are out of bounds
|
|
* @see checkBuilder
|
|
*/
|
|
public Builder setLatitudeAt(int x, int y, float latitude) {
|
|
checkBuilder();
|
|
checkBounds(this.parameters.isValidSampleIndex(x, y));
|
|
this.latitude[this.parameters.linearSampleIndex(x, y)] = latitude;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Enters the altitude into the table at a given index
|
|
*
|
|
* @param x
|
|
* : horizontal index
|
|
* @param y
|
|
* : vertical index
|
|
* @param elevation
|
|
* : the value to enter in the table
|
|
* @return the builder (itself)
|
|
* @throws IllegalStateException
|
|
* if the panorama has already been created
|
|
* @throws IndexOutOfBoundsException
|
|
* if x or y are out of bounds
|
|
* @see checkBuilder
|
|
*/
|
|
public Builder setElevationAt(int x, int y, float elevation) {
|
|
checkBuilder();
|
|
checkBounds(this.parameters.isValidSampleIndex(x, y));
|
|
this.altitude[this.parameters.linearSampleIndex(x, y)] = elevation;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Enters the slope into the table at a given index
|
|
*
|
|
* @param x
|
|
* : horizontal index
|
|
* @param y
|
|
* : vertical index
|
|
* @param slope
|
|
* : the value to enter in the table
|
|
* @return the builder (itself)
|
|
* @throws IllegalStateException
|
|
* if the panorama has already been created
|
|
* @throws IndexOutOfBoundsException
|
|
* if x or y are out of bounds
|
|
* @see checkBuilder
|
|
*/
|
|
public Builder setSlopeAt(int x, int y, float slope) {
|
|
checkBuilder();
|
|
checkBounds(this.parameters.isValidSampleIndex(x, y));
|
|
this.slope[this.parameters.linearSampleIndex(x, y)] = slope;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Creates and returns the panorama
|
|
*
|
|
* @return the panorama
|
|
* @throws IllegalStateException
|
|
* if the panorama has already been created
|
|
* @see checkBuilder
|
|
*/
|
|
public Panorama build() {
|
|
checkBuilder();
|
|
Panorama p = new Panorama(parameters, distance, longitude, latitude,
|
|
altitude, slope);
|
|
this.distance = null;
|
|
this.longitude = null;
|
|
this.latitude = null;
|
|
this.altitude = null;
|
|
this.slope = null;
|
|
return p;
|
|
}
|
|
|
|
/**
|
|
* Checks if the panorama has already been built
|
|
*
|
|
* @throws IllegalStateException
|
|
* if the panorama has already been created
|
|
*/
|
|
private void checkBuilder() {
|
|
if (!(distance != null && longitude != null && latitude != null
|
|
&& altitude != null && slope != null))
|
|
throw new IllegalStateException();
|
|
}
|
|
|
|
}
|
|
|
|
}
|