RayTracer Geometrie Farbe, AxisAllignedBox

Hallo, ich habe bei einer wichtigen Aufgabe 2 Probleme.

Das erste Problem besteht darin das meine Sphere das Phongmaterial nicht mit ausgeben möchte. Die Skalierung funktioniert hier einwandfrei. Nur leider verstehe ich nicht warum sie nur das SingleColorMaterial akzeptiert. :confused: Ich habe schon versucht bei der Ausgabe der neuen Geometrie Node das Phongmaterial zu übergeben, leider genauso erfolglos. Vielleicht könnt ihr mir ja helfen? :slight_smile:

Die Klasse Node:

package raytracer.geometry;

import java.util.ArrayList;
import java.util.List;

import raytracer.material.Material;
import raytracer.math.Normal3;
import raytracer.math.Ray;
import raytracer.math.Transform;

public class Node extends Geometry{

	Transform t;
	List<Geometry> geoList;
	
	public Node(final Material material, final Transform t, final List<Geometry> geoList) {
		super(material);
		this.t = t;
		this.geoList = geoList;
	}

	@Override
	public Hit hit(Ray r) {
		Ray tempRay = t.mul(r);
		Hit tempHit;
		ArrayList<Hit> hitList = new ArrayList<>();
		
		for (Geometry g : this.geoList) {
			if(g.hit(tempRay) != null)
				hitList.add(g.hit(tempRay));
		}
		
		//if hitList is empty, return null as to apply background color later
		if (hitList.isEmpty()){
			return null;
		}
		
		
		tempHit = hitList.get(0);
		for (Hit h : hitList) 
			if (h.t < tempHit.t) 
				tempHit = h;
		
		Normal3 tempNormal = t.mul(tempHit.normal);
		return new Hit(tempHit.t, r, tempHit.geo, tempNormal);
		
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result + ((geoList == null) ? 0 : geoList.hashCode());
		result = prime * result + ((t == null) ? 0 : t.hashCode());
		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!super.equals(obj))
			return false;
		if (!(obj instanceof Node))
			return false;
		Node other = (Node) obj;
		if (geoList == null) {
			if (other.geoList != null)
				return false;
		} else if (!geoList.equals(other.geoList))
			return false;
		if (t == null) {
			if (other.t != null)
				return false;
		} else if (!t.equals(other.t))
			return false;
		return true;
	}
	
	

}

Die Klasse Sphere:

package raytracer.geometry;

import raytracer.material.Material;
import raytracer.math.Point3;
import raytracer.math.Ray;

/**
 * 
 * The Sphere-Class
 * @author Nicky
 * @author Vincent
 *
 */
public class Sphere extends Geometry {

	/**
	 * the center of the Sphere
	 */
	final Point3 c;
	
	/**
	 * the radius
	 */
	final Double d;
	
   
	/**
	 * constructor
	 * @param color the color of the Sphere
	 * @param c the center of the Sphere
	 * @param d the radius
	 */
	public Sphere(final Material material, final Point3 c, final Double d) {
		super(material);
		
		this.c = c; // Ursprung der Spere
		this.d = d; // Radius der Sphere
	}
	
	public Sphere(final Material material){
		super(material);
		this.c = new Point3(0.0, 0.0, 0.0);
		this.d = 1.0;
	}

	/**
	 * returns the Hit with a ray
	 */
	public Hit hit(final Ray r) {
		double t1, t2, D, a, b, c;
		a = r.d.dot(r.d);
		b = r.d.dot(r.o.sub(this.c).mul(2));
		c = ((r.o.sub(this.c).dot(r.o.sub(this.c))) - (this.d * (this.d)));
		D = b * b - 4 * a * c;

		if (D < 0) 
			return null;
		
		t1 = (-b + Math.sqrt(D)) / 2 * a;
		t2 = (-b - Math.sqrt(D)) / 2 * a;
		
		/**
		 * the smaller t will be returned and must be greater than 0
		 */
		if((t1 < t2) && t1 > 0)
			return new Hit (t1, r, this, r.at(t1).sub(this.c).normalized().asNormal());
		else if (t2>0)
			return new Hit (t2, r, this,r.at(t2).sub(this.c).normalized().asNormal());
		return null;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result + ((c == null) ? 0 : c.hashCode());
		result = prime * result + ((d == null) ? 0 : d.hashCode());
		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!super.equals(obj))
			return false;
		if (!(obj instanceof Sphere))
			return false;
		Sphere other = (Sphere) obj;
		if (c == null) {
			if (other.c != null)
				return false;
		} else if (!c.equals(other.c))
			return false;
		if (d == null) {
			if (other.d != null)
				return false;
		} else if (!d.equals(other.d))
			return false;
		return true;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "Sphere [c=" + c + ", d=" + d + "]";
	}
}

Die Klasse Mat4x4:

package raytracer.math;

public class Mat4x4 {

	final public double m11;
	final public double m12;
	final public double m13;
	final public double m14;
	final public double m21;
	final public double m22;
	final public double m23;
	final public double m24;
	final public double m31;
	final public double m32;
	final public double m33;
	final public double m34;
	final public double m41;
	final public double m42;
	final public double m43;
	final public double m44;


	/**
	 * constructor
	 *  The variables are saved as follows:
	 * | m11 -- m12 -- m13 -- m14 |
	 * | m21 -- m22 -- m23 -- m24 |
	 * | m31 -- m32 -- m33 -- m34 |
	 * | m41 -- m42 -- m43 -- m44 |
	 * @param m11
	 * @param m12
	 * @param m13
	 * @param m14
	 * @param m21
	 * @param m22
	 * @param m23
	 * @param m24
	 * @param m31
	 * @param m32
	 * @param m33
	 * @param m34
	 * @param m41
	 * @param m42
	 * @param m43
	 * @param m44
	 */
	public Mat4x4(final double m11, final double m12, final double m13, final double m14,
			final double m21, final double m22, final double m23, final double m24, final double m31, 
			final double m32, final double m33, final double m34, final double m41, final double m42, final double m43, final double m44){
		
		this.m11 = m11;
		this.m12 = m12;
		this.m13 = m13;
		this.m14 = m14;
		this.m21 = m21;
		this.m22 = m22;
		this.m23 = m23;
		this.m24 = m24;
		this.m31 = m31;
		this.m32 = m32;
		this.m33 = m33;
		this.m34 = m34;
		this.m41 = m41;
		this.m42 = m42;
		this.m43 = m43;
		this.m44 = m44;
	}
	
	/**
	 * multiplies this matrix with an input Vector and returns a Vector
	 * @param v
	 * @return
	 */
	public Vector3 mul(final Vector3 v){
		final double w = 0.0;
		return new Vector3(
				this.m11*v.x + this.m12*v.y + this.m13*v.z + this.m14*w,
				this.m21*v.x + this.m22*v.y + this.m23*v.z + this.m24*w,
				this.m31*v.x + this.m32*v.y + this.m33*v.z + this.m34*w);
	}
	
	/**
	 * multiplies this matrix with an input point and returns a point
	 * @param v
	 * @return
	 */
	public Point3 mul(final Point3 p){
		final double w = 1.0;
		return new Point3(
				this.m11*p.x + this.m12*p.x + this.m13*p.x + this.m14*w,
				this.m21*p.y + this.m22*p.y + this.m23*p.y + this.m24*w,
				this.m31*p.z + this.m32*p.z + this.m33*p.z + this.m34*w);
	}
	
	
	/**
	 * multiplies this matrix with an input matrix
	 * @param m Mat4x4
	 * @return Mat4x4 * Mat4x4
	 */
	public Mat4x4 mul(final Mat4x4 m){
		return new Mat4x4(
				this.m11 * m.m11 + this.m12 * m.m21 + this.m13 * m.m31 + this.m14 * m.m41,
				this.m11 * m.m12 + this.m12 * m.m22 + this.m13 * m.m32 + this.m14 * m.m42,
				this.m11 * m.m13 + this.m12 * m.m23 + this.m13 * m.m33 + this.m14 * m.m43,
				this.m11 * m.m14 + this.m12 * m.m24 + this.m13 * m.m34 + this.m14 * m.m44,
				
				this.m21 * m.m11 + this.m22 * m.m21 + this.m23 * m.m31 + this.m24 * m.m41,
				this.m21 * m.m12 + this.m22 * m.m22 + this.m23 * m.m32 + this.m24 * m.m42,
				this.m21 * m.m13 + this.m22 * m.m23 + this.m23 * m.m33 + this.m24 * m.m43,
				this.m21 * m.m14 + this.m22 * m.m24 + this.m23 * m.m34 + this.m24 * m.m44,
				
				this.m31 * m.m11 + this.m32 * m.m21 + this.m33 * m.m31 + this.m34 * m.m41,
				this.m31 * m.m12 + this.m32 * m.m22 + this.m33 * m.m32 + this.m34 * m.m42,
				this.m31 * m.m13 + this.m32 * m.m23 + this.m33 * m.m33 + this.m34 * m.m43,
				this.m31 * m.m14 + this.m32 * m.m24 + this.m33 * m.m34 + this.m34 * m.m44,
				
				this.m41 * m.m11 + this.m42 * m.m21 + this.m43 * m.m31 + this.m44 * m.m41,
				this.m41 * m.m12 + this.m42 * m.m22 + this.m43 * m.m32 + this.m44 * m.m42,
				this.m41 * m.m13 + this.m42 * m.m23 + this.m43 * m.m33 + this.m44 * m.m43,
				this.m41 * m.m14 + this.m42 * m.m24 + this.m43 * m.m34 + this.m44 * m.m44
				);
	}
	
	/**
	 * returns the transposition from a matrix 
	 * @param m:
	 * | m11 -- m12 -- m13 -- m14 |
	 * | m21 -- m22 -- m23 -- m24 |
	 * | m31 -- m32 -- m33 -- m34 |
	 * | m41 -- m42 -- m43 -- m44 |
	 * @return 
	 * | m11 -- m21 -- m31 -- m41 |
	 * | m12 -- m22 -- m32 -- m42 |
	 * | m13 -- m23 -- m33 -- m43 |
	 * | m14 -- m24 -- m34 -- m44 |
	 */
	public Mat4x4 transposed(){
		return new Mat4x4(
				this.m11, this.m21, this.m31, this.m41,
				this.m12, this.m22, this.m32, this.m42,
				this.m13, this.m23, this.m33, this.m43,
				this.m14, this.m24, this.m34, this.m44
				);
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		long temp;
		temp = Double.doubleToLongBits(m11);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(m12);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(m13);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(m14);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(m21);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(m22);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(m23);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(m24);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(m31);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(m32);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(m33);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(m34);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(m41);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(m42);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(m43);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(m44);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof Mat4x4))
			return false;
		Mat4x4 other = (Mat4x4) obj;
		if (Double.doubleToLongBits(m11) != Double.doubleToLongBits(other.m11))
			return false;
		if (Double.doubleToLongBits(m12) != Double.doubleToLongBits(other.m12))
			return false;
		if (Double.doubleToLongBits(m13) != Double.doubleToLongBits(other.m13))
			return false;
		if (Double.doubleToLongBits(m14) != Double.doubleToLongBits(other.m14))
			return false;
		if (Double.doubleToLongBits(m21) != Double.doubleToLongBits(other.m21))
			return false;
		if (Double.doubleToLongBits(m22) != Double.doubleToLongBits(other.m22))
			return false;
		if (Double.doubleToLongBits(m23) != Double.doubleToLongBits(other.m23))
			return false;
		if (Double.doubleToLongBits(m24) != Double.doubleToLongBits(other.m24))
			return false;
		if (Double.doubleToLongBits(m31) != Double.doubleToLongBits(other.m31))
			return false;
		if (Double.doubleToLongBits(m32) != Double.doubleToLongBits(other.m32))
			return false;
		if (Double.doubleToLongBits(m33) != Double.doubleToLongBits(other.m33))
			return false;
		if (Double.doubleToLongBits(m34) != Double.doubleToLongBits(other.m34))
			return false;
		if (Double.doubleToLongBits(m41) != Double.doubleToLongBits(other.m41))
			return false;
		if (Double.doubleToLongBits(m42) != Double.doubleToLongBits(other.m42))
			return false;
		if (Double.doubleToLongBits(m43) != Double.doubleToLongBits(other.m43))
			return false;
		if (Double.doubleToLongBits(m44) != Double.doubleToLongBits(other.m44))
			return false;
		return true;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString(){
		return("
Matrix:" +
				"
" + this.m11 + " | " + this.m12 + " | " + this.m13 + " |" + this.m14 +
				"
" + this.m21 + " | " + this.m22 + " | " + this.m32 + " |" + this.m24 +
				"
" + this.m31 + " | " + this.m32 + " | " + this.m33 + " |" + this.m34 +
				"
" + this.m41 + " | " + this.m42 + " | " + this.m43 + " |" + this.m44 +
				"
"
				);
	}
	
	
	
}


Die Klasse Transform:

package raytracer.math;

public class Transform {
	
	final public Mat4x4 m;  //Hier steht die Matrix
	final public Mat4x4 i; //Dies stellt die Inverse der Matrix dar
	

	/**
	 * public constructor
	 */
	public Transform(){
		this.m = new Mat4x4(
				1.0, 0.0, 0.0, 0.0,
				0.0, 1.0, 0.0, 0.0,
				0.0, 0.0, 1.0, 0.0,
				0.0, 0.0, 0.0, 1.0
				);
		this.i = this.m;
	}
	
	/**
	 * private constructor
	 * @param m
	 * @param i
	 */
	private Transform(final Mat4x4 m, final Mat4x4 i){
		this.m = m;
		this.i = i;
		System.out.println(this.m.mul(this.i).toString());
	}
	
	/**
	 * translates with an input Vector3
	 * @param t
	 * @return
	 */
	public Transform translated(final double x, final double y, final double z){
		Mat4x4 m1 = new Mat4x4(
				1.0, 0.0, 0.0, x,
				0.0, 1.0, 0.0, y,
				0.0, 0.0, 1.0, z,
				0.0, 0.0, 0.0, 1.0
				);
		
		Mat4x4 m2 = new Mat4x4(
				1.0, 0.0, 0.0, -x,
				0.0, 1.0, 0.0, -y,
				0.0, 0.0, 1.0, -z,
				0.0, 0.0, 0.0, 1.0
				);
		
		return new Transform(this.m.mul(m1), m2.mul(this.i));
	}
	
	/**
	 * transforms with an input Vector3
	 * @param s
	 * @return
	 */
	public Transform scaled(final double x, final double y, final double z){
		Mat4x4 m1 = new Mat4x4(
				x,   0.0, 0.0, 0.0,
				0.0, y,   0.0, 0.0,
				0.0, 0.0, z,   0.0,
				0.0, 0.0, 0.0, 1.0
				);
		
		Mat4x4 m2 = new Mat4x4(
				1.0/x, 0.0,   0.0,   0.0,
				0.0,   1.0/y, 0.0,   0.0,
				0.0,   0.0,   1.0/z, 0.0,
				0.0,   0.0,   0.0,   1.0
				);
		
		return new Transform(this.m.mul(m1), m2.mul(this.i));
	}
	
	/**
	 * rotates around the x-axis with input angle
	 * @param alpha
	 * @return
	 */
	public Transform rotateX(final double alpha){
		Mat4x4 m1 = new Mat4x4(
				1.0, 0.0,			   0.0,				0.0,
				0.0, Math.cos(alpha), -Math.sin(alpha), 0.0,
				0.0, Math.sin(alpha),  Math.cos(alpha), 0.0,
				0.0, 0.0,			   0.0,				1.0
				);
		
		Mat4x4 m2 = new Mat4x4(
				1.0,  0.0,			   0.0,				0.0,
				0.0,  Math.cos(alpha), Math.sin(alpha), 0.0,
				0.0, -Math.sin(alpha), Math.cos(alpha), 0.0,
				0.0, 0.0,			   0.0,				1.0
				);
		
		return new Transform(this.m.mul(m1), m2.mul(this.i));
	}
	
	/**
	 * rotates around the y-axis with input angle
	 * @param alpha
	 * @return
	 */
	public Transform rotateY(final double alpha){
		Mat4x4 m1 = new Mat4x4(
				 Math.cos(alpha), 0.0, Math.sin(alpha), 0.0,
				 0.0,			  1.0, 0.0,			    0.0,
				-Math.sin(alpha), 0.0, Math.cos(alpha), 0.0,
				 0.0,			  0.0, 0.0,			    1.0
				);
		
		Mat4x4 m2 = new Mat4x4(
				 Math.cos(alpha), 0.0, -Math.sin(alpha), 0.0,
				 0.0,			  1.0,  0.0,			    0.0,
				 Math.sin(alpha), 0.0,  Math.cos(alpha), 0.0,
				 0.0,			  0.0,  0.0,			    1.0
				);
		
		return new Transform(this.m.mul(m1), m2.mul(this.i));
	}
	
	/**
	 * rotates around the z-axis with input angle
	 * @param alpha
	 * @return
	 */
	public Transform rotateZ(final double alpha){
		Mat4x4 m1 = new Mat4x4(
				Math.cos(alpha), -Math.sin(alpha), 0.0, 0.0,
				Math.sin(alpha),  Math.cos(alpha), 0.0, 0.0,
				0.0,			  0.0,			   1.0, 0.0,
				0.0,			  0.0,			   0.0, 1.0
				);
		
		Mat4x4 m2 = new Mat4x4(
				 Math.cos(alpha), Math.sin(alpha), 0.0, 0.0,
				-Math.sin(alpha), Math.cos(alpha), 0.0, 0.0,
				 0.0,			  0.0,			   1.0, 0.0,
				 0.0,			  0.0,			   0.0, 1.0
				);
		
		return new Transform(this.m.mul(m1), m2.mul(this.i));
	}
	
	/**
	 * returns the transformated Normal
	 * @param n
	 * @return
	 */
	public Normal3 mul(Normal3 n){
		return this.i.transposed().mul(n.asVector()).normalized().asNormal();
	}
	
	/**
	 * returns the transformated Ray
	 * @param r
	 * @return
	 */
	public Ray mul(Ray r){
		return new Ray(i.mul(r.o), i.mul(r.d));
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((i == null) ? 0 : i.hashCode());
		result = prime * result + ((m == null) ? 0 : m.hashCode());
		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof Transform))
			return false;
		Transform other = (Transform) obj;
		if (i == null) {
			if (other.i != null)
				return false;
		} else if (!i.equals(other.i))
			return false;
		if (m == null) {
			if (other.m != null)
				return false;
		} else if (!m.equals(other.m))
			return false;
		return true;
	}
	
	
	
}

Und die main Klasse mit die das ganze Projekt ausgeführt werden soll:

package ue5;

import java.util.ArrayList;

import raytracer.Color;
import raytracer.Raytracer;
import raytracer.World;
import raytracer.camera.Camera;
import raytracer.camera.PerspectiveCamera;
import raytracer.geometry.Geometry;
import raytracer.geometry.Node;
import raytracer.geometry.Sphere;
import raytracer.light.PointLight;
import raytracer.material.PhongMaterial;
import raytracer.math.Point3;
import raytracer.math.Transform;
import raytracer.math.Vector3;

public class Main {

	public static void main(String[] args) {
		Color redColor = new Color(1.0, 0.0, 0.0);
		Color whiteColor = new Color(1.0, 1.0, 1.0);
		
		Transform e = new Transform();
		
		Sphere sphere = new Sphere(new PhongMaterial(redColor, whiteColor, 64));
		
		ArrayList<Geometry> geoList = new ArrayList<>();
		
		geoList.add(sphere);
		
		Transform t = e.scaled(5.0, 3.0, 2.0); //muss hier noch gemacht werden!
		
		Node node = new Node(new PhongMaterial(redColor, whiteColor, 64), t, geoList);
		
		Camera cam = new PerspectiveCamera(new Point3(8.0, 8.0, 8.0), new Vector3(-1.0, -1.0, -1.0), new Vector3(0.0, 1.0, 0.0), (Math.PI/8.0));
		PointLight point = new PointLight(whiteColor, new Point3(8.0,8.0,8.0), true);
		
		World world = new World(new Color(0.15,0.15,0.15));
		world.add(node);
		world.add(point);
		
		Raytracer raytracer = new Raytracer( cam, world);
		raytracer.show();
	}

}

Das zweite problem hat wahrscheinlich mit der Skalierung zu tun. Die Box spielt total verrückt und zerfetzt sich in 1000 Teile, anstatt gleichmäßig sich irgendwo hinzustrecken.
Jemand eine Idee?
Die Klassen sind die gleichen die Oben außer die Axis Alligned Box und eine andere main.

Hier die Box:

