/*
	Autor:			Bernhard Preis
	MatrNr:			0200328
	
	Beschreibung:	Ein Farbwert im RGB-Farbwürfel (Rot, Grün, Blau je 256 Stufen) soll auf einen Farbwürfel mit 147 Farbwerten abgebildet werden. Dazu ist eine Bewertung der 8 Ecken des Teilquaders, in dem der Farbwert liegt, auszugeben.
*/

import java.lang.Math.*;


public class Cube{

	//es genügen die Koordinaten von zwei gegenüberliegenden Punkten um den Quader vollständig zu beschreiben.
	private int m_lowerX, m_lowerY, m_lowerZ, m_upperX, m_upperY, m_upperZ;

	//Konstruktor
	public Cube(int lowerX, int lowerY, int lowerZ, int upperX, int upperY, int upperZ){
		m_lowerX = lowerX;
		m_lowerY = lowerY;
		m_lowerZ = lowerZ;
		m_upperX = upperX;
		m_upperY = upperY;
		m_upperZ = upperZ;
	}
	
	//Konstruktor
	public Cube(Point3d lowerPoint, Point3d upperPoint){
		m_lowerX = (int)Math.round(lowerPoint.getX());
		m_lowerY = (int)Math.round(lowerPoint.getY());
		m_lowerZ = (int)Math.round(lowerPoint.getZ());
		m_upperX = (int)Math.round(upperPoint.getX());
		m_upperY = (int)Math.round(upperPoint.getY());
		m_upperZ = (int)Math.round(upperPoint.getZ());
	}
	
	//berechnet die Eckpunkte des Quaders.
	public Point3d[] getEdges(){
		Point3d[] edges = new Point3d[8];
		
		edges[0] = new Point3d(m_lowerX,m_lowerY,m_lowerZ);
		edges[1] = new Point3d(m_lowerX,m_lowerY,m_upperZ);
		edges[2] = new Point3d(m_lowerX,m_upperY,m_lowerZ);
		edges[3] = new Point3d(m_lowerX,m_upperY,m_upperZ);
		edges[4] = new Point3d(m_upperX,m_lowerY,m_lowerZ);
		edges[5] = new Point3d(m_upperX,m_lowerY,m_upperZ);
		edges[6] = new Point3d(m_upperX,m_upperY,m_lowerZ);
		edges[7] = new Point3d(m_upperX,m_upperY,m_upperZ);
		
		return edges;
	}		
	
	//bildet einen Punkt aus diesem Quader auf einen Punkt eines anderen Quaders ab.
	public Point3d convertToOtherCube(Point3d point,Cube otherCube){
		double factorX = (double) getLengthX() / otherCube.getLengthX();
		double factorY = (double) getLengthY() / otherCube.getLengthY();
		double factorZ = (double) getLengthZ() / otherCube.getLengthZ();
		
		return new Point3d(point.getX() / factorX,point.getY() / factorY,point.getZ() / factorZ);
	}
	
	//bestimmt in welchem Teilquader ein Punkt liegt.
	public int[] getSectorNumbers(Point3d point,Cube otherCube){
		int return_values[] = new int[3];
		
		Point3d newPoint = convertToOtherCube(point,otherCube);
		
		return_values[0] = (int) newPoint.getX() - (Math.floor(newPoint.getX())==(newPoint.getX())?(1):(0));
		return_values[1] = (int) newPoint.getY() - (Math.floor(newPoint.getY())==(newPoint.getY())?(1):(0));
		return_values[2] = (int) newPoint.getZ() - (Math.floor(newPoint.getZ())==(newPoint.getZ())?(1):(0));
		
		return return_values;
	}
	
	//berechnet die Abstände der Eckpunkte des Quaders zu einen Punkt und normiert sie.
	public double[] getNormedDistances(Point3d point){
		double distances[] = new double[8];
		
		Point3d myEdges[] = getEdges();
		
		double sum = 0;
		for(int i=0;i<8;i++){
			distances[i]=point.getDistance(myEdges[i]);
			sum+=distances[i];
		}
		for(int i=0;i<8;i++){
			distances[i]/=sum;
		}
		return distances;
	}

	//Wrapper-Funktionen
	public int getLengthX(){
		return m_upperX - m_lowerX;
	}
	public int getLengthY(){
		return m_upperY - m_lowerY;
	}
	public int getLengthZ(){
		return m_upperZ - m_lowerZ;
	}

}