# Pfade durch Farbräume definieren



## Bergtroll (16. Jul 2010)

Hallo mal wieder werte Java Gemeinde,

wollte mal fragen, wer sich mit Farbräumen gut auskennt? Ich möchte nämlich in der Lage sein, eine Reihe von Zahlenwerten auf Farben abzubilden.

Zum Problem:
In vielen Visualisierunsapplikationen wird eine einfache Regenbogenskala oder eine einfache lineare Graustufenskala verwendet, die allerdings keiner natürlichen Ordnung entspricht. Auch eine zusätzliche Codierung über Helligkeit ist keine optimale Wahl.

Gerade für Messreihen wo die Zahlenwerte aber einer natürlichen Ordnung entsprechen, wäre die Verwendung wahrnehmungsgemäß korrekter Farbskalen sinnvoll. Zusätzlich wäre zu berücksichtigen, Farbskalen für Leute mit veränderter Farbwahrnehmung, wie z.B. Rot-Grün Schwäche konstruieren zu können. Um letzteres zu erreichen, müsste die Farbskala im CIE Farbort Diagramm möglichst senkrecht zu Schar der Verwechslungsgeraden des jeweiligen Farbenblindsheitstypen verlaufen.

Als Beispiel sei hier das CIE Diagramm mit einigen Verwechslungsgeraden gezeigt:






Die Idee:
In einem genähert wahrnehmungsgemäßen Farbraum (CIE-LUV oder CIE-LAB) eine Kurve konstruieren und dann die gegebene Werteverteilung auf diese Kurve abbilden. Für einen beliebigen Punkt dieser Kurve, der ja eindimensional im 3D-Farbraum eingebettet ist, könnte man dann den Farbort als RGB Wert abgreifen, was ja in Java für jeden ColorSpace als Methode definiert ist.

Die Kurve wird dann je nach Bedarf unter Einhaltung bestimmter Bedingungen konstruiert, wie z.B. eben, dass Farbton und Sättigung auf einer Kurve senkrecht zu den Verwechslungsgeraden variieren.

Die Frage:
Wie ließe sich eine Kurve durch den CIELUV Farbraum formulieren. Ich stehe irgendwie gerade sehr auf dem Schlauch, wie ich anfangen sollte und könnte nen Denkanstoß gebrauchen...

Mfg,
Bergtroll


----------



## Bergtroll (16. Jul 2010)

P.S. Zusätzliche Bedingungen die man an die Kurve stellen könnte wären natürlich auch, dass Sie nur durch Farborte läuft, die z.B. im RGBs, oder CYMK Farbraum existieren.


----------



## Marco13 (16. Jul 2010)

Zugegeben, ich habe davon jetzt etwas weniger verstanden, als ich bei diesem "Gesamtthema" erwartet hätte. "Verwechslungsgeraden" habe ich z.B. noch nie gehört. Aber das hängt vermutlich damit zusammen, dass das CIE-Farbmodell (zumindest für mich, bisher) nicht wirklich viel praktische Relevanz hat(te) - RGB und HSB sind in vielen Bereichen gebräuchlicher, und das CIE-Modell wohl nur bei stark... (wie sagt man da) ... Wahrnehmungspsychologisch oder -phyisologisch orientierten Anwendungen sinnvoll.

Liegt der Schwerpunkt der Frage nun auf einer "geeigneten" Wahl der Punkte oder des Pfades durch den Farbraum, oder darin, wie man einen solchen Pfad durch einen 3D-Raum geeignet implementiert?

