package tinyray.examples;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Iterator;
import tinyray.frontend.ParseException;
import tinyray.frontend.Parser;
import tinyray.frontend.Scanner;
import tinyray.language.Ambience;
import tinyray.language.Background;
import tinyray.language.Bounding;
import tinyray.language.Camera;
import tinyray.language.Defaults;
import tinyray.language.Fog;
import tinyray.language.LanguageKit;
import tinyray.language.Parameters;
import tinyray.language.Plane;
import tinyray.language.Real;
import tinyray.language.Sphere;
import tinyray.language.Sun;
import tinyray.language.Tinyray;
import tinyray.language.Triangle;
import tinyray.language.Vector;
import tinyray.language.Visitable;
import tinyray.language.Visitor;
/**
* Die Klasse ColorCheckVisitor stellt nur ein Beispiel eines
* Visitors dar. Der Besuch eines Knotens ermittelt, ob die darin
* erreichbaren Farbvektoren wertemäßig korrekt belegt sind.
*
* Ein Farbvektor mit den Werten [0.0, 1.2, -0.2] wäre unkorrekt,
* da 1.2 > 1.0 und -0.2 < 0.0.
*
* Ob der gesamte Tinyray-Baum nun unkorrekte Farbvektoren enthält,
* kann mit dem vorliegenden ColorCheckVisitor geprüft werden.
*/
public class ColorCheckVisitor implements Visitor<Boolean, Void> {
public Boolean visit(Tinyray tinyray, Void nothing) {
boolean result = true;
result &= tinyray.camera.accept(this, null);
result &= tinyray.background.accept(this, null);
result &= tinyray.ambience.accept(this, null);
result &= tinyray.fog.accept(this, null);
Iterator<Sun> suns = tinyray.suns.listIterator();
while (suns.hasNext()) {
result &= suns.next().accept(this, null);
}
Iterator<Visitable> visitables = tinyray.visitables.listIterator();
while (visitables.hasNext()) {
result &= visitables.next().accept(this, null);
}
return result;
}
public Boolean visit(Camera camera, Void nothing) {
return true; // Die Kamera enthält keine Farbvektoren!
}
public Boolean visit(Background background, Void nothing) {
return background.color.accept(this, null);
}
public Boolean visit(Ambience ambience, Void nothing) {
return ambience.color.accept(this, null);
}
public Boolean visit(Fog fog, Void nothing) {
return fog.color.accept(this, null);
}
public Boolean visit(Defaults defaults, Void nothing) {
return defaults.parameters.accept(this, null);
}
public Boolean visit(Sun sun, Void nothing) {
return sun.color.accept(this, null);
}
public Boolean visit(Bounding bounding, Void nothing) {
boolean result = true;
Iterator<Visitable> visitables = bounding.visitables.listIterator();
while (visitables.hasNext()) {
result &= visitables.next().accept(this, null);
}
return result;
}
public Boolean visit(Triangle triangle, Void nothing) {
return triangle.parameters.accept(this, null);
}
public Boolean visit(Sphere sphere, Void nothing) {
return sphere.parameters.accept(this, null);
}
public Boolean visit(Plane plane, Void nothing) {
return plane.parameters.accept(this, null);
}
public Boolean visit(Parameters parameters, Void nothing) {
boolean result = true;
if (parameters.visitables.size() > 0) { // diffuse color
result &= parameters.visitables.get(0).accept(this, null);
}
if (parameters.visitables.size() > 1) { // ambient color
result &= parameters.visitables.get(1).accept(this, null);
}
return result;
}
public Boolean visit(Vector vector, Void nothing) {
return vector.x.accept(this, null)
&& vector.y.accept(this, null)
&& vector.z.accept(this, null);
}
public Boolean visit(Real real, Void nothing) {
return (real.value >= 0.0) && (real.value <= 1.0);
}
/* Hauptprogramm */
public static void main(String[] arguments) {
if (arguments.length > 0) {
try {
// Scanner, Parser, Tinyray wie immer!
Scanner scanner =
new Scanner(new FileInputStream(arguments[0]));
Parser<Visitable, Tinyray> parser =
new Parser<Visitable, Tinyray>(scanner, new LanguageKit());
Tinyray tinyray = parser.parse();
// Verwendung des ColorCheckVisitors
boolean okay = tinyray.accept(new ColorCheckVisitor(), null);
if (okay) {
System.out.println("Colors okay!");
} else {
System.out.println("Colors NOT okay!");
}
} catch (ParseException e) {
System.err.println(e.getMessage());
} catch (FileNotFoundException e) {
System.err.println(e.getMessage());
}
} else {
System.err.println("Tinyray-Programm-Datei angeben.");
}
}
}
Das
„Hallo Welt”-Programm
…
… enthält natürlich nur korrekte Farbwerte.
Doch beim folgenden
Tinyray-Programm
sieht es ganz anders aus.
Unter den vielen Farbvektoren hat sich ein schwarzes Schaf eingeschlichen!
Tinyray {
Camera { [0, 17, 4.5]; [-0.22, 0, -2]; [0.2, 0, 1] }
Ambience { [0.4, 0.4, 0] }
Sun { [0, 0, 1]; [0.4, 0.3, 0.0] }
Sun { [0, 17, 20]; [0.9, 0.9, 0.9] }
Fog { [0.6, 0.6, 0.6]; 0.035 }
Bounding {
Defaults { [0.8, 0.8, 0.8]; [0.2, 0.2, 0]; 0.1; 50.0; 0.6 }
Sphere { [+5.0000, +0.0000, 0]; 0.3; [0.8, 0.6500, 0] }
Sphere { [+4.8296, +1.2941, 0]; 0.3; [0.8, 0.5853, 0] }
Sphere { [+4.3301, +2.4999, 0]; 0.3; [0.8, 0.5250, 0] }
Sphere { [+3.5355, +3.5355, 0]; 0.3; [0.8, 0.4732, 0] }
Sphere { [+2.4999, +4.3301, 0]; 0.3; [0.8, 0.4335, 0] }
Sphere { [+1.2941, +4.8296, 0]; 0.3; [0.8, 0.4085, 0] }
Sphere { [+0.0000, +5.0000, 0]; 0.3;
[0.8, 0.4000, -0.2] // Wo ist das schwarze Schaf?
}
Sphere { [-1.2941, +4.8296, 0]; 0.3; [0.8, 0.4085, 0] }
Sphere { [-2.4999, +4.3301, 0]; 0.3; [0.8, 0.4335, 0] }
Sphere { [-3.5355, +3.5355, 0]; 0.3; [0.8, 0.4732, 0] }
Sphere { [-4.3301, +2.4999, 0]; 0.3; [0.8, 0.5250, 0] }
Sphere { [-4.8296, +1.2941, 0]; 0.3; [0.8, 0.5853, 0] }
Sphere { [-5.0000, +0.0000, 0]; 0.3; [0.8, 0.6500, 0] }
Sphere { [-4.8296, -1.2941, 0]; 0.3; [0.8, 0.7147, 0] }
Sphere { [-4.3301, -2.4999, 0]; 0.3; [0.8, 0.7750, 0] }
Sphere { [-3.5355, -3.5355, 0]; 0.3; [0.8, 0.8268, 0] }
Sphere { [-2.4999, -4.3301, 0]; 0.3; [0.8, 0.8665, 0] }
Sphere { [-1.2941, -4.8296, 0]; 0.3; [0.8, 0.8914, 0] }
Sphere { [+0.0000, -5.0000, 0]; 0.3; [0.8, 0.9000, 0] }
Sphere { [+1.2941, -4.8296, 0]; 0.3; [0.8, 0.8914, 0] }
Sphere { [+2.4999, -4.3301, 0]; 0.3; [0.8, 0.8665, 0] }
Sphere { [+3.5355, -3.5355, 0]; 0.3; [0.8, 0.8268, 0] }
Sphere { [+4.3301, -2.4999, 0]; 0.3; [0.8, 0.7750, 0] }
Sphere { [+4.8296, -1.2941, 0]; 0.3; [0.8, 0.7147, 0] }
}
Defaults { [0.27, 0.26, 0.2]; [0.2, 0.15, 0.1]; 0.4; 600.0; 0.7 }
Plane { [-1, 1, -1.2]; [1, -1, -1]; [-1, -1, -1] }
}
Gleich mal testen, ob der
ColorCheckVisitor
in dem
Tinyray-Programm
badcolor.tinyray
das besagte schwarze Schaf erkennt!
Ja, das schwarze Schaf wurde entdeckt!
Leider kann man daraus nicht erkennen, wo sich nun genau im
Tinyray-Programm
die unkorrekte Farbangabe verbirgt bzw. wie die unkorrekte Farbangabe lautet.
Diese Klasse dahingehend zu erweitern, sei Ihrem Ehrgeiz überlassen.