<?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>Łukasz Sowa &#187; wpf</title>
	<atom:link href="http://lukaszsowa.pl/tag/wpf/feed/" rel="self" type="application/rss+xml" />
	<link>http://lukaszsowa.pl</link>
	<description>O programowaniu i nie tylko ;)</description>
	<lastBuildDate>Mon, 27 Feb 2012 22:40:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Transformacje w WPF</title>
		<link>http://lukaszsowa.pl/2008/09/transformacje-w-wpf/</link>
		<comments>http://lukaszsowa.pl/2008/09/transformacje-w-wpf/#comments</comments>
		<pubDate>Sat, 13 Sep 2008 19:34:00 +0000</pubDate>
		<dc:creator>Łukasz</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[surface]]></category>
		<category><![CDATA[transformacje]]></category>
		<category><![CDATA[wpf]]></category>

		<guid isPermaLink="false">/post/2008/09/13/Transformacje-w-WPF.aspx</guid>
		<description><![CDATA[<a href="http://lukaszsowa.pl/2008/09/transformacje-w-wpf/" title="Transformacje w WPF"></a>W lipcu przyszło mi wykonywać dla pewnej firmy projekt łudząco przypominający zastosowanie Microsoft Surface. W mojej gestii leżało napisać program, który na podstawie przyjmowanych od panelu dotykowego współrzędnych będzie manipulował (transformował) obrazki. Ot, taki terminal, na którym klienci mogą sobie &#8230;<p class="read-more"><a href="http://lukaszsowa.pl/2008/09/transformacje-w-wpf/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://lukaszsowa.pl/2008/09/transformacje-w-wpf/" title="Transformacje w WPF"></a><div class="entry" style="text-align: justify;">
<p>W lipcu przyszło mi wykonywać dla pewnej firmy projekt łudząco przypominający zastosowanie <a href="http://www.microsoft.com/surface/index.html">Microsoft Surface</a>. W mojej gestii leżało napisać program, który na podstawie przyjmowanych od panelu dotykowego współrzędnych będzie manipulował (transformował) obrazki. Ot, taki terminal, na którym klienci mogą sobie w przyjemny sposób pooglądać zdjęcia produktu. Przy okazji tego projektu zasięgnąłem poważnej lekcji WPF-a i długo zmagałem się z transformacjami graficznych obiektów &#8211; dlatego stwierdziłem, że warto napisać o paru aspektach tego zagadnienia :)</p>
<p>Wygodne transformowanie obiektów graficznych w WPF-ie to jedno z dobrodziejstw, które owa technologia oferuje, w szczególności jeśli zestawić ją z WinForms i GDI. Transformować możemy obiekty wszystkich klas, które dziedziczą po <span style="color: #33cccc;">UIElement</span>. Każdy taki obiekt posiada 2 właściwości: <strong>RenderTransform</strong> i <strong>LayoutTransform</strong> do której przypisujemy naszą transformacje. Czym różnią się te właściwości? Można o tym przeczytać <a href="http://www.charlespetzold.com/blog/2006/03/211105.html">tu</a> albo uruchomić krótkie demo (koniecznie w IE), dostępne <a href="http://www.charlespetzold.com/blog/2006/03/RenderTransformVersusLayoutTransform.xaml">tu</a>.</p>
<p>Teraz może nieco o transformacjach. Dostępnych typów transformacji jest cztery:</p>
<ol>
<li><span style="color: #33cccc;">RotateTransform </span>- obrót o podany kąt (w stopniach) i podany środek obrotu (punkt)<span style="color: #33cccc;"> </span></li>
<li><span style="color: #33cccc;">ScaleTransform </span>- skalowanie, w punkcie skalowania, w dwóch płaszczyznach (X i Y) o podanej skali (oddzielnie X i Y); wartości &gt;1 powiększają a wartości należące do przedziału (0;1) pomniejszają<span style="color: #33cccc;"> </span></li>
<li><span style="color: #33cccc;">SkewTransform </span>- &#8222;skośne&#8221; transformowanie o podane kąty (X i Y) oraz środek &#8222;skosowania&#8221; ;)<span style="color: #33cccc;"> </span>- służy często do tworzenia iluzji trójwymiarowości<span style="color: #33cccc;"> </span></li>
<li><span style="color: #33cccc;">TranslateTransform</span> &#8211; najzwyklejsza translacja o wektor &#8211; wymagane są dwie współrzędne wektora</li>
</ol>
<p>Więcej polecam poczytać więcej na MSDN, są nawet ładne rysunki :)</p>
<p>Przechodząc do rzeczy, aplikowanie transformacji jest bajecznie proste. Załózmy iż mamy obiekt typu <span style="color: #33cccc;">Image</span> &#8211; <strong>arrowImage</strong> i chcemy go przesunąć o wektor [50,82]. Wystarczy jedynie napisać:</p>
<p><strong>arrowImage.RenderTransform</strong> = <span style="color: #0000ff;">new</span> <span style="color: #33cccc;">TranslateTransform</span>(50,82);</p>
<p>i gotowe :)</p>
<p>W taki sposób możemy jednak dodać tylko jedną transformację. Co jeśli chcemy zaaplikować naszemu obiektowi całą grupę transformacji? Wystarczy wtedy skorzystać z klasy <span style="color: #33cccc;">TransformGroup</span>:</p>
<p><span style="color: #33cccc;">TransformGroup</span> <strong>transformGroup</strong> = <span style="color: #0000ff;">new</span> <span style="color: #33cccc;">TransformGroup</span>();</p>
<p>i teraz:</p>
<p><strong>transformGroup</strong>.Children.Add(<strong>rotateTransform</strong>);</p>
<p><strong>transformGroup</strong>.Children.Add(<strong>translateTransform</strong>); <strong></strong></p>
<p><strong>transformGroup</strong>.Children.Add(<strong>scaleTransform</strong>);</p>
<p>pozostaje zaaplikować grupę transformacji:</p>
<p><strong>arrowImage.RenderTransform</strong> = transformGroup;</p>
<p>tadam! Gotowe :)</p>
<p>Na koniec chciałbym zaznaczyć, że transformacje mają na siebie wpływ np. pomniejszenie obiektu o połowe powoduje iż translacja o wektor [8,0] jest tak naprawdę translacją o wektor [4,0]. Chyba, że zrobimy najpierw translacje, a potem pomniejszanie. Tutaj należy pamiętać, iż dodawanie transformacji nie zawsze jest przemienne: kolejność translacji nie ma znaczenia &#8211; wynik zawsze będzie taki sam; co innego np. z obrotem. Dokumentacja niestety nie jest zbyt wyczerpująca w tej kwestii. Osobiście męczyłem się tydzień, żeby zrozumieć cały mechanizm współdziałania między transformacjami &#8211; trzeba być naprawdę bardzo uważnym. Dla przykładu &#8211; najbardziej &#8222;aktualne&#8221; (te które mają być zastosowane najpóźniej) transformacje <strong>należy wstawiać na początku, a nie na końcu kolekcji.</strong></p>
<p><strong>transformGroup</strong>.Children.Add(<strong>rotateTransform</strong>); <strong>transformGroup</strong>.Children.Add(<strong>translateTransform</strong>);</p>
<p>Taki kod spowoduje najpierw translacje, a potem obrót. Jeśli więc chcemy uzyskać efekt wielokrotnej transformacji przydatne staje się coś takiego:</p>
<p><strong>transformGroup</strong>.Children.Insert(0, <strong>pewnaTransformacja</strong>);</p>
<p>To by było na tyle. Jeszcze nie jestem pewien, czy mogę, ale być może wspomniana aplikacja a&#8217;la Surface zostanie opublikowana na moim blogu :) Tymczasem polecam spojrzenie na <a href="http://silverlight.net/samples/2b1/SilverlightSurface/Run/default.html">podobną aplikację</a> &#8211; napisaną w Silverlighcie. Jej kod źródłowy jest cennym przykładem stosowania transformacji :)</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://lukaszsowa.pl/2008/09/transformacje-w-wpf/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