Letzteres könnte man ganz pragmatisch als eine Art "Polygonkurve" machen (notfalls auch Bezier, wenn's stetig sein soll), also sinngemäß sowas wie

```
class Point3f 
{ 
    float x,y,z;

    Point3f interpolate(Point other, float alpha) 
    { 
        // liefert this+alpha*(other-this)  
    }
    ...
}

class Polgoncurve
{
    private List<Point3f> points = ...

    Point3f getPointAt(float alpha) 
    {
        // Liefert den Punkt an der relativen Position "alpha" (zwischen 0 und 1) dieser Kurve
    }
}
```

Damit kann man in n Schritten über die Kurve laufen, und sich für jeden Punkt auf der Kurve dort den (passend interpolierten) Point3f holen, der dann als RGB- oder CIE- oder sonstige Farbe interpretiert und mit der ColorSpace-Klasse hin jeden anderen Farbraum umgerechnet werden kann...


----------



## Bergtroll (16. Jul 2010)

Hi Marco,

genau um solche Wahrnehmungspsychologischen (-physiologischen, wahrscheinlich geht beides) Farbskalen geht es, da die Abbildung auf eine Skala bereits intuitiv die Ordnung der Wertereihe verdeutlichen und das korrekte Ablesen erleichtern soll.

Im Prinzip sind beide von dir angesprochenen Fragen Schwerpunkte, wobei mich im Moment zweiterer, wie man den Pfad geeignet implementiert, eher interessiert. Dein Ansatz hilft mir auf jeden Fall schonmal weiter, nur dass die Kurven tatsächlich analytisch und stetig statt über Punktmengen definiert sein sollten. Die Kurvenbahn sollte also über ihre Länge (0.0 - 1.0) parametrisiert sein, so wäre jeder Punkt über seine Position im Wertebereich berechenbar. Weißt du ob es möglich ist, Bezierkurven zu parametrisieren? Habe mich mit diesen leider noch nie auseinandergesetzt, was bezüglich meiner Fragestellung wohl eines der Hauptprobleme ist.

Eine interessante Kurve wäre z.B. eine Periode einer Spirale (also 0 bis 2*Pi) mit Variation des Radius von 0 zu einem maximum und wieder zu null, die aufsteigend durch den CIE-LUV läuft. Die Bedeutung dieser wäre beispielsweise, von schwarz ausgehend mit monoton steigender Helligkeit und zuerst zunehmender, dann abnehmender Sättigung bis nach weiß zu laufen. 

Jetzt grübele ich nur, wie ich dabei sicherstelle, dass die Kurve immer im Bereich der darstellbaren Farben verbleibt?


----------



## Marco13 (16. Jul 2010)

Bergtroll hat gesagt.:


> nur dass die Kurven tatsächlich analytisch und stetig statt über Punktmengen definiert sein sollten. Die Kurvenbahn sollte also über ihre Länge (0.0 - 1.0) parametrisiert sein, so wäre jeder Punkt über seine Position im Wertebereich berechenbar. Weißt du ob es möglich ist, Bezierkurven zu parametrisieren? Habe mich mit diesen leider noch nie auseinandergesetzt, was bezüglich meiner Fragestellung wohl eines der Hauptprobleme ist.



Zugegeben, viele meiner Kenntnisse zu diesen Themen sind ... nunja... "eingerostet"  Grundsätzlich könnte man z.B. besagte Spirale auch analytisch beschreiben (und es würde sich auch anbieten). GANZ GANZ GROB könnte das dann ja sowas sein wie

```
private final double minRadius = 0.25;
private final double maxRadius = 1.0;
private final double minZ = 0.25;
private final double maxZ = 1.0;

Point3f getPointAt(float alpha)
{
    double angle = alpha * Math.PI * 2;
    double radius = minRadius + alpha * (maxRadius - minRadius);
    double x = radius * Math.cos(angle);
    double y = radius * Math.sin(angle);
    double z = minZ + alpha * (maxZ - minZ);
    return new Point3f(x,y,z);
}
```

Allerdings wäre die in mancher Hinsicht nicht mehr so leicht handhabar. Wenn sie z.B. verschoben oder skaliert werden sollte, könnte man nicht mehr einfach die Punkte verschieben - höchstens nach der Berechnung, mit sowas wie

```
interface Curve { Point3f getPointAt(float alpha); }
class SpiralCurve implements Curve
{
    public Point3f getPointAt(float alpha) { /* code von oben */ }
}

class ScaledCurve implements Curve
{
    private Curve curve;
    private Point3f scaling = new Point3f(2,1,2);
    public Point3f getPointAt(float alpha) 
    { 
        Point3f p = curve.getPointAt(alpha);
        return p.scaled(scaling);
    }
}
```
Aber .... vielleicht ist das schon zu spezifisch, und für deine Intentionen gar nicht so gut geeignet... :bahnhof:



> Jetzt grübele ich nur, wie ich dabei sicherstelle, dass die Kurve immer im Bereich der darstellbaren Farben verbleibt?



Hm. A priori ist das schwierig. Natürlich kann man die Kurve mit einer kleinen Schrittweite abtasten, und jeden einzelnen Punkt prüfen (und sie ggf. in eine "ScaledCurve" oder eine "TranslatedCurve" (oder gleich eine CurveThatIsTransformedWithAMatrixSoThatItFitsIntoAnArea ) oder so einwickeln, aber wie praktikabel das ist, kann ich im Moment kaum sagen...


----------



## Bergtroll (17. Jul 2010)

Sodalla, habe jetzt erstmal nen ColorSpace gebaut, würde mich freuen wenn ihr mir sagt, was ihr davon haltet, insbesondere semantisch bessere Vorschläge für Namen von Attributen und Methoden sind sehr willkommen:


```
package de.jscivision.utils.ColorTable;

import java.awt.color.ColorSpace;

public class CIE_LUV_ColorSpace extends ColorSpace {
	
	private Illumination illumination;
	
	private static final ColorSpace sRGB = ColorSpace.getInstance(CS_sRGB);
	
	private static final float L_BORDER_VALUE = (float) Math.pow((6.0/29.0), 3);  
	private static final float L_LOW_FACTOR_FORWARD = (float) Math.pow((29.0/3.0), 3);
	private static final float L_LOW_FACTOR_BACKWARD = (float) Math.pow((3.0/29.0), 3);
	
	
	public CIE_LUV_ColorSpace() {
		this(Illumination.D50_2DEG);
	}
	
	public CIE_LUV_ColorSpace(Illumination illuminant) {
		super(ColorSpace.TYPE_Luv, 3);
		this.setIllumination(illuminant);
	}

	@Override
	public float[] toRGB(float[] colorvalue) {
		return sRGB.fromCIEXYZ(this.toCIEXYZ(colorvalue));
	}

	@Override
	public float[] fromRGB(float[] rgbvalue) {
		return this.fromCIEXYZ(sRGB.toCIEXYZ(rgbvalue));
	}

	@Override
	public float[] toCIEXYZ(float[] colorvalue) {
		float L_asterisk = colorvalue[0];
		float u_asterisk = colorvalue[1];
		float v_asterisk = colorvalue[2];
		
		float Y = calcY(L_asterisk);
		float u = calc_u_from_Luv(L_asterisk, u_asterisk);
		float v = calc_v_from_Luv(L_asterisk, v_asterisk);
		
		float X = Y * (9*u)/(4*v);
		float Z = Y * (12 - 3*u - 20*v)/(4*v);
			
		colorvalue[0] = X;
		colorvalue[1] = Y;
		colorvalue[2] = Z;
		
		colorvalue = rescaleXYZValues(colorvalue, illumination, Illumination.D50_2DEG);
		
		return colorvalue;
	}
	
	@Override
	public float[] fromCIEXYZ(float[] colorvalue) {
		colorvalue = rescaleXYZValues(colorvalue, Illumination.D50_2DEG, illumination);
		
		float Y = colorvalue[1];
		float L_asterisk = calc_L_asterisk(Y);
		float u_asterisk = calc_u_asterisk(L_asterisk, colorvalue);
		float v_asterisk = calc_v_asterisk(L_asterisk, colorvalue);
		
		colorvalue[0] = L_asterisk;
		colorvalue[1] = u_asterisk;
		colorvalue[2] = v_asterisk;

		return colorvalue;
	}
	
	public float[] rescaleXYZValues(float[] colorvalue, Illumination src, Illumination dest) {
		double whitepoint_quotient_x;
		double whitepoint_quotient_y;
		double whitepoint_quotient_z;
		
		if (src == dest) {
			whitepoint_quotient_x = 1.0;
			whitepoint_quotient_y = 1.0;
			whitepoint_quotient_z = 1.0;
				
		} else {
			whitepoint_quotient_x = dest.getCIEXYZ_X() / src.getCIEXYZ_X();
			whitepoint_quotient_y = dest.getCIEXYZ_Y() / src.getCIEXYZ_Y();
			whitepoint_quotient_z = dest.getCIEXYZ_Z() / src.getCIEXYZ_Z();
		}
		
		colorvalue[0] = (float) (colorvalue[0] * whitepoint_quotient_x);
		colorvalue[1] = (float) (colorvalue[1] * whitepoint_quotient_y);
		colorvalue[2] = (float) (colorvalue[2] * whitepoint_quotient_z);
		
		return colorvalue;
	}
	
	private float calcY(float L_asterisk) {
		if (L_asterisk <= 8) {
			return (float) (illumination.getCIEXYZ_Y() * L_asterisk * L_LOW_FACTOR_BACKWARD);
		} else {
			double quotient = (L_asterisk + 16) / 116;
			return (float) (illumination.getCIEXYZ_Y() * Math.pow(quotient, 3));
		}
	}
	
	private float calc_u_from_Luv(double L_asterisk, double u_asterisk) {
		return (float) (u_asterisk / (13*L_asterisk) + illumination.getU());
	}
	
	private float calc_v_from_Luv(double L_asterisk, double v_asterisk) {
		return (float) (v_asterisk / (13*L_asterisk) + illumination.getV());
	}
	
	private float calc_L_asterisk(float Y) {
		float quotient = (float) ( Y / illumination.getCIEXYZ_Y() );
		
		if (Math.pow(quotient, 3) <= L_BORDER_VALUE) {
			return L_LOW_FACTOR_FORWARD * quotient;
			
		} else {
			return (float) (116 * Math.pow(quotient, (1.0/3.0)) - 16);
		}
	}
	
	private float calc_u_asterisk(float L_asterisk, float[] colorvalue) {
		float u = this.calc_u_from_XYZ(colorvalue);
		return (float) ( 13 * L_asterisk * (u - illumination.getU()) );
	}
	
	private float calc_u_from_XYZ(float[] colorvalue) {
		float Xp = colorvalue[0];
		float Yp = colorvalue[1];
		float Zp = colorvalue[2];
		return (4*Xp)/(Xp + 15*Yp + 3*Zp);
	}
	
	private float calc_v_asterisk(float L_asterisk, float[] colorvalue) {
		float v = this.calc_v_from_XYZ(colorvalue);
		return (float) ( 13 * L_asterisk * (v - illumination.getV()) );
	}
	
	private float calc_v_from_XYZ(float[] colorvalue) {
		float Xp = colorvalue[0];
		float Yp = colorvalue[1];
		float Zp = colorvalue[2];
		return (9*Yp)/(Xp + 15*Yp + 3*Zp);
	}
	
	public Illumination getIllumination() {
		return illumination;
	}

	public void setIllumination(Illumination illumination) {
		this.illumination = illumination;
	}

}
```

Und die dazugehörige Beleuchtungsklasse

```
package de.jscivision.utils.ColorTable;

public enum Illumination {
	D50_2DEG(0.34567f, 0.35850f, 5003), 
	D50_10DEG(0.34773f, 0.35952f, 5003),
	D65_2DEG(0.31271f, 0.32902f, 6504), 
	D65_10DEG(0.31382f, 0.33100f, 6504),
	E(0.33333f, 0.33333f, 5454);
	
	private float relativeX;
	private float relativeY;
	private float relativeZ;
	private float CIEXYZ_X;
	private float CIEXYZ_Y;
	private float CIEXYZ_Z;
	private float u;
	private float v;
	private int temperature;
	
	private Illumination(float x, float y, int temperature) {
		this.relativeX = x;
		this.relativeY = y;
		this.relativeZ = 1.0f-y-x;
		this.temperature = temperature;
		
		this.u = (4*x)/((-2)*x + 12*y +3);
		this.v = (9*y)/((-2)*x + 12*y +3);
		
		this.CIEXYZ_Y = 1.0f;
		this.CIEXYZ_X = this.CIEXYZ_Y * (9*this.u)/(4*this.v);
		this.CIEXYZ_Z = this.CIEXYZ_Y * (12 - 3*this.u - 20*this.v)/(4*this.v);
	}
	
	public double getRelativeX() {
		return this.relativeX;
	}
	
	public double getRelativeY() {
		return this.relativeY;
	}
	
	public double getRelativeZ() {
		return Math.rint(this.relativeZ*10000.0)/10000.0;
	}
	
	public double getCIEXYZ_X() {
		return Math.rint(this.CIEXYZ_X*10000.0)/10000.0;
	}
	
	public double getCIEXYZ_Y() {
		return this.CIEXYZ_Y;
	}
	
	public double getCIEXYZ_Z() {
		return Math.rint(this.CIEXYZ_Z*10000.0)/10000.0;
	}

	public double getU() {
		return Math.rint(this.u*10000.0)/10000.0;
	}
	
	public double getV() {
		return Math.rint(this.v*10000.0)/10000.0;
	}

	public int getTemperature() {
		return this.temperature;
	}
}
```


----------



## Bergtroll (17. Jul 2010)

Achja hier meine Eclipse Scrapbook Page um ein bissi zu spielen:


```
de.jscivision.utils.ColorTable.Illumination illu = de.jscivision.utils.ColorTable.Illumination.D50_2DEG;
System.out.println("u is: "+illu.getU());
System.out.println("v is: "+illu.getV());
System.out.println("X is: "+illu.getCIEXYZ_X());
System.out.println("Y is: "+illu.getCIEXYZ_Y());
System.out.println("Z is: "+illu.getCIEXYZ_Z());

de.jscivision.utils.ColorTable.CIE_LUV_ColorSpace cs = new de.jscivision.utils.ColorTable.CIE_LUV_ColorSpace();
float[] rgbValue = cs.fromRGB(new float[] {1.0f, 1.0f, 0.3f});
String msg = String.format("L* is: %s, u* is: %s, v* is: %s", rgbValue[0], rgbValue[1], rgbValue[2]);
System.out.println( msg );

de.jscivision.utils.ColorTable.CIE_LUV_ColorSpace cs = new de.jscivision.utils.ColorTable.CIE_LUV_ColorSpace();
float[] xyzValue = cs.toCIEXYZ(new float[] {97.645615f, 7.2625346f, 76.91739f});
String msg = String.format("X is: %s, Y is: %s, Z is: %s", xyzValue[0], xyzValue[1], xyzValue[2]);
System.out.println( msg );

de.jscivision.utils.ColorTable.CIE_LUV_ColorSpace cs = new de.jscivision.utils.ColorTable.CIE_LUV_ColorSpace();
float[] rgbValue = cs.toRGB(new float[] {97.645615f, 7.2625346f, 76.91739f});
String msg = String.format("R is: %s, G is: %s, B is: %s", rgbValue[0], rgbValue[1], rgbValue[2]);
System.out.println( msg );
```


----------



## Bergtroll (17. Jul 2010)

Wie immer im Leben eines Programmierers funktioniert es nicht wie erwartet, ich werde also morgen erstmal eine Testklasse schreiben um herauszufinden, wo es hakt...


----------



## Marco13 (17. Jul 2010)

Ohne anmaßend erscheinen zu wollen: Aus der Tatsache, dass ich nur ansatzweise verstehe, worum es dabei überhaupt geht, schließe ich mal ganz frech, dass es ungefähr 6.8 Milliarden anderen Menschen (und nebenbei, aber was viel entscheidender ist, auch 99% der Besucher dieses Forums, und 80% derer, die diesen Thread überhaupt lesen) genauso geht ... 

Bastel' doch mal ein schönes GUI mit Schiebereglern und kontextsensitiver Hilfe und so drum :bae:


----------



## Bergtroll (18. Jul 2010)

Hehe, sollte es in absehbarer Zeit so tun wie ich mir das vorstelle, wird es in JSciVision eingebaut, was dann hier zu finden ist. Projektinteressierte sind übrigens herzlich willkommen, wenngleich auch das ganze in einem eher frühen Stadium ist, aber bald kommen Screenshots. Zwischenzeitlich wäre es schön zu wissen, ob nicht noch jemand nen CIELUV Farbraum angestaubt irgendwo rumliegen hat?


----------



## Bergtroll (18. Jul 2010)

Aaalso, was ich versucht habe ist, einen CIELUV ColorSpace zu bauen, wobei die nötigen Gleichungen der englischen Wiki zu entnehmen sind: CIELUV_color_space. 

Gemacht habe ich das, um einen Farbraum zur Verfügung zu haben, der lineare Veränderungen des Farbortes auf lineare Veränderung des menschlichen Farbempfindens abbildet. Einen einfachen Farbraum wie beispielsweise sRGB kann man hierfür leider nicht nehmen, da lineare Änderungen in solchen als nichtlinear wahrgenommen werden. Der CIELUV hingegen ist ein derart verzerrter CIEXYZ Farbraum, dass eine Reihe linearer Veränderung des Farbortes vom menschlichen Betrachter als Reihe relativ gleichmäßiger Veränderungen empfunden werden.

Was sich zb. mit diesem Farbraum anstellen lässt ist, Raumkurven in diesen zu legen, um diese als Skalen zu verwenden. Wichtig ist so eine Möglichkeit beispielsweise in der wissenschaftlichen Visualisierung, wenn man quantitative Daten durch Farbwerte codieren möchte. Da Mensch Dinge und so auch Farben gerne anordnet, diese insbesondere nach Helligkeit und dann nach Sättigung, sollte man beim farbcodieren darauf achten dass die Farben keine subtile Falschinformation suggerieren. Eine korrekte Kodierung unterstützt hingegen beim Ablesen der Werte, weil eine intuitive Abschätzung der Größenordnung von Werten erleichtert wird.

Da ich seltsamerweise aber nirgendwo einen Java Implementierung von diesem Farbraum gefunden habe, im Gegensatz zu CIELAB, der ein ähnliches Ziel allerdings für Körperfarben verfolgt, habe ich ihn hier selbst implementiert. Gestern hatte ich nen Denkfehler, ich habe beim testen die toCIEXYZ und toRGB mit falschen Eingaben gefüttert und deswegen falsche Rückgabewerte.

Benutzen werde ich das ganze hoffentlich bald zur psychometrischen Farbskalenerzeugung für JSciVision, ihr werdet die Klassen dann wohl im Bundle de.jscivision.utils finden. JSciVision soll eine LGPL Software zum Visualisieren unterschiedlichster wissenschaftlicher Datenreihen werden und befindet sich momentan noch im Alpha Status. JSciVision baut auf Eclipse Equinox und der VisAD Bibliothek auf.


----------



## Marco13 (18. Jul 2010)

Ah ja, JSciVision - ich erinnere mich - und http://www.jscivision.de/ ist inzwischen wohl auch registriert - wenn auch nicht von dir...?!

Ich hatte ja schon in einem früheren Thread erwähnt, dass das Thema an sich ganz interessant ist. Und ich hatte mir das dann auch mal runtergeladen (damals AFAIK noch nicht von Kenai), aber nur relativ kurz drübergeschaut. In seinem universellen Charakter ist das halt schon ein dickes Brett.

Speziell in bezug auf die Farbräume gehen meine Kenntnisse aber auch nicht über das hinaus, was man in den Grafik-Grundlagenvorlesungen so hört (und wovon man dann eigentlich nur RGB und manchmal HSB braucht  ). Ein paar ... erweiterende Informationsbrocken hatte ich zwar noch aus allgemeineren Visualiserungs- und Neurobiologievorlesungen mitgenommen, aber nichts, was man konkret anwenden könnte.

Ein direkter Vergleich zwischen einer Kodierung von ... vielleicht 10 diskreten Werten zwischen 0 und 1, einmal mit HSB und einmal mit diesem ausgefeilten CIELUV wäre mal ganz interessant... man müßte mal schauen, ob man das irgendwie in ein kleines, einfaches GUI pressen kann...


----------



## Bergtroll (18. Jul 2010)

Doch JSciVision.de ist mittlerweile von mir registriert und da kommt, wenn ich viiieeeel mehr Zeit habe, auch ne Projektpage hin. Vom universellen ImageBuilder habe ich mich zwischenzeitlich erstmal verabschiedet, weil VisAD entsprechende Mappingschnittstellen definiert und es mehr Sinn macht, dort einzuhaken. 

Da JSciVision im jetzigen Zustand auch Teil meine Diplomarbeit ist, die ich am besten vor Monaten schon fertig abgegeben hätte, werde ich auf die Schnelle wohl kein einfaches GUI mehr schrauben. Allerdings hoffe ich, dass ich von JSciVision in naher Zeit (kommende Woche?) ne Version online stellen kann, in welcher sich eine CIELUV Skala verwenden lässt. Ich hoffe übrigens selbst, dass aus der ganzen Theorie nicht nur heiße Luft rauskommt, sonst müsste ich mich ärgern... :-D


----------



## Marco13 (18. Jul 2010)

OK, um da den Überblick zu bekommen, müßte man sich wohl erstmal das J3DWorkbench und VisAD näher ansehen (der eigentliche SourceCode ist ja nur für registrierte). Ich vermute, dass die PDF der Diplomarbeit als eine Art "erweiterte High-Level-Doku" dann früher oder später auch auf jscivision.de zu finden sein wird


----------



## Bergtroll (18. Jul 2010)

Ja, sobald die Arbeit bewertet wurde und ich veröffentlichen darf, wird diese auch hochgeladen. Den Verweis auf den J3DWorkbench muss ich überarbeiten, weil ich nun doch eine eigene Equinox Minimalbasis gewählt habe und nur ein paar nette Details übernehmen werde.


----------



## Bergtroll (18. Jul 2010)

So und während ich hier jetzt ne eigene Kurvenklasse implementiere wundere ich mich, ob es so etwas nicht gibt. Java2D liefert ja im geom Paket Konstruktionen für Kurven im karthesischen 2D, irgendwo wirds doch eine Bibliothek für 3 bis ND geben? Aber entweder suche ich falsch, oder ich liege falsch. Für Hinweise auf ne ordentlich vordesignte Bibliothek bin ich dankbar


----------



## Marco13 (18. Jul 2010)

Nicht dass ich wüßte. Ich hatte irgendwann auch mal angefangen, eine Bezierkurvenklasse zu machen, weil was es bei Java2(!)D mit GeneralPath und CURVE_TO und so gibt ist (gelinde gesagt) unhandlich... Es gibt sicher Bibliotheken, wo das eine oder andere drin ist - im TimingFramework gibt's Interpolatoren, genau wie in Java3D an sich (zusammen mit Vecmath für Point3D und so), aber eine einzelne, kompakte, dedizierte "Kurven-Library" (insbesondere für solche, die nicht aus einzelnen Punkten bestehen) kenne ich nicht (hab' aber jetzt keine dedizierte Websuche darüber gemacht).


----------



## Bergtroll (21. Jul 2010)

So also Kurve ist selbst implementiert und jetzt gibts auch mal erste Screenshots, zu sehen ist eine Magentaskala, eine Falschfarbenskala und eine psychometrische Skala. Nur selber Software ausprobieren iss noch nicht, weil ich noch keine Zeit hatte, die ganzen Datensätze hochzuladen...

Screenshot 1
Screenshot 2


Mfg,
Bergtroll


----------



## Marco13 (21. Jul 2010)

Ich sehe was... aber WAS, da bin ich mir nicht sicher  Bei den letzten Beiden sind gar keine Verläufe erkennbar ???:L


----------



## Bergtroll (21. Jul 2010)

ja das ist mir auch zuerst mal aufgefallen, dass die farbunterschiede eigentlich nur auf der magentaskala rauskommen, obwohl sie insgesamt am dunkelsten ist. Andererseits ja auch nicht verwunderlich, weil da die hellempfindlichkeit höher ist. Ich stelle bald mal die direkten Volumenrendering Sachen hier ein, dann kann man mehr sagen...


----------



## Bergtroll (23. Jul 2010)

So, wie versprochen ein paar wenige mehr Screenis online:

JSciVision: Wiki: Home &mdash; Project Kenai


----------