package raytracer.geometry;

import java.util.ArrayList;
import java.util.List;

import raytracer.material.Material;
import raytracer.math.Normal3;
import raytracer.math.Point3;
import raytracer.math.Ray;

public class AxisAllIgnedBox extends Geometry {

	final Point3 lbf;
	final Point3 run;
    
	 public AxisAllIgnedBox(final Material material, final Point3 lbf, final Point3 run) {
		super(material);
		this.lbf = lbf;
		this.run = run;	
	}
	 
	public AxisAllIgnedBox(final Material material){
		super(material);
		this.lbf = new Point3(-0.5, -0.5, -0.5);
		this.run = new Point3(0.5, 0.5, 0.5);
	}
	
	/**
	 * returns the hit with a ray
	 */
	public Hit hit(final Ray r){
		Hit shapeHit = null;
		
		Plane top = new Plane(this.material, run, new Normal3(0.0,1.0,0.0));
		Plane bottom = new Plane(this.material, lbf, new Normal3(0.0,-1.0,0.0));
		Plane right = new Plane(this.material, run, new Normal3(1.0,0.0,0.0));
		Plane left = new Plane(this.material, lbf, new Normal3(-1.0,0.0,0.0));
		Plane front = new Plane(this.material, run, new Normal3(0.0,0.0,1.0));
		Plane back = new Plane(this.material, lbf, new Normal3(0.0,0.0,-1.0));
        
        List<Hit> hits;
        
       
        
        hits = new ArrayList<Hit>();
	    hits.add(top.hit(r));
	    hits.add(bottom.hit(r));
	        
	    if(!( hits.isEmpty() )){
	      	for(Hit h: hits){
	       		if(h != null){
	       		Point3 p = r.at(h.t);
	       		if(	p.x >= lbf.x && p.x <= run.x &&
	           		p.z >= lbf.z && p.z <= run.z){
	        			if(shapeHit == null)
	        				shapeHit = h;
	        			if(h.t < shapeHit.t)
		        			shapeHit = h;
	        		}
	        	}
	        }
	    }
        
	    hits = new ArrayList<Hit>();
	    hits.add(right.hit(r));
	    hits.add(left.hit(r));
	        
	    if(!( hits.isEmpty() )){
	      	for(Hit h: hits){
	      		if(h != null){
	        		Point3 p = r.at(h.t);
	        		if(p.y >= lbf.y && p.y <= run.y &&
	    	           p.z >= lbf.z && p.z <= run.z){
	        			if(shapeHit == null)
	        				shapeHit = h;
	        			if(h.t < shapeHit.t)
		        			shapeHit = h;
	        		}
	        	}
	        }
	    }
	    
	    hits = new ArrayList<Hit>();
	    hits.add(front.hit(r));
	    hits.add(back.hit(r));
	        
	    if(!( hits.isEmpty() )){
	      	for(Hit h: hits){
	       		if(h != null){
	       		Point3 p = r.at(h.t);
	       		if(	p.x >= lbf.x && p.x <= run.x &&
	           		p.y >= lbf.y && p.y <= run.y){
	        			if(shapeHit == null)
	        				shapeHit = h;
	        			if(h.t < shapeHit.t)
		        			shapeHit = h;
	        		}
	        	}
	        }
	    }
	    
	    return shapeHit;
	}



	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result + ((lbf == null) ? 0 : lbf.hashCode());
		result = prime * result + ((run == null) ? 0 : run.hashCode());
		return result;
	}



	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!super.equals(obj))
			return false;
		if (!(obj instanceof AxisAllIgnedBox))
			return false;
		AxisAllIgnedBox other = (AxisAllIgnedBox) obj;
		if (lbf == null) {
			if (other.lbf != null)
				return false;
		} else if (!lbf.equals(other.lbf))
			return false;
		if (run == null) {
			if (other.run != null)
				return false;
		} else if (!run.equals(other.run))
			return false;
		return true;
	}



	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "AxisAllIgnedBox [lbf=" + lbf + ", run=" + run + "]";
	}
	
	
}

Und die Main:

package ue5;

import java.util.ArrayList;

import raytracer.Color;
import raytracer.Raytracer;
import raytracer.World;
import raytracer.camera.Camera;
import raytracer.camera.PerspectiveCamera;
import raytracer.geometry.AxisAllIgnedBox;
import raytracer.geometry.Geometry;
import raytracer.geometry.Node;
import raytracer.light.PointLight;
import raytracer.material.LambertMaterial;
import raytracer.math.Point3;
import raytracer.math.Transform;
import raytracer.math.Vector3;

public class Main2 {

	public static void main(String[] args) {
		
		Color yellowColor = new Color(1.0, 1.0, 0.0);
		Color whiteColor = new Color(1.0, 1.0, 1.0);
		
		Transform e = new Transform();
		
		
		AxisAllIgnedBox box = new AxisAllIgnedBox(new LambertMaterial(yellowColor));
		AxisAllIgnedBox box2 = new AxisAllIgnedBox(new LambertMaterial(yellowColor), new Point3(-0.5, -0.5, -0.5), new Point3(0.5, 0.5, 0.5));

		
		ArrayList<Geometry> geoList = new ArrayList<>();
		
		geoList.add(box);
		
		Transform t = e.translated(1.0, 1.0, 3.0).scaled(6.0, 2.0, 5.0); //muss hier noch gemacht werden!
		
		Node node = new Node(null, t, geoList);
		
		Camera cam = new PerspectiveCamera(new Point3(8.0, 8.0, 8.0), new Vector3(-1.0, -1.0, -1.0), new Vector3(0.0, 1.0, 0.0), (Math.PI/8.0));
		PointLight point = new PointLight(whiteColor, new Point3(8.0,8.0,8.0), true);
		
		World world = new World(new Color(0.15,0.15,0.15));
		world.add(node);
		//world.add(box2);
		world.add(point);
		
		Raytracer raytracer = new Raytracer( cam, world);
		raytracer.show();

	}

}

Ich weiß es ist wirklich viel, aber ich freue mich über jede Unterstützung :slight_smile:

Viel, aber … entweder ZU viel, oder nicht genug: Compilieren wird man das ja wohl nicht können, da fehlt noch etliches. Insbesondere verschwindet das “Material” ja immer gleich im “Geometry”-Konstruktor, d.h. den Fehler durch Draufschauen zu finden, könnte schwierig werden. Kann man die Fehlerquelle nicht etwas eingrenzen?

[ot]
Bei sowas wie

public class Sphere extends Geometry {
 
    /**
     * the center of the Sphere
     */
    final Point3 c;
   
    /**
     * the radius
     */
    final Double d;

    /**
     * constructor
     * @param color the color of the Sphere
     * @param c the center of the Sphere
     * @param d the radius
     */
    public Sphere(final Material material, final Point3 c, final Double d) {
        super(material);
       
        this.c = c; // Ursprung der Spere
        this.d = d; // Radius der Sphere
    }

rollen sich einem erfahrenen Programmierer die Fußnägel hoch. Manche würden sowas propagieren:

public class Sphere extends Geometry {
 
    private final Point3 center;
    private final double radius;

    public Sphere(Material material, Point3 center double radius) {
        super(material);
       
        this.center = center;
        this.radius = radius;
    }

Ich würde aber sagen, dass man es so machen sollte:

public class Sphere extends Geometry 
{
    /**
     * The center of the Sphere. May never be null. 
     */
    private final Point3 center;
   
    /**
     * The radius of the sphere. This will never be negative.
     */
    private final double radius;

    /**
     * Creates a new sphere with the given material, center and radius.
     * A reference to the given center point will be stored. So changes
     * in the given point will affect the position of this sphere.
     *
     * @param material The material of the sphere
     * @param center The center of the Sphere
     * @param radius The radius of the Sphere
     * @throws NullPointerException If the given center is null.
     * @throws IllegalArgumentException If the given radius is negative
     */
    public Sphere(Material material, Point3 center, double radius) 
    {
        super(material);
        if (center == null)
        {
            throw new NullPointerException("The center is null");   
        }
        if (radius < 0.0)
        {
            throw new IllegalArgumentException (
                "The radius is negative: "+radius);   
        }
        this.center = center;
        this.radius = radius;
    }

(Das ist nur EINE Kleinigkeit, von vielen. Von anderen Fragen, wie ob die Klasse denn public und nicht-final sein sollte, mal abgesehen…)
[/ot]