<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>IOException.de &#187; Raimar Wagner</title>
	<atom:link href="http://www.ioexception.de/author/raimar-wagner/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ioexception.de</link>
	<description>Ausgewählter Nerdkram von Informatikstudenten der Uni Ulm</description>
	<lastBuildDate>Fri, 13 Jan 2012 07:38:26 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Histogramplot in Sage/Matplotlib</title>
		<link>http://www.ioexception.de/2010/06/23/histogramplot-in-sagematplotlib/</link>
		<comments>http://www.ioexception.de/2010/06/23/histogramplot-in-sagematplotlib/#comments</comments>
		<pubDate>Wed, 23 Jun 2010 15:35:37 +0000</pubDate>
		<dc:creator>Raimar Wagner</dc:creator>
				<category><![CDATA[allgemein]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[sage]]></category>

		<guid isPermaLink="false">http://www.ioexception.de/?p=583</guid>
		<description><![CDATA[Wer Matlab mag wird Sage lieben, insbesondere wenn die Ausgangsdaten sowieso in Python vorliegen. Ein einfaches Histogram für Ganzzahlen lässt sich wie folgt realisieren:


from sage.all import *
import numpy
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab

def plot_hist(subplot,name,x_data,x_var,y_var,b_width):

  #create array
  n_array = numpy.array(x_data)

  #labels
  subplot.set_xlabel('variable '+x_var+' [min = '+str(n_array.min())+', max='+str(n_array.max())+' ]')
  subplot.set_ylabel(y_var)

  [...]]]></description>
			<content:encoded><![CDATA[<p>Wer Matlab mag wird <a href="http://www.google.de/url?sa=t&#038;source=web&#038;cd=6&#038;ved=0CDwQFjAF&#038;url=http%3A%2F%2Fwww.sagemath.org%2F&#038;ei=pCkiTMXtLOCjOMmB5Ww&#038;usg=AFQjCNH2NWozNkiq8T27uN3RaNnZUvWksg&#038;sig2=nOCuPFF0dZhBMyAPyuXZ9Q">Sage</a> lieben, insbesondere wenn die Ausgangsdaten sowieso in Python vorliegen. Ein einfaches Histogram für Ganzzahlen lässt sich wie folgt realisieren:</p>
<pre class="brush: python;">

from sage.all import *
import numpy
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab

def plot_hist(subplot,name,x_data,x_var,y_var,b_width):

  #create array
  n_array = numpy.array(x_data)

  #labels
  subplot.set_xlabel('variable '+x_var+' [min = '+str(n_array.min())+', max='+str(n_array.max())+' ]')
  subplot.set_ylabel(y_var)

  #create bins
  mmin = n_array.min()
  mmax = n_array.max()
  b = numpy.arange(mmin-(1.0/2),mmax+1+(1.0/2))

  #set ticks
  subplot.set_xticks(b)

  #hist
  n, bins, patches = subplot.hist(x_data,bins=b, rwidth=b_width)

  #title
  subplot.set_title(r'Histogram of '+x_var)
</pre>
<p>Benutzt wird das Ganze dann mittels:</p>
<pre class="brush: python;">
f = matplotlib.pyplot.figure()
a = f.add_subplot(111)

plot_utils.plot_hist(a,'Decimals', [1,1,1,2,2,3,3,3,4,4,5,5,6,6,7,7],'decimal','# of decimals',0.8)

matplotlib.pyplot.savefig('plot.png')
</pre>
<p><a href="http://www.ioexception.de/wp-content/uploads/2010/06/plot.png"><img src="http://www.ioexception.de/wp-content/uploads/2010/06/plot-300x225.png" alt="" title="plot" width="300" height="225" class="alignnone size-medium wp-image-585" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ioexception.de/2010/06/23/histogramplot-in-sagematplotlib/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>eBay Suchergebnisse in Yahoo Pipes bündeln</title>
		<link>http://www.ioexception.de/2010/03/26/ebay-suchergebnisse-in-yahoo-pipes-bundeln/</link>
		<comments>http://www.ioexception.de/2010/03/26/ebay-suchergebnisse-in-yahoo-pipes-bundeln/#comments</comments>
		<pubDate>Fri, 26 Mar 2010 17:09:33 +0000</pubDate>
		<dc:creator>Raimar Wagner</dc:creator>
				<category><![CDATA[allgemein]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.ioexception.de/?p=496</guid>
		<description><![CDATA[Bei der Möbelsuche auf eBay stößt man oft auf den Umstand dass nur selten die gesuchten Artikel vorhanden sind und wenn nicht in abholbarer Reichweite. Da eBay inzwischen die Möglichkeit bietet jedes Suchergebnis als RSS Feed abzurufen schreit das förmlich nach einer Verarbeitung mit Yahoo Pipes. 
Der grundsätzliche Aufbau ist trivial:

Einbau von PLZ und Umkreis [...]]]></description>
			<content:encoded><![CDATA[<p>Bei der Möbelsuche auf eBay stößt man oft auf den Umstand dass nur selten die gesuchten Artikel vorhanden sind und wenn nicht in abholbarer Reichweite. Da eBay inzwischen die Möglichkeit bietet jedes Suchergebnis als RSS Feed abzurufen schreit das förmlich nach einer Verarbeitung mit <a href="http://pipes.yahoo.com">Yahoo Pipes</a>. </p>
<p>Der grundsätzliche Aufbau ist trivial:</p>
<ul>
<li>Einbau von PLZ und Umkreis in die Suchergebnis URI</li>
<li>Fetchen der Suchergebnis URI</li>
<li>Ergebnisse zusammenfassen</li>
<li>Ergebnisse sortieren</li>
</ul>
<p>In Yahoo Pipes sieht das dann wie folgt aus:</p>
<p><a href="http://www.ioexception.de/wp-content/uploads/2010/03/pipes.png"><img src="http://www.ioexception.de/wp-content/uploads/2010/03/pipes-300x118.png" alt="Yahoo Pipes" title="Yahoo Pipes" width="300" height="118" class="alignnone size-medium wp-image-497" /></a></p>
<p>Nun hat man alle Suchergebnisse zusammengefasst als praktischen RSS Feed.  <a href="http://pipes.yahoo.com/d33r/78dd0f4d427fc8a964c879ca3e442b19">Meine bisherige Version</a> hat nur die Suche nach &#8220;Ikea&#8221;, die Büromöbel Kategorie und einige andere Suchen eingebunden. Erweiterungen sind gerne gesehen! </p>
]]></content:encoded>
			<wfw:commentRss>http://www.ioexception.de/2010/03/26/ebay-suchergebnisse-in-yahoo-pipes-bundeln/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Einführung in C Linker, Compiler, Preprocessor und mehr</title>
		<link>http://www.ioexception.de/2009/12/05/einfuhrung-in-c-linker-compiler-preprocessor-und-mehr/</link>
		<comments>http://www.ioexception.de/2009/12/05/einfuhrung-in-c-linker-compiler-preprocessor-und-mehr/#comments</comments>
		<pubDate>Sat, 05 Dec 2009 17:39:04 +0000</pubDate>
		<dc:creator>Raimar Wagner</dc:creator>
				<category><![CDATA[c++]]></category>
		<category><![CDATA[betriebssysteme]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Compiler]]></category>
		<category><![CDATA[Linker]]></category>

		<guid isPermaLink="false">http://www.ioexception.de/?p=363</guid>
		<description><![CDATA[Die Einführungsvorlesung &#8220;Computer Science 50: Introduction to Computer Science I&#8221; von Harvard College hat sehr gut gemachte Vorlesungen als Flash Video online, insbesondere die Vorlesungen über die C Grundlagen sind wirklich schön. 
Meine Empfehlungen:

Week 8. Huffman coding. Preprocessing. Compiling. Assembling. Linking. CPUs. Ant-8. 

Vorlesung 1
Vorlesung 2


Week 9. Writing secure C code. Buffer overruns. Dangerous functions.

]]></description>
			<content:encoded><![CDATA[<p>Die Einführungsvorlesung <a href="http://cs50.tv/">&#8220;Computer Science 50: Introduction to Computer Science I&#8221;</a> von <a href="http://en.wikipedia.org/wiki/Harvard_College">Harvard College</a> hat sehr gut gemachte Vorlesungen als Flash Video online, insbesondere die Vorlesungen über die C Grundlagen sind wirklich schön. </p>
<p><strong>Meine Empfehlungen:</strong></p>
<ul>
<li>Week 8. Huffman coding. Preprocessing. Compiling. Assembling. Linking. CPUs. Ant-8. </p>
<ul>
<li><a href="http://www.courses.fas.harvard.edu/~cs50/play/podcasts/2007/lectures/week8w.flv">Vorlesung 1</a></li>
<li><a href="http://www.courses.fas.harvard.edu/~cs50/play/podcasts/2007/lectures/week8f.flv">Vorlesung 2</a></li>
</ul>
</li>
<li>Week 9. Writing secure C code. Buffer overruns. Dangerous functions.
<ul>
<li><a href=http://www.courses.fas.harvard.edu/~cs50/play/podcasts/2007/lectures/week9m.flv">Vorlesung 1</a></li>
</ul>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.ioexception.de/2009/12/05/einfuhrung-in-c-linker-compiler-preprocessor-und-mehr/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vektorfeldvisualisierung durch Flow Streams</title>
		<link>http://www.ioexception.de/2009/07/28/vektorfeldvisualisierung-durch-flow-streams/</link>
		<comments>http://www.ioexception.de/2009/07/28/vektorfeldvisualisierung-durch-flow-streams/#comments</comments>
		<pubDate>Tue, 28 Jul 2009 15:45:49 +0000</pubDate>
		<dc:creator>Raimar Wagner</dc:creator>
				<category><![CDATA[visualisierungen]]></category>
		<category><![CDATA[tcl]]></category>
		<category><![CDATA[visualisierung]]></category>
		<category><![CDATA[vtk]]></category>

		<guid isPermaLink="false">http://www.ioexception.de/?p=278</guid>
		<description><![CDATA[In einem vorherigen Artikel hatte ich bereits über Visualisierungen von Vektorfeldern geschrieben, hier werden wir ein identisches Vektorfeld nutzen. Unser Beispielfeld ist wieder:

Wir setzen wieder gridPoints, glyPoints als gegeben vorraus. Des weiteren können wir auch wieder ein Magnituden-Array mag und ein Beschleunigungs-3Tupel-Array velocity als gegeben vorraussetzen:

vtkPoints gridPoints
vtkPoints glyPoints

vtkFloatArray velocity
  velocity SetNumberOfComponents 3
  velocity [...]]]></description>
			<content:encoded><![CDATA[<p>In einem vorherigen Artikel hatte ich bereits über Visualisierungen von Vektorfeldern geschrieben, hier werden wir ein identisches Vektorfeld nutzen. Unser Beispielfeld ist wieder:</p>
<p><img src="http://l.wordpress.com/latex.php?latex=%20V%20%3D%20x%5E2%2Ay%2A%20e_1%20%20%2B%202%20%2A%20x%20%2A%20y%5E2%20%2A%20z%20%2A%20e_2%20%2B%20y%2A%20z%5E3%20%2A%20e_3%20&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title=" V = x^2*y* e_1  + 2 * x * y^2 * z * e_2 + y* z^3 * e_3 " style="vertical-align:-20%;" class="tex" alt=" V = x^2*y* e_1  + 2 * x * y^2 * z * e_2 + y* z^3 * e_3 " /></p>
<p>Wir setzen wieder <code>gridPoints</code>, <code>glyPoints</code> als gegeben vorraus. Des weiteren können wir auch wieder ein Magnituden-Array <code>mag </code>und ein Beschleunigungs-3Tupel-Array <code>velocity </code>als gegeben vorraussetzen:</p>
<pre class="brush: perl;">
vtkPoints gridPoints
vtkPoints glyPoints

vtkFloatArray velocity
  velocity SetNumberOfComponents 3
  velocity SetNumberOfValues [expr $x_extend*$y_extend*$z_extend]

vtkFloatArray mag
  mag SetNumberOfComponents 1
  mag SetNumberOfValues [expr $x_extend*$y_extend*$z_extend]
</pre>
<p>Im nächsten Schritt erzeugen wir wieder aus den Punkten und den zwei Arrays ein strukturiertes Gitter.</p>
<pre class="brush: perl;">
vtkStructuredGrid sgrid
  sgrid SetDimensions $x_extend $y_extend $z_extend
  sgrid SetPoints gridPoints
  [sgrid GetPointData] SetVectors velocity
  [sgrid GetPointData] SetScalars mag
</pre>
<p>Damit wäre die Definition des Feldes abgeschlossen, als erstes müssen die die Streams einen Startpunkt bekommen. In unserem Fall nehmen wir eine Linie auf der die Streams starten sollen.</p>
<pre class="brush: perl;">

vtkLineSource rake
  rake SetPoint1 1 9 9
  rake SetPoint2 9 9  9
  rake SetResolution 200
</pre>
<p>Der <a href="http://www.creatis.univ-lyon1.fr/~jpr/PUBLIC/Doc_VTK_5.0.4/html/a02050.html"><code>vtkStreamTracer</code></a> wird im nächsten Schritt die Stromlinien erzeugen die dann mit einem <a href="http://www.vtk.org/doc/release/4.0/html/classvtkTubeFilter.html"><code>vtkTubeFilter</code></a> dargestellt werden.  </p>
<pre class="brush: perl;">
vtkRungeKutta4 integ
vtkStreamTracer streamer
    streamer SetInput sgrid
    streamer SetSourceConnection [rake GetOutputPort]
    streamer SetMaximumPropagation 5000
    streamer SetMaximumPropagationUnitToTimeUnit
    streamer SetInitialIntegrationStep 0.005
    streamer SetInitialIntegrationStepUnitToCellLengthUnit
    streamer SetIntegrationDirectionToBoth
    streamer SetIntegrator integ

vtkTubeFilter streamTube
    streamTube SetInputConnection [streamer GetOutputPort]
    streamTube SetRadius 0.1
    streamTube SetNumberOfSides 12
</pre>
<p>Im letzten Schritt muss nurnoch alles in Mapper und Aktoren gepackt werden (siehe frühere Posts) und wir bekommen das folgende Bild:</p>
<p><img src="http://www.ioexception.de/wp-content/uploads/2009/07/flow.jpg" alt="flow" title="flow" width="328" height="274" class="alignnone size-full wp-image-279" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ioexception.de/2009/07/28/vektorfeldvisualisierung-durch-flow-streams/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Die VTK Renderpipeline am Beispiel eines Oktaeders</title>
		<link>http://www.ioexception.de/2009/07/03/vtk_renderpipeline/</link>
		<comments>http://www.ioexception.de/2009/07/03/vtk_renderpipeline/#comments</comments>
		<pubDate>Fri, 03 Jul 2009 21:31:05 +0000</pubDate>
		<dc:creator>Raimar Wagner</dc:creator>
				<category><![CDATA[visualisierungen]]></category>
		<category><![CDATA[tcl]]></category>
		<category><![CDATA[visualisierung]]></category>
		<category><![CDATA[vtk]]></category>

		<guid isPermaLink="false">http://www.ioexception.de/?p=199</guid>
		<description><![CDATA[Die VTK Renderpipeline ist im Gegensatz zu traditionellen Grafikpipelines weniger auf Rasterung, Beleuchtung, Clipping, &#8230; fokussiert sondern setzt den Schwerpunkt auf das Aufbereiten, Verändern und Repräsentieren von Eingabedaten. Die traditionelle Renderpipeline wird von dem Benutzer soweit wie möglich versteckt. Zu beachten ist dass die Pipeline von der Senke zur Quelle getriggert wird, falls jedoch in [...]]]></description>
			<content:encoded><![CDATA[<p>Die VTK Renderpipeline ist im Gegensatz zu traditionellen Grafikpipelines weniger auf Rasterung, Beleuchtung, Clipping, &#8230; fokussiert sondern setzt den Schwerpunkt auf das Aufbereiten, Verändern und Repräsentieren von Eingabedaten. Die traditionelle Renderpipeline wird von dem Benutzer soweit wie möglich versteckt. Zu beachten ist dass die Pipeline von der Senke zur Quelle getriggert wird, falls jedoch in einem vorherigen Modul eine Eingabedatenänderung vorgenommen wird, muss für eine aktuelle Darstellung das jeweilige Modul manuell mittels <code>Update</code> getriggert werden.<br />
<br/><br />
<img src="http://l.wordpress.com/latex.php?latex=%20%5Cbegin%7Bbmatrix%7D%20%5Ctext%7B%20%5Ctextbf%7BQuelle%7D%20%7D%20%20%5C%5C%20%5Ctext%7BDatenbasis%20f%5C%22%7Bu%7Dr%20die%20Visualisierung%7D%20%20%5Cend%7Bbmatrix%7D%20&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title=" \begin{bmatrix} \text{ \textbf{Quelle} }  \\ \text{Datenbasis f\"{u}r die Visualisierung}  \end{bmatrix} " style="vertical-align:-20%;" class="tex" alt=" \begin{bmatrix} \text{ \textbf{Quelle} }  \\ \text{Datenbasis f\"{u}r die Visualisierung}  \end{bmatrix} " /></p>
<p>Dieser Teil der Pipeline bearbeitet und repräsentiert die Eingabedaten. In unserem Fall repräsentieren wir den Oktaeder aus Punkten, Flächen zwischen den Punkten und Farbangaben für jeden Punkt. In den VTK Tcl Bindings sieht das wie folgt aus:</p>
<pre class="brush: perl;">
#holds all points
vtkPoints points

points SetNumberOfPoints 6

#insert all points
points InsertPoint 0 1.0 0.0 0.0
#[...]
points InsertPoint 5 0.0 0.0 -1.0

#holds all faces
vtkCellArray polys

polys InsertNextCell 3
   polys InsertCellPoint 0
   polys InsertCellPoint 3
   polys InsertCellPoint 4
#[...]
polys InsertNextCell 3
   polys InsertCellPoint 2
   polys InsertCellPoint 0
   polys InsertCellPoint 5

#set color to i for each face
vtkFloatArray vertexScalars
   for { set i 0 } { $i &lt; 6 } { incr i } {
vertexScalars InsertTuple1 $i $i
}
</pre>
<p><br/><br />
<img src="http://l.wordpress.com/latex.php?latex=%20%5Cbegin%7Bbmatrix%7D%20%5Ctext%7B%20%5Ctextbf%7BQuelle%7D%20%7D%20%20%5C%5C%20%5Ctext%7BDatenbasis%20f%5C%22%7Bu%7Dr%20die%20Visualisierung%7D%20%20%5Cend%7Bbmatrix%7D%20%5Crightarrow%20%20%5Cbegin%7Bbmatrix%7D%20%5Ctext%7B%20%5Ctextbf%7BFilter%7D%20%7D%20%20%5C%5C%20%5Ctext%7BDaten-%20und%20Datenstrommodifikation%7D%20%20%5Cend%7Bbmatrix%7D%20&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title=" \begin{bmatrix} \text{ \textbf{Quelle} }  \\ \text{Datenbasis f\"{u}r die Visualisierung}  \end{bmatrix} \rightarrow  \begin{bmatrix} \text{ \textbf{Filter} }  \\ \text{Daten- und Datenstrommodifikation}  \end{bmatrix} " style="vertical-align:-20%;" class="tex" alt=" \begin{bmatrix} \text{ \textbf{Quelle} }  \\ \text{Datenbasis f\"{u}r die Visualisierung}  \end{bmatrix} \rightarrow  \begin{bmatrix} \text{ \textbf{Filter} }  \\ \text{Daten- und Datenstrommodifikation}  \end{bmatrix} " /></p>
<p>In unserem Fall besteht der Filter daraus dass alle Eingabedaten (Punkte, Flächen, &#8230;) zusammengesetzt werden müssen. </p>
<pre class="brush: perl;">
vtkPolyData octahedron
   octahedron SetPoints points
   octahedron SetPolys polys
   [octahedron GetPointData] SetScalars vertexScalars
</pre>
<p><br/><br />
<img src="http://l.wordpress.com/latex.php?latex=%20%5Cbegin%7Bbmatrix%7D%20%5Ctext%7B%20%5Ctextbf%7BFilter%7D%20%7D%20%20%5C%5C%20%5Ctext%7BDaten-%20und%20Datenstrommodifikation%7D%20%20%5Cend%7Bbmatrix%7D%20%5Crightarrow%5Cbegin%7Bbmatrix%7D%20%5Ctext%7B%20%5Ctextbf%7BMapper%7D%20%7D%20%20%5C%5C%20%5Ctext%7BErzeugen%20der%20Grafikobjekte%7D%20%20%5Cend%7Bbmatrix%7D%20&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title=" \begin{bmatrix} \text{ \textbf{Filter} }  \\ \text{Daten- und Datenstrommodifikation}  \end{bmatrix} \rightarrow\begin{bmatrix} \text{ \textbf{Mapper} }  \\ \text{Erzeugen der Grafikobjekte}  \end{bmatrix} " style="vertical-align:-20%;" class="tex" alt=" \begin{bmatrix} \text{ \textbf{Filter} }  \\ \text{Daten- und Datenstrommodifikation}  \end{bmatrix} \rightarrow\begin{bmatrix} \text{ \textbf{Mapper} }  \\ \text{Erzeugen der Grafikobjekte}  \end{bmatrix} " /></p>
<p>Im Mapper wird die eigentlich Repräsentation erzeugt, in unserem Fall ist nurnoch eine Bereichsangabe für die Skalare notwendig.</p>
<pre class="brush: perl;">
vtkPolyDataMapper octahedronMapper
   octahedronMapper SetInput octahedron
   octahedronMapper SetScalarRange 0 7
</pre>
<p><br/><br />
<img src="http://l.wordpress.com/latex.php?latex=%20%5Cbegin%7Bbmatrix%7D%20%5Ctext%7B%20%5Ctextbf%7BMapper%7D%20%7D%20%20%5C%5C%20%5Ctext%7BErzeugen%20der%20Grafikobjekte%7D%20%20%5Cend%7Bbmatrix%7D%20%5Crightarrow%20%20%5Cbegin%7Bbmatrix%7D%20%5Ctext%7B%20%5Ctextbf%7BActor%7D%20%7D%20%20%5C%5C%20%5Ctext%7BRepr%5C%22%7Ba%7Dsentationsparameter%7D%20%20%5Cend%7Bbmatrix%7D%20&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title=" \begin{bmatrix} \text{ \textbf{Mapper} }  \\ \text{Erzeugen der Grafikobjekte}  \end{bmatrix} \rightarrow  \begin{bmatrix} \text{ \textbf{Actor} }  \\ \text{Repr\"{a}sentationsparameter}  \end{bmatrix} " style="vertical-align:-20%;" class="tex" alt=" \begin{bmatrix} \text{ \textbf{Mapper} }  \\ \text{Erzeugen der Grafikobjekte}  \end{bmatrix} \rightarrow  \begin{bmatrix} \text{ \textbf{Actor} }  \\ \text{Repr\"{a}sentationsparameter}  \end{bmatrix} " /></p>
<p>Im Actor werden die Parameter der Datenrepräsentation spezifiziert, meist sind das klassische Computergraphikparameter wie Beleuchtung, Transparenz, &#8230;</p>
<pre class="brush: perl;">
vtkActor octahedronActor
   octahedronActor SetMapper octahedronMapper
</pre>
<p><br/><br />
<img src="http://l.wordpress.com/latex.php?latex=%20%5Cbegin%7Bbmatrix%7D%20%5Ctext%7B%20%5Ctextbf%7BActor%7D%20%7D%20%20%5C%5C%20%5Ctext%7BRepraesentationsparameter%7D%20%20%5Cend%7Bbmatrix%7D%20%20%20%5Crightarrow%20%5Cbegin%7Bbmatrix%7D%20%5Ctext%7B%20%5Ctextbf%7BRenderer%20%5C%26Fenster%7D%20%7D%20%20%5C%5C%20%5Ctext%7BZeigt%20alle%20Actoren%20an%7D%20%20%5Cend%7Bbmatrix%7D%20%20&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title=" \begin{bmatrix} \text{ \textbf{Actor} }  \\ \text{Repraesentationsparameter}  \end{bmatrix}   \rightarrow \begin{bmatrix} \text{ \textbf{Renderer \&#038;Fenster} }  \\ \text{Zeigt alle Actoren an}  \end{bmatrix}  " style="vertical-align:-20%;" class="tex" alt=" \begin{bmatrix} \text{ \textbf{Actor} }  \\ \text{Repraesentationsparameter}  \end{bmatrix}   \rightarrow \begin{bmatrix} \text{ \textbf{Renderer \&#038;Fenster} }  \\ \text{Zeigt alle Actoren an}  \end{bmatrix}  " /></p>
<p>In diesem Teil werden alle Actors einen Renderer zugewiesen und über ein Fenster gezeichnet. </p>
<pre class="brush: perl;">
vtkRenderer ren1
   ren1 AddActor octahedronActor
   ren1 SetBackground 0.1 0.2 0.4

vtkRenderWindow renWin
   renWin AddRenderer ren1
   renWin SetSize 300 300

vtkRenderWindowInteractor iren
   iren SetRenderWindow renWin

vtkInteractorStyleTrackballCamera style
   iren SetInteractorStyle style

iren AddObserver UserEvent {wm deiconify .vtkInteract}

iren Initialize

wm withdraw .
</pre>
<p>Die Interaktionskomponenten die noch initialisiert werden sind nicht direkt Teil der Pipeline sondern nebenläufige Module.<br />
<br/><br />
Die komplette VTK Pipeline sieht am Ende wie folgt aus:</p>
<p><img src="http://l.wordpress.com/latex.php?latex=%20%5Cbegin%7Bbmatrix%7D%20%5Ctext%7B%20%5Ctextbf%7BQuelle%7D%20%7D%20%20%5Cend%7Bbmatrix%7D%20%20%20%5Crightarrow%20%5Cbegin%7Bbmatrix%7D%20%5Ctext%7B%20%5Ctextbf%7BFilter%7D%20%7D%20%20%5Cend%7Bbmatrix%7D%20%20%20%5Crightarrow%20%5Cbegin%7Bbmatrix%7D%20%5Ctext%7B%20%5Ctextbf%7BMapper%7D%20%7D%20%20%5Cend%7Bbmatrix%7D%20%20%20%5Crightarrow%20%5Cbegin%7Bbmatrix%7D%20%5Ctext%7B%20%5Ctextbf%7BActor%7D%20%7D%20%20%5Cend%7Bbmatrix%7D%20%20%20%5Crightarrow%20%5Cbegin%7Bbmatrix%7D%20%5Ctext%7B%20%5Ctextbf%7BRenderer%20%5C%26%20Fenster%7D%20%7D%20%20%5Cend%7Bbmatrix%7D%20%20%20&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title=" \begin{bmatrix} \text{ \textbf{Quelle} }  \end{bmatrix}   \rightarrow \begin{bmatrix} \text{ \textbf{Filter} }  \end{bmatrix}   \rightarrow \begin{bmatrix} \text{ \textbf{Mapper} }  \end{bmatrix}   \rightarrow \begin{bmatrix} \text{ \textbf{Actor} }  \end{bmatrix}   \rightarrow \begin{bmatrix} \text{ \textbf{Renderer \&#038; Fenster} }  \end{bmatrix}   " style="vertical-align:-20%;" class="tex" alt=" \begin{bmatrix} \text{ \textbf{Quelle} }  \end{bmatrix}   \rightarrow \begin{bmatrix} \text{ \textbf{Filter} }  \end{bmatrix}   \rightarrow \begin{bmatrix} \text{ \textbf{Mapper} }  \end{bmatrix}   \rightarrow \begin{bmatrix} \text{ \textbf{Actor} }  \end{bmatrix}   \rightarrow \begin{bmatrix} \text{ \textbf{Renderer \&#038; Fenster} }  \end{bmatrix}   " /></p>
<p>und das Ergebnis in den Tcl Bindings:</p>
<p><img src="http://www.ioexception.de/wp-content/uploads/2009/07/okt.jpg" alt="okt" title="okt" width="308" height="334" class="alignnone size-full wp-image-255" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ioexception.de/2009/07/03/vtk_renderpipeline/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Videoexport aus VTK mittels vtkAVIWriter</title>
		<link>http://www.ioexception.de/2009/06/23/videoexport-aus-vtk-mittels-vtkaviwriter/</link>
		<comments>http://www.ioexception.de/2009/06/23/videoexport-aus-vtk-mittels-vtkaviwriter/#comments</comments>
		<pubDate>Tue, 23 Jun 2009 20:55:44 +0000</pubDate>
		<dc:creator>Raimar Wagner</dc:creator>
				<category><![CDATA[visualisierungen]]></category>
		<category><![CDATA[tcl]]></category>
		<category><![CDATA[visualisierung]]></category>
		<category><![CDATA[vtk]]></category>

		<guid isPermaLink="false">http://www.ioexception.de/?p=169</guid>
		<description><![CDATA[Um eine interessante Animation in VTK als Video zu exportieren bietet sich der vtkAVIWriter an. Dieser Filter kann Animation als .avi Datei rausschreiben. Wieder kommt hier VTK in den Tcl Bindings zum Einsatz, die Übertragung auf andere Bindings sollte aber 1:1 möglich sein. An das Ende der Filterkette hängen wir mit dem vtkWindowToImageFilter, einen Filter [...]]]></description>
			<content:encoded><![CDATA[<p>Um eine interessante Animation in <a href="http://www.vtk.org/">VTK</a> als Video zu exportieren bietet sich der <code><a href="http://www.vtk.org/doc/release/5.0/html/a01171.html">vtkAVIWriter</a></code> an. Dieser Filter kann Animation als .avi Datei rausschreiben. Wieder kommt hier VTK in den Tcl Bindings zum Einsatz, die Übertragung auf andere Bindings sollte aber 1:1 möglich sein. An das Ende der Filterkette hängen wir mit dem <code><a href="http://www.vtk.org/doc/release/4.0/html/classvtkWindowToImageFilter.html">vtkWindowToImageFilter</a></code>, einen Filter der das Bild eines <code>vtkRenderWindow</code> aus der momentanen Fensterdarstellung extrahiert. </p>
<pre class="brush: perl;">
vtkRenderWindow renderW

#[ ... ]

vtkWindowToImageFilter imageF
  imageF SetInput renderW
</pre>
<p>Im nächsten Schritt kommt der <code>vtkAVIWriter </code>zum Einsatz, nach der Initialisierung wird nach jedem Frame die Filterkette aktualisiert und der aktuelle Frame rausgeschrieben. Nach dem letzten Frame wird der <code>vtkAVIWriter </code>gestoppt.</p>
<pre class="brush: perl;">
vtkAVIWriter aviW
  aviW SetFileName &quot;animation.avi&quot;
  aviW SetInputConnection [imageF GetOutputPort]
  aviW Start

for {set k 0} {$k&lt;$frames} {incr k} {

  #do computation

  #render window
  renderW Render
  #call modified at filter
  imageF Modified
  #write frame
  aviW Write

}
#end of animation
aviW End
</pre>
<p>Für ein Beispiel siehe <a href="http://www.ioexception.de/2009/06/21/visualisierung-von-winkelgeschwindigkeiten-in-vektorfeldern/">&#8220;Visualisierung von Winkelgeschwindigkeiten in Vektorfeldern&#8221;</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ioexception.de/2009/06/23/videoexport-aus-vtk-mittels-vtkaviwriter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ein einfacher Scheduler in C++ — Teil 2: Scheduler</title>
		<link>http://www.ioexception.de/2009/06/23/ein-einfacher-scheduler-in-c-%e2%80%94-teil-2-scheduler/</link>
		<comments>http://www.ioexception.de/2009/06/23/ein-einfacher-scheduler-in-c-%e2%80%94-teil-2-scheduler/#comments</comments>
		<pubDate>Tue, 23 Jun 2009 20:05:06 +0000</pubDate>
		<dc:creator>Raimar Wagner</dc:creator>
				<category><![CDATA[c++]]></category>
		<category><![CDATA[betriebssysteme]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[datenstrukturen]]></category>
		<category><![CDATA[pthread]]></category>

		<guid isPermaLink="false">http://www.ioexception.de/?p=123</guid>
		<description><![CDATA[Die zentrale Frage bei der Implementierung des Schedulers ist die Frage nach der Datenstruktur in der die   Tupel gehalten werden. Der Scheduler soll, gemäß der SJF Strategie, immer das Tupel auswählen dessen Joblänge  am kürzesten ist. Für solche eine Problemstellung eignet sich die Datenstruktur std::set bzw. std::multiset parametrisiert auf std::pair am Besten. [...]]]></description>
			<content:encoded><![CDATA[<p>Die zentrale Frage bei der Implementierung des Schedulers ist die Frage nach der Datenstruktur in der die <img src="http://l.wordpress.com/latex.php?latex=%20%28%20%5Ctext%7BId%7D%2C%20%20%5Ctext%7BJobl%5C%22%7Ba%7Dnge%7D%29%20&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title=" ( \text{Id},  \text{Jobl\"{a}nge}) " style="vertical-align:-20%;" class="tex" alt=" ( \text{Id},  \text{Jobl\"{a}nge}) " />  Tupel gehalten werden. Der Scheduler soll, gemäß der SJF Strategie, immer das Tupel<img src="http://l.wordpress.com/latex.php?latex=%20%28%20i%2C%20j%29%20&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title=" ( i, j) " style="vertical-align:-20%;" class="tex" alt=" ( i, j) " /> auswählen dessen Joblänge <img src="http://l.wordpress.com/latex.php?latex=j&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="j" style="vertical-align:-20%;" class="tex" alt="j" /> am kürzesten ist. Für solche eine Problemstellung eignet sich die Datenstruktur <code>std::set</code> bzw. <code>std::multiset</code> parametrisiert auf <code>std::pair</code> am Besten. Jedoch ist zu beachten dass die Sortierung bei <code>std::pair</code> normalerweise auf dem ersten Element, also bei uns auf der ThreadId basiert. Daher müssen wir den Vergleichsoperator des <code>std::multiset</code> mit unserem eigenen Operator überschreiben. </p>
<pre class="brush: cpp;">
/*
Scheduler.h
*/

/*
this struct is used to have a different compare operator for std::pair in my std::multiset. I have to compare the second argument of pair!
*/
struct compareBySecond {
  bool operator() (const std::pair&lt;int,int&gt;&amp; a, const std::pair&lt;int,int&gt;&amp; b) const
  {return (a).second&lt;(b).second;}
};

/*
my scheduler class, schedules the requests
*/

class Scheduler{

  public:
    [  ... ]

  private:
    //multiset holds all pairs with (thread,job)
    std::multiset&lt; std::pair&lt;int,int&gt; , compareBySecond &gt; jobs;

    [  ... ]

};
</pre>
<p>Als Synchronisationselemente kommen normale RW-Locks und Condition-Variablen zur Anwendung, auf diese Standardelemente wird hier nicht weiter eingegangen. Guten Beispielcode für diese Elemente findet sich in den Qt3.3-Quellen (z.B.: <a href="http://doc.trolltech.com/4.5/qreadwritelock.html">QReadWriteLock</a>). </p>
<p>Die einzige Methode die von den Anfragethreads ausgeführt wird ist <code>Scheduler::enqueue(int thread, int length)</code> (siehe <a href="http://www.ioexception.de/2009/06/22/ein-einfacher-scheduler-in-c-teil-1-rahmenprogramm/">Teil 1</a>). Bemerkenswert ist hier nur der letzte Aufruf, da wir ja immer eine möglichst volle Queue gewährleisten wollen wartet der Scheduler darauf dass er Jobs erst auswählt, wenn die Queue voll ist oder eine volle Queue nicht mehr erreicht werden kann. Hierzu ist die Condition-Variable<code> cv_queuefull</code> nötig auf die beim Überprüfen der Queue gewartet wird. </p>
<pre class="brush: cpp;">

/*
enqueues a job
*/
void  Scheduler::enqueue(int thread, int length){

  //wait if queue is full or thread has already job in queue
  while(isQueueFull() || threadHasRequestInQueue(thread)){
    cv-&gt;wait();
  }

  //new pair for enqueueing
  std::pair&lt;int,int&gt; tmp(thread,length);

  //lock and insert in queue
  rw-&gt;lockWrite();
  jobs.insert(tmp);
  rw-&gt;unlockWrite();

  //we did it!
  std::cout &lt;&lt; &quot;requester &quot; &lt;&lt; thread &lt;&lt; &quot; joblength &quot; &lt;&lt; length &lt;&lt; std::endl;

  //signal scheduler thread that thread is now maybe full
  cv_queuefull-&gt;signal();
}
</pre>
<p>Die beiden hier noch verwendeten Methoden <code>bool Scheduler::isQueueFull()</code> und <code>bool Scheduler::threadHasRequestInQueue(int thread)</code> sind aus Implementierungssicht trivial. </p>
<p>Die wichtigste Methode in der die eigentlichen Jobs &#8220;abgearbeitet&#8221; werden ist <code>Scheduler::processNextJob()</code>, hier muss zunächst überprüft werden ob die Queue bereit ist. Dies geschieht in  <code>Scheduler::QueueReady()</code> und ist weiter unten erläutert. Für die Auswahl des nächsten Jobs mit der kürzesten Joblänge reicht es das erste Element des Sets zu entnehmen, dies ist nach der von uns definierten Ordnung im Set automatisch der Job mit der kürzesten Laufzeit. Nach dem Abarbeiten wird der Job aus der Queue gelöscht. Falls gerade ein Thread darauf wartet einen Job zu enqueuen dem es vorher nicht möglich war zu enqueuen da er schon einen Job in der Queue hatte wird dieser zum Schluss noch aufgeweckt. </p>
<pre class="brush: cpp;">
/*
processes the next job
*/
void  Scheduler::processNextJob(){
  //is queue ready?
  QueueReady();

  //get job
  rw-&gt;lockRead();
  std::pair&lt;int,int&gt; tmp = *( jobs.begin());
  rw-&gt;unlockRead();

  //process .......... :-)
  std::cout &lt;&lt; &quot;service requester &quot; &lt;&lt; tmp.first &lt;&lt; &quot; joblength &quot; &lt;&lt; tmp.second &lt;&lt; std::endl;

  //delete from queue
  rw-&gt;lockWrite();
  jobs.erase(jobs.find(tmp));
  rw-&gt;unlockWrite();

  //wake up all guys that wait on enqueuing
  cv-&gt;signalAll();
}
</pre>
<p>Für die Überprüfung ob die Queue bereit ist, sind zwei Bedingungen nötig: Ersten muss die Queue voll sein, siehe Annahmen. In dem Fall dass schon Threads beendet wurden kann es passieren dass die Queue nicht voll werden kann. In diesem Fall soll der Scheduler trotz nicht voller Queue seine Arbeit aufnehmen. Hier wäre noch Optimierungspotential gegeben, da nicht garantiert wird dass die Queue in momentanen Zustand der Threads immer so voll wie möglich ist. </p>
<pre class="brush: cpp;">
/*
checks if queue is ready
*/
void Scheduler::QueueReady(){
  while(!isQueueFull() &amp;&amp; (jobs.size() &lt; nrOfThreads) ){
    //wait if our queue is not full or some threads are already dead, thus we can proceed if #threads&lt;Queuesize
    cv_queuefull-&gt;wait();
  }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ioexception.de/2009/06/23/ein-einfacher-scheduler-in-c-%e2%80%94-teil-2-scheduler/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ein einfacher Scheduler in C++ &#8212; Teil 1: Rahmenprogramm</title>
		<link>http://www.ioexception.de/2009/06/22/ein-einfacher-scheduler-in-c-teil-1-rahmenprogramm/</link>
		<comments>http://www.ioexception.de/2009/06/22/ein-einfacher-scheduler-in-c-teil-1-rahmenprogramm/#comments</comments>
		<pubDate>Mon, 22 Jun 2009 16:13:29 +0000</pubDate>
		<dc:creator>Raimar Wagner</dc:creator>
				<category><![CDATA[c++]]></category>
		<category><![CDATA[betriebssysteme]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[pthread]]></category>

		<guid isPermaLink="false">http://www.ioexception.de/?p=108</guid>
		<description><![CDATA[Der hier vorgestellte Scheduler soll am Ende folgende Rahmenbedingungen erfüllen:

Jeder Thread darf nur maximal eine Anfrage in der Warteschlange haben.
Ein Thread stoppt falls alle seine Anfragen bearbeitet wurden.
Der Scheduler arbeitet nach dem SJF (Shortest Job First) Verfahren
Die Warteschlangengröße muss beim Programmstart festlegbar sein

Als Eingabe erhält das Programm die Warteschlangenlänge und eine Liste von Eingabedateien. Jede [...]]]></description>
			<content:encoded><![CDATA[<p>Der hier vorgestellte Scheduler soll am Ende folgende Rahmenbedingungen erfüllen:</p>
<ul>
<li>Jeder Thread darf nur maximal eine Anfrage in der Warteschlange haben.</li>
<li>Ein Thread stoppt falls alle seine Anfragen bearbeitet wurden.</li>
<li>Der Scheduler arbeitet nach dem <a href="http://de.wikipedia.org/wiki/Shortest-Job-Next">SJF (Shortest Job First)</a> Verfahren</li>
<li>Die Warteschlangengröße muss beim Programmstart festlegbar sein</li>
</ul>
<p>Als Eingabe erhält das Programm die Warteschlangenlänge und eine Liste von Eingabedateien. Jede Eingabedatei entspricht einem anfragenden Thread und beinhaltet eine Liste von Nummern die die Joblänge symbolisieren sollen. </p>
<p>Der erste Teil besteht aus der Implementierung des Rahmenprogramm der sich der später zu implementierenden Schedulerklasse bedient.<br />
Der erste Teil der <code>main()</code> Methode besteht aus den Auslese- und Initialisierungaufrufen. Insbesondere wird der Scheduler mit der Anzahl der Threads und der maximalen Warteschlangenlänge initialisiert. </p>
<pre class="brush: cpp;">

  //get queue-size
  int maxQueue=atoi(argv[1]);

  if(maxQueue&lt;=0) {
     std::cout &lt;&lt; &quot;min. queue size is 1&quot; &lt;&lt; std::endl;
     return 0;
  }

  //vector so store filenames
  std::vector&lt;std::string&gt; files;

  //count #threads
  int numOfThreads=0;

  //save filenames
  for (int i = 2; i &lt; argc; i++) {
     files.push_back(std::string(argv[i]));
     //every file is one thread
     numOfThreads++;
  }

  //create new scheduler
  scheduler= new Scheduler(maxQueue, numOfThreads);  

  //just temp storage for reading file
  std::string line;

  //iterate through parameters
  for(int i = 0; i&lt; argc-2; i++){
    //new parameter =&gt; new thread
    jobs.push_back(std::vector&lt;int&gt;());
    //open file
    std::ifstream myfile(files.at(i).c_str());
    if (myfile.is_open())
    {
      //push all job lengthes in vector
      while (! myfile.eof() )
      {
        std::getline (myfile,line);
        (jobs.at(i)).push_back(atoi(line.c_str()));
      }
      //close file
      myfile.close();
    }
  }
</pre>
<p>Im nächsten Schritt müssen alle anfragenden Threads gestartet werden, in diesem Fall kommen einfache <a href="http://en.wikipedia.org/wiki/POSIX_Threads">pthreads</a> zur Anwendung. Zu beachten ist dass <code>&#038;run_thread</code> der Funktionspointer auf die sogenannte run-Methode darstellt. </p>
<pre class="brush: cpp;">

   //array of threads
   pthread_t th[numOfThreads];

   //array of int* to transfer thread nr. to thread
   int* numbers[numOfThreads];

   for (int i = 0; i &lt; numOfThreads; i++) {
      //save thread nr.
      numbers[i]=new int(i);
      //create thread and transfer parameter
      pthread_create (&amp;th[i], NULL, &amp;run_thread, numbers[i]);
   }
</pre>
<p>Im <code>main()</code> Thread läuft auch der Scheduler der solange Anfragen abarbeitet bis die Warteschlange leer ist. Danach muss um ein sauberes Programmende zu gewährleisten noch auf alle Threads gewartet werden. </p>
<pre class="brush: cpp;">
   //process jobs until Queue is empty
   while(!scheduler-&gt;isQueueEmpty()){
       scheduler-&gt;processNextJob();
   }

   //wait until all threads are finished
   for (int i = 0; i &lt; numOfThreads; i++){
      pthread_join (th[i], NULL);
   }

   return 0;
</pre>
<p>Die von den Anfragethreads ausgeführte Methode <code>run_thread(void *number)</code> hat ein paar Stolperfallen; hier ist zu beachten dass an <code>pthreads </code>übergebene Funktionen nur <code>void*</code> Pointer als Parameter haben dürfen, deshalb muss auch innerhalb der Methode die Threadnummer wieder auf <code>int*</code> gecastet werden. Nach dem einreihen aller Anfragen in die Warteschlange des Schedulers kann sich der Thread beenden. </p>
<pre class="brush: cpp;">
static void* run_thread (void *number) {

   for(unsigned int i=0; i&lt; (jobs.at(*( (int*) number))).size()-1;i++){
    //enqueue all jobs in waiting queue
    scheduler-&gt;enqueue(*( (int*) number), (jobs.at(*( (int*) number))).at(i) );
   }
   //all jobs are enqueued =&gt; thread has done his work
   scheduler-&gt;decreaseThreads();
   pthread_exit (NULL);
}
</pre>
<p>In nächsten Teil wird detailliert auf die Funktionsweise und den Aufbau eines des hier benutzten Schedulers eingegangen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ioexception.de/2009/06/22/ein-einfacher-scheduler-in-c-teil-1-rahmenprogramm/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Visualisierung von Winkelgeschwindigkeiten in Vektorfeldern</title>
		<link>http://www.ioexception.de/2009/06/21/visualisierung-von-winkelgeschwindigkeiten-in-vektorfeldern/</link>
		<comments>http://www.ioexception.de/2009/06/21/visualisierung-von-winkelgeschwindigkeiten-in-vektorfeldern/#comments</comments>
		<pubDate>Sun, 21 Jun 2009 21:11:10 +0000</pubDate>
		<dc:creator>Raimar Wagner</dc:creator>
				<category><![CDATA[visualisierungen]]></category>
		<category><![CDATA[tcl]]></category>
		<category><![CDATA[visualisierung]]></category>
		<category><![CDATA[vtk]]></category>

		<guid isPermaLink="false">http://www.ioexception.de/?p=45</guid>
		<description><![CDATA[Um für ein gegebenes Beschleunigungsfeld die Winkelgeschwindigkeiten zu visualisieren bietet es sich an, an äquidistant gestreuten Stützstellen Würfel zu visualisieren die um die Beschleunigungsachse rotiert. Ein mögliches Beispielfeld ist:

Für die Umsetzung wurde VTK mit den Tcl Bindings verwendet. Zu Beginn benötigen wir zwei vtkPoints, eines für die geglyphten Würfel und eins für die eigentlichen Punkte [...]]]></description>
			<content:encoded><![CDATA[<p>Um für ein gegebenes Beschleunigungsfeld die Winkelgeschwindigkeiten zu visualisieren bietet es sich an, an äquidistant gestreuten Stützstellen Würfel zu visualisieren die um die Beschleunigungsachse rotiert. Ein mögliches Beispielfeld ist:</p>
<p><img src="http://l.wordpress.com/latex.php?latex=%20V%20%3D%20x%5E2%2Ay%2A%20e_1%20%20%2B%202%20%2A%20x%20%2A%20y%5E2%20%2A%20z%20%2A%20e_2%20%2B%20y%2A%20z%5E3%20%2A%20e_3%20&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title=" V = x^2*y* e_1  + 2 * x * y^2 * z * e_2 + y* z^3 * e_3 " style="vertical-align:-20%;" class="tex" alt=" V = x^2*y* e_1  + 2 * x * y^2 * z * e_2 + y* z^3 * e_3 " /></p>
<p>Für die Umsetzung wurde <a href="http://www.vtk.org/">VTK</a> mit den Tcl Bindings verwendet. Zu Beginn benötigen wir zwei <code>vtkPoints</code>, eines für die geglyphten Würfel und eins für die eigentlichen Punkte im Raum. Im folgenden können wir <code>gridPoints</code>, <code>glyPoints</code> als gegeben vorraussetzen. Des weiteren können wir ein Magnituden-Array <code>mag </code>und ein Beschleunigungs-3Tupel-Array <code>velocity </code>als gegeben vorraussetzen:</p>
<pre class="brush: perl;">
vtkPoints gridPoints
vtkPoints glyPoints

vtkFloatArray velocity
  velocity SetNumberOfComponents 3
  velocity SetNumberOfValues [expr $x_extend*$y_extend*$z_extend]

vtkFloatArray mag
  mag SetNumberOfComponents 1
  mag SetNumberOfValues [expr $x_extend*$y_extend*$z_extend]
</pre>
<p> Im nächsten Schritt müssen die Würfel Glyphs initialisiert werden und zu jedem <code>cube_$i</code> ein Mapper und Filter definiert werden. </p>
<pre class="brush: perl;">
#iterate thru all glyph points
for {set i 0} {$i &lt; [eval glyPoints GetNumberOfPoints]} {incr i} {  

  #create cubes
  vtkCubeSource cube_$i
    set pt [glyPoints GetPoint $i]

  #get nearest pnt
  set ref [eval loc FindClosestPoint [lindex $pt 0] [lindex $pt 1] [lindex $pt 2] ]
  set vl [velocity GetTuple3 $ref]

  #turn and translate
  vtkTransform cubeTransform_$i
    cubeTransform_$i PostMultiply
    cubeTransform_$i Translate 0 0 0
    set n [eval norm [lindex $vl 0] [lindex $vl 1] [lindex $vl 2]]
    cubeTransform_$i RotateWXYZ $n [lindex $vl 0] [lindex $vl 1] [lindex $vl 2]
    cubeTransform_$i Translate [lindex $pt 0] [lindex $pt 1] [lindex $pt 2]

  #create filter for transformation
  vtkTransformPolyDataFilter cubeTransformFilter_$i
    cubeTransformFilter_$i SetInput [cube_$i GetOutput ]
    cubeTransformFilter_$i SetTransform cubeTransform_$i

  #create mapper
  vtkPolyDataMapper   cubeMapper_$i
      cubeMapper_$i SetInput [cubeTransformFilter_$i GetOutput]
}
</pre>
<p>Im letzten Schritt folgt die Animation mit der Kameradrehung. </p>
<pre class="brush: perl;">
#render 900 frames
for {set k 0} {$k&lt;900} {incr k} {

  #rotate all glyphs
  for {set i 0} {$i&lt;[eval glyPoints GetNumberOfPoints]} {incr i} {
    set pt [glyPoints GetPoint $i]

    #find velocity to point
    set ref [eval loc FindClosestPoint [lindex $pt 0] [lindex $pt 1] [lindex $pt 2] ]
    set vl [velocity GetTuple3 $ref]

    #transform every cube
    cubeTransform_$i Identity
    cubeTransform_$i Translate 0 0 0

    set n [eval norm [lindex $vl 0] [lindex $vl 1] [lindex $vl 2]]
    cubeTransform_$i RotateWXYZ [expr $k * $n/1000] [lindex $vl 0] [lindex $vl 1] [lindex $vl 2]
    cubeTransform_$i Translate [lindex $pt 0] [lindex $pt 1] [lindex $pt 2]

  }

  #move camera &amp; render frame
  [ren1 GetActiveCamera] Azimuth 0.1
  renWin Render

}
</pre>
<p>Mit zusätzlicher Einblendung der Beschleunigungvektoren sieht das Ergebnis dann so aus:<br />
<center><br />
<object width="551" height="413"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=5262615&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=0&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=5262615&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=0&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="551" height="413"></embed></object></p>
<p></center></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ioexception.de/2009/06/21/visualisierung-von-winkelgeschwindigkeiten-in-vektorfeldern/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

