Dokumentation zu Beispiel 1 der LU Visualisierung (Ray Casting)
by Christoph Krc (MatrNr. 9125103)

Für die Realisierung der Aufgabe standen ein Datensatz eine Kopfes sowie der Artikel
"Display of Surfaces from Volume Data" von Marc Levoy zur Verfügung.

Dieser Artikel geht auf die Darstellung einzelner Schichten gleicher Dichte sowie die Darstellung von Dichtemengen 
mit unterschiedlichen Alpha-Werten samt Schattierung ein.

Nicht behandelt wird das kolorieren bestimmter Dichtemengen mit verschiedenen Farben.

Hier ergibt sich auch das erste Problem, wie kombiniert man die Farben die sich durch die Schattierung ergeben mit 
den Farben die die Kolorierung vorschreibt ?

Mein Lösungsansatz ignoriert die Farbe der Lichtquelle und reduziert die Schattierungsfarbe auf einen 
Helligkeitswert, der dann auf die Kolorierungsfarbe angewandt wird.

Das zweite Problem war die Trilineare Interpolation von Farbwerten mit Alpha-Wert.
Mein Ansatz sieht folgendermaßen aus:

void KColor::TrilinearInterpolation(
  const KColor &c000, const KColor &c100,
  const KColor &c010, const KColor &c110,
  const KColor &c001, const KColor &c101,
  const KColor &c011, const KColor &c111,
  double x, double y, double z)
{
  double a1=c000.GetAlphaD()*(1-x)*(1-y)*(1-z);
  double a2=c100.GetAlphaD()*   x *(1-y)*(1-z);
  double a3=c010.GetAlphaD()*(1-x)*   y *(1-z);
  double a4=c110.GetAlphaD()*   x *   y *(1-z);
  double a5=c001.GetAlphaD()*(1-x)*(1-y)*   z ;
  double a6=c101.GetAlphaD()*   x *(1-y)*   z ;
  double a7=c011.GetAlphaD()*(1-x)*   y *   z ;
  double a8=c111.GetAlphaD()*   x *   y *   z ;

  Set(c000*a1+c100*a2+c010*a3+c110*a4+c001*a5+c101*a6+c011*a7+c111*a8);
  double alpha=a1+a2+a3+a4+a5+a6+a7+a8;
  if (alpha!=0.0) (*this)/=alpha;
  SetAlpha(alpha);
  Normalize();
}

Das Programm ist in C++ geschrieben und verwendet exzessiv Klassen, sowie die MFC.
Die wichtigsten Klassen, die hier zu erwähnen wären sind:

KColor
Diese Klasse kann einen Farbwert der Form RGBA speichern und verschiedene Operationen darauf durchführen.

KRayCasting:
Hier geschieht die eigentliche Arbeit, man kann einen Winkel übergeben, um den Kopf zu drehen und dann für 
einzelne 2D-Koordinaten den Farbwert abfragen.
Das laden der Daten, die Matrizenmanipulationen, die Schattierung und das Raycasting finden hier statt.

CRayCastingView:
Die MFC-View:
Hier wird das Bild im Speicher in einem eigenem Thread aufgebaut (FillBitmap), das Bild bei Bedarf dargestellt 
(OnDraw) und abgespeichert (SaveBmp).
Standardmäßig werden nacheinander 24 Bilder berechnet und abgespeichert, wobei der Winkel um die Y-Achse 
jeweils um 15 Grad erhöht wird.


Das GUI:

Im Setting-Dialog kann man die Wrte für das Shading sowie die Position der Lichtquelle angeben.
Weiters kann man die Rotation um X und Z-Achse angeben die vor der Berechnung durchgeführt wird.
Für die Rotation um die Y-Achse ist eine Wertebereich möglich, sodaß in einem Durchlauf mehrere Bilder berechnet werden.
Die Größe des berechneten Bildes wird durch die angegebene Skalierung bestimmt.

Da ich nur zwei verschiedene zusammengehörige Dichtebereiche ausfindig machen konnte wurden diese fix Codiert (Knochen, Gewebe).
Für beide Bereiche kann man Farbe und Alpha-Wert frei einstellen.




Das Ergebnis der Bemühungen sieht dann so aus: