Dieser Artikel wurde maschinell übersetzt.

Die Benutzeroberfläche und ihre Grenzen

Projektionstransformationen ohne Mathematik

Charles Petzold

Downloaden des Codebeispiels

In fast allen Grafiksystem darstellen Transformationen die wichtigste Funktion, die tatsächlich etwas Zeichnen nicht.Transformationen werden stattdessen die Darstellung der visuellen Objekte durch Ändern der Koordinaten mit mathematischen Formeln, die in der Regel als eine Matrixmultiplikation ausgedrückt ändern.

RenderTransform-Eigenschaft, die von der UIElement definierte wurde in Silverlight von Anfang und vor, die in Windows Presentation Foundation (WPF).Da die Eigenschaft von "UIElement" definiert ist, können Sie es mit grafischer Objekte, die als auch Text, Steuerelemente und Medien verwenden.Legen Sie einfach RenderTransform auf ein Objekt vom Typ TranslateTransform, ScaleTransform, RotateTransform, SkewTransform, MatrixTransform (für die vollständige Kontrolle über die Transformationsmatrix) oder einer TransformGroup für eine Kombination aus mehreren Transformationen.

Die Typen von Transformationen, die Sie festlegen, die mit RenderTransform sind Beispiele für zweidimensionale (2D) affine transformiert.Affine Transformationen sind sehr gut behaved und nur ein wenig langweilige: Gerade Linien werden immer umgewandelt, um gerade Linien, Ellipsen sind stets um Ellipsen transformiert und Quadrate werden immer an Parallelograms umgewandelt.Wenn zwei Zeilen vor der Transformation parallel verlaufen, sind Sie nach der Transformation weiterhin parallel.

Pseudo-3D

Silverlight 3 eingeführt, eine neue UIElement-Eigenschaft mit dem Namen Projektion, mit der Einstellung könnennicht affinen Transformationen auf grafische Objekte, Text, Steuerelemente und Medien.Nicht affinen Transformationen werden Parallelität nicht beibehalten werden.

Der Typ von nicht affinen Transformation in Silverlight 3 zugelassen wird immer noch durch eine Matrixmultiplikation dargestellt, und es noch Beschränkungen für was Sie tun kann.Gerade Linien werden immer um gerade Linien umgewandelt, und ein Quadrat wird immer in einer einfachen Konvexer Quadrilateral transformiert.Durch “ Quadrilateral, ” gemeint, dass eine Abbildung der vier Seiten (auch als Tetragon oder kubischen bezeichnet); durch “ einfache und ” gemeint, dass die Seiten mit Ausnahme in Ihre Scheitelpunkte schneiden nicht; mit “ Konvexer ” ich meinen, dass die internen Winkel an jeden Scheitelpunkt weniger als 180 Grad sind.

Diese Art von nicht affinen Transformation eignet sich zum Erstellen von Kegel-Transformationen bei gegenüberliegenden Seiten ein Quadrat oder Rechteck Kegel-, etwas in eine Richtung.Abbildung 1 Zeigt Text mit einer Kegel-Transformation, die über eine sehr einfache Prognose für die Eigenschafteneinstellung realisiert.

Figure 1 Text with a Taper TransformAbbildung 1 Text mit einer Transformation Kegel

Der Text wird angezeigt, um etwas drei dreidimensionale (3D) sein, da das Wert bei einseitigem Test End weiter weg von unsere Augen scheint – Effekts eine perspektivische Projektion genannt.

In gewisser Weise ermöglicht die Projection-Eigenschaft Silverlight ein wenig “ Pseudo-3D. ” Es ist keinem echten 3D System, weil es keine Möglichkeit, Objekte im 3D-Raum zu definieren, kein Konzept für Kameras, Beleuchtung oder Schattierungen und – vielleicht wichtigste – kein Clipping Objekte basierend auf deren Anordnung im 3D-Raum.

Dennoch muss das Arbeiten mit der Prognose für die Transformation des Programmierers, denken etwa drei Dimensionen und insbesondere über 3D drehen zu beginnen.Glücklicherweise haben der Silverlight-Entwickler einige häufige und einfache Verwendung der Projection-Eigenschaft relativ leicht vorgenommen.

Der einfachere Ansatz

Sie können die Projection-Eigenschaft auf ein Matrix3DProjection-Objekt oder ein PlaneProjection-Objekt festlegen.Die Matrix3DProjection-Eigenschaft nur ein Objekt definiert, ist es eine 4 x 4 Matrix3D Struktur, die eine Vielzahl von Mathematik erforderlich ist.(Einige Methoden dieser Struktur finden Sie in die Blogeinträgen auf meiner Website – charlespetzold.com – vom Juli 23, 2009 und Juli 31, 2009.)

Aber in diesem Artikel habe ich mich auf Mathematik in den meisten Fällen zu vermeiden, was bedeutet, dass ich mit der PlaneProjection-Klasse festhalten werden werde Zugesagtes.Obwohl die Klasse 12 festlegbare Eigenschaften definiert, werde ich mich auf nur sechs konzentrieren.

Im herunterladbaren Quellcode ist Code für diesen Artikel PlaneProjectionExperimenter, die Sie interaktiv mit diesen sechs Eigenschaften experimentieren kann.Abbildung 2 zeigt das Programm in Aktion.Sie können durch die Kompilierung der downloadbaren Anwendung ausführen oder können Sie ihn auf meiner Website unter ausführen charlespetzold.com/Silverlight/PlaneProjectionDemos, zusammen mit allen anderen Programmen in diesem Artikel.Ignorieren Sie vorläufig blauen Punkt in der Mitte.

Abbildung 2 Das PlaneProjectionExperimenter-Programm

Drei entscheidenden Eigenschaften die PlaneProjection sind RotationX, RotationY und RotationZ, die die drei ScrollBars geändert werden kann.Diese Eigenschaften übernehmen ein 3D Koordinatensystem, wobei die X-Werte erhöhen nach rechts und Y-Werte Erhöhen der Bildschirmhöhe nach unten wechseln.(Dies ist konsistent mit den normalen Silverlight Koordinatensystem, aber nicht mit typischen 3D Systeme, bei dem die Werte von Y in der Regel erhöhen nach oben wechseln.) Steigende Werte von Z scheinen außerhalb des Bildschirms in Richtung des Viewers zu stammen.Diese drei Eigenschaften dazu führen, dass die Drehung um die drei Achsen.

Die ScrollBars für X und Y auf die Achse der Drehung perpendicularly positioniert sind.Beispielsweise dreht die vertikale Bildlaufleiste auf der linken Seite in der Abbildung, um die X-Achse, die durch die Mitte des Briefes horizontal ausgeführt wird.Die oberen und unteren Rand des Buchstabens erscheinen, Mitte oder Weg von den Viewer zu kippen.

Auf den ersten empfiehlt es sich, versuchen Sie es jeder Achse der Drehung unabhängig von den anderen und aktualisieren Sie Ihren Browser zwischen Experimentations.Sie können die Richtung der Drehung mit die Rechte Regel erwarten.Zeigen Sie den Ziehpunkt in der Richtung der positiven Achse.(Für X, die auf der rechten Seite ist; für Y ist ausgefallen, Z, es ist in Richtung Sie.) Die Kurve, die Ihre andere Finger gibt die Richtung der Drehung für positive Drehung Winkel.Negativer Winkel in entgegengesetzter Richtung zu drehen.

Eine zusammengesetzte Drehung hängt von der Reihenfolge, in der die einzelnen Drehungen angewendet werden.Mit PlaneProjection geopfert gewisse Flexibilität bei diesen Drehungen.PlaneProjection gilt immer RotationX zuerst, dann RotationY und schließlich RotationZ.Wie können wir feststellen?Versuchen Sie es verlassen RotationZ bei 0, und Bearbeiten von RotationX und RotationY.Sehen Sie, dass RotationX immer den Brief an der horizontalen Achse des Briefes, dreht während RotationY den Buchstaben, um die vertikale Achse des gedrehtFenster, d. h., dass auf den Buchstaben, die bereits von der RotationX-Winkel gedreht RotationY angewendet wird.Nun, RotationX und RotationY auf einen beliebigen Wert festgelegt, RotationZ bearbeiten.Diese Drehung ist auch relativ zum Fenster und die Darstellung des Briefes wird überhaupt nicht geändert.

In der Praxis können Sie einfach legen Sie eine Eigenschaft der Projektion und angemessene ein Ergebnis.Der Text im Abbildung 1 ist Teil des TaperText-Projekts und wurde mit den folgenden XAML-Code angezeigt:

<TextBlock Text="TAPER"
           FontFamily="Arial Black"
           FontSize="144"
           HorizontalAlignment="Center"
           VerticalAlignment="Center">
    <TextBlock.Projection>
        <PlaneProjection RotationY="-60" />
    </TextBlock.Projection>
</TextBlock>

Wie bei RenderTransform, auswirken keine Projektion Layout. Das Layoutsystem sieht ein un-transformed und un-projected-Element.

Selbstverständlich sind die Eigenschaften RotationX, RotationY und RotationZ alle durch Abhängigkeitseigenschaften, gesichert kann Sie auch die Animation Ziele werden.

Die FlipPanel

Nur diese Menge Wissen über PlaneProjection, es ist möglich, einen “ kippen Bereich ”, code, einem Verfahren, um eine Anwendung Speicherbedarf auf dem Bildschirm zu minimieren, durch das Anordnen von Steuerelementen auf der Vorder- und Rückseite eines Bereichs (oder es scheint). In WPF erfordert ein Steuerelement FlipPanel zwischen 2D und 3D hin und her wechseln. In Silverlight wird die FlipPanel recht einfach.

Das FlipPanelDemo-Projekt enthält ein FlipPanel-Steuerelement von UserControl abgeleitet. Der Code-Teil in angezeigtAbbildung 3 definiert zwei neue Eigenschaften, die mit dem Namen Child1 und Child2 vom Typ "UIElement" und die öffentlichen Methoden, die mit dem Namen kippen und FlipBack.

Abbildung 3 Die Datei FlipPanel.xaml.cs

using System;
using System.Windows;
using System.Windows.Controls;

namespace FlipPanelDemo
{
    public partial class FlipPanel : UserControl
    {
        public static readonly DependencyProperty Child1Property =
            DependencyProperty.Register("Child1",
                typeof(UIElement),
                typeof(FlipPanel),
                new PropertyMetadata(null, OnChild1Changed));

        public static readonly DependencyProperty Child2Property =
            DependencyProperty.Register("Child2",
                typeof(UIElement),
                typeof(FlipPanel),
                new PropertyMetadata(null, OnChild2Changed));

        public FlipPanel()
        {
            InitializeComponent();
        }

        public UIElement Child1
        {
            set { SetValue(Child1Property, value); }
            get { return (UIElement)GetValue(Child1Property); }
        }

        public UIElement Child2
        {
            set { SetValue(Child2Property, value); }
            get { return (UIElement)GetValue(Child2Property); }
        }

        public void Flip()
        {
            flipStoryboard.Begin();
        }

        public void FlipBack()
        {
            flipBackStoryboard.Begin();
        }

        static void OnChild1Changed(DependencyObject obj,
                        DependencyPropertyChangedEventArgs args)
        {
            (obj as FlipPanel).child1Container.Content = args.NewValue;
        }

        static void OnChild2Changed(DependencyObject obj,
                        DependencyPropertyChangedEventArgs args)
        {
            (obj as FlipPanel).child2Container.Content = args.NewValue;
        }
    }
}

Der XAML-Teil in Abbildung 4 zeigt, wie Child1 und Child2 die gleichen Speicherplatz und haben Hochrechnung Transformationen angewendet belegen. In die ursprüngliche Position weist die PlaneProjection-Transformation für Child2 RotationX bis-90 Grad eingestellt, d. h., dass er im rechten Winkel zueinander stehen, um den Viewer und effektiv nicht sichtbar ist. Die “ kippen ” Animationen swing einfach Child1 aus der Ansicht durch animieren RotationX auf 90; Sie swing Child2 in die Ansicht durch animieren RotationX auf 0. Die “ kippen wieder ” Animationen reverse dieser Aktionen.

Abbildung 4 Die Datei FlipPanel.xaml

<UserControl x:Class="FlipPanelDemo.FlipPanel"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <UserControl.Resources>
        <Storyboard x:Name="flipStoryboard">
            <DoubleAnimation Storyboard.TargetName="planeProjection1"
                             Storyboard.TargetProperty="RotationX"
                             To="90"
                             Duration="0:0:0.5" />
            
            <DoubleAnimation Storyboard.TargetName="planeProjection2"
                             Storyboard.TargetProperty="RotationX"
                             To="0"
                             BeginTime="0:0:0.5"
                             Duration="0:0:0.5" />
        </Storyboard>

        <Storyboard x:Name="flipBackStoryboard">
            <DoubleAnimation Storyboard.TargetName="planeProjection1"
                             Storyboard.TargetProperty="RotationX"
                             To="0"
                             BeginTime="0:0:0.5"
                             Duration="0:0:0.5" />
            <DoubleAnimation Storyboard.TargetName="planeProjection2"
                             Storyboard.TargetProperty="RotationX"
                             To="-90"
                             Duration="0:0:0.5" />
        </Storyboard>

    </UserControl.Resources>
    
    <Grid x:Name="LayoutRoot" Background="White">
        <ContentControl Name="child1Container">
            <ContentControl.Projection>
                <PlaneProjection x:Name="planeProjection1" />
            </ContentControl.Projection>
        </ContentControl>
        <ContentControl Name="child2Container">
            <ContentControl.Projection>
                <PlaneProjection x:Name="planeProjection2" 
                                 RotationX="-90" />
            </ContentControl.Projection>
        </ContentControl>
    </Grid>
</UserControl>

In der Regel würden Child1 und Child2 auf Bereiche mit Steuerelementen behandelt Art festgelegt werden. In der Anwendung FlipPanelDemo haben die Child1 und Child2 einfach unterschiedliche Farben und einer Schaltfläche in der Flip auslösen. Kipp Aktion, anscheinend mehr comforting für den Benutzer als zu einer neuen Seite zu navigieren, da Sie impliziert, dass eine Reihe von Steuerelementen werden nicht unwiderruflich verschwindet, jedoch können auf einfache Weise abgerufen werden.

Mittelpunkt der Drehung

Alle Drehung ist relativ zu einem Center. Die Drehung in zwei Dimensionen ist relativ zu einem Punkt. Die Drehung in drei Dimensionen ist relativ zu einer Linie im 3D-Raum – häufig als eine “ Achse der Drehung. ” bezeichnet Zur Vereinfachung – und vielleicht zu vermeiden, Einführung in 3D Linien und 3D Vektoren in Silverlight – die Projektion Transformation gilt relativ zu einem 3D.

Die PlaneProjection-Klasse unterstützt, ändern den Mittelpunkt der Drehung über drei Eigenschaften:

  • CenterOfRotationX (relativen Koordinate; der Standardwert ist 0,5)
  • CenterOfRotationY (relativen Koordinate; der Standardwert ist 0,5)
  • CenterOfRotationZ (absolute Koordinate; Standard ist 0)

Let’s sehen Sie sich die ersten beiden zuerst. Diese Werte sind wie die RenderTransformOrigin-Eigenschaft relativ zur oberen linken Ecke des Elements transformiert. Sie unterscheiden sich darin, dass der Standardwert von RenderTransformOrigin der Punkt (0, 0) ist, während die Standardwerte für PlaneProjection dazu führen, dass die Drehungen um auf das Element zentriert werden.

In PlanProjectionExperimenter können Sie CenterOfRotationX und CenterOfRotationY mit blauen Punkt ändern. (Eine QuickInfo zeigt die aktuellen Werte). Sie sehen wahrscheinlich sofort, dass CenterOfRotationX hat keinen Einfluss auf Drehung um die x-Achse und CenterOfRotationY hat keinen Einfluss auf Drehung um die y-Achse.

Wenn CenterOfRotationX gleich 0, Drehung um die y-Achse ist relativ zum linken Rand des Elements, ebenso, wenn Sie es auf 1 festlegen, Drehung um die rechte Seite. Sie können den Wert kleiner als 0 oder größer als 1 für einige sehr große Swings vornehmen. Das Element scheint sehr nahe an den Viewer erhalten und sehr weit weg zu gehen.

Probieren Sie Folgendes aus: Stellen Sie CenterOfRotationY ungefähr gleich 0. Nun legen Sie RotationX um 90 Grad oder thereabouts. Sie werden bemerken, dass das Element weiterhin sichtbar ist. In der FlipPanel wird eine Drehung von 90 Grad oder 90 Grad das Element nicht sichtbar sein, da es auf den Rand angezeigt wird. Die mathematischen Berechnungen passiert innerhalb der PlaneProjection-Klasse wird davon ausgegangen, dass der Viewer-Augen-Effekt (oder die Kamera Schoß) immer in der Mitte des Elements suchen direkt wieder in die negativen Z-Richtung ausgerichtet wird. Wenn etwas mehr zentriert und gedreht wird wieder um 90 Grad, es immer noch von der Mitte des Elements angezeigt werden soll.

Die CenterOfRotationZ-Achse wird von X anders gehandhabt und Y. Es ist in Silverlight absolute Koordinaten anstelle von relativen Koordinaten und der Standardwert ist 0. In PlaneProjectionExperimenter können Sie diesen Wert mit dem Mausrad ändern. Der blaue Punkt vergrößert und verkleinert wird, damit die Änderung in der Eigenschaft darstellen.

Drehung mit einer nicht dem Standard-CenterOfRotationZ ist wahrscheinlich am schwersten zu visualisieren, mentally, deshalb lohnt sich die Zeit ein wenig experimentieren.

Das Element, projiziert wird davon ausgegangen, dass in der XY-Ebene befinden, d. h. die Ebene im 3D-Raum, in dem Z gleich 0 ist. Wenn Sie übernehmen Sie die CenterOfRotationZ-Eigenschaft den Standardwert von 0 und RotationX oder RotationY bearbeiten, werden Teile des Briefs größer Sie in positiven Z-Abstand verschoben, und teilen abrufen kleiner, wie Sie in negativen Z-Abstand verschoben. Erhöhen Sie CenterOfRotationZ auf einen Wert von ca. 200, und bearbeiten Sie die RotationY. Der Buchstabe erhalten größer, da es um den Mittelpunkt gedreht wird, wobei Z für 200 aus einem Bereich des Speicherplatzes entspricht, wobei Z 0 in den Bereich entspricht, in der Z gleich 400 ist. Wenn Sie CenterOfRotationZ auf 500 oder höher setzen, funktioniert die ganze Sache gut, weil die internen Mathematik der PlaneProjection wird davon ausgegangen, dass der Viewer (oder die Kamera) sich 1.000 Einheiten von XY-Ebene ist. Mit einer Drehung Mitte von 500 ist das Element tatsächlich 
being, die hinter der Kamera projiziert.

Drei-Systemsteuerung Karussell

Können wir etwas Ähnliches wie in einem FlipPanel mit drei Seiten statt nur zwei Stellen? Ja, aber es ist ein klein wenig trigonometrischen und eine ganze Menge von messing um mit Z Indizes erforderlich.

Abbildung 5 zeigt einer Draufsicht was ich vorstellen. Es ist eine Ansicht aus einer negativen Position auf der y-Achse – über dem Bildschirm, um zu sprechen, Suchen nach unten. Dicken Linien stellen die drei Bereiche dar. Alle diese Bereiche werden tatsächlich in der gleichen Stelle positioniert. Nur die Prognose für die Transformation führt dazu, dass an verschiedenen Orten angezeigt werden. Der sichtbare hat im Vordergrund keine Drehungen angewendet wird. Die anderen beiden haben Drehungen unterzogen wurden, bei denen RotationY auf 120 (für die auf der rechten Seite) und-120 Grad (auf der linken Seite) festgelegt ist. Beide Drehungen auf einen negativen Wert von CenterOfRotationZ zentriert schwarzer Punkt entspricht. Was ist der Wert?

Figure 5 A Proposed Three-Panel Carousel
Abbildung 5 Eine vorgeschlagene drei-Systemsteuerung Karussell

Wenn Sie diesen Punkt mit einer gepunkteten Linie auf den Scheitelpunkt am rechten verbinden, wird die gepunktete Linie einen Winkel von 30 Grad mit der x-Achse. Der Tangens von 30 Grad ist 0.577. Das ist das Verhältnis zwischen der Entfernung des Punkts auf der x-Achse, dividiert durch die Hälfte der Breite des Bereichs. Der Bereich ist 200 Einheiten breit, diesen Punkt unter-57.7. Legen Sie CenterOfRotationZ auf diesen Wert fest.

Jetzt, um das Karussell auf die nächste von einem Panel zu drehen, nur animieren RotationY von 120 Grad für alle drei Bereichen zu erhöhen.

Nun, nicht genau. Obwohl wir diese Panels im 3D-Raum picturing sind, wirklich noch in 2D Speicherplatz vorhanden, und Sie tatsächlich über aufeinander gestapelt sind. Wie Sie drehen möchten, muss die Canvas.ZIndex angefügt-Eigenschaft jeder der drei Bereiche geändert werden, die Flächen neu anordnen. Dies ist, wie Elemente scheinbar “ vor ” oder “ hinter anderen Elementen ” verschoben werden können.

Nehmen Sie an Let’s Drehung im Uhrzeigersinn wird basierend auf Abbildung 5 Diagramm. Zu Beginn des Bereichs im Vordergrund sollte einen Z-Index von 2 (Vordergrund), auf der rechten Seite einen Z-Index von 1 hat und auf der linken Seite hat einen Z-Index 0 (Hintergrund). Starten Sie jetzt die 120-Grad-Drehung. Um einen halben – d. h., wenn sich jedes Panel wurde 60 Grad gedreht und zwei Bereiche gleichmäßig angezeigt – die Z-Indizes müssen geändert werden. Der Bereich, in der Ansicht verschieben sollten den Z-Index auf 2 festgelegt haben sollte, und eine, die aus der Ansicht verschieben deren Z-Index auf 1 festgelegt.

Dies wird alle im Projekt ThreePanelCarousel implementiert. In der tatsächlichen Verwendung natürlich würde die drei Bereiche mit Steuerelementen behandelt werden; in dieser Demo-Programm Sie gerade haben unterschiedliche Farben und einer Schaltfläche. Ich habe die Bereiche teilweise transparent links, damit Sie sehen, was vor sich geht. Abbildung 6 zeigt die Bereiche in Aktion.

Figure 6 The ThreePanelCarousel Program as It’s Spinning
Abbildung 6 Das ThreePanelCarousel-Programm, wie IT drehen

Sie können sich Fragen, wenn es möglich, eine einzelne Projektion Drehung auf die zusammengesetzten Gruppe von drei Bereichen anzuwenden ist. Nein. Mehrere Projektion Transformationen können nicht über untergeordnete Elemente noch verschärft werden.

Andere Effekte

Wie Sie mit der Projection-Eigenschaft experimentieren, vergessen Sie nicht über andere Effekte “-3D-Ishness der Anwendung verbessern ”. Ein wenig Schatten immer hilft, und es ist ganz einfach, simulieren Sie einen Schatten – sogar einen Schatten verschieben – mit einem Pinsel mit Farbverlauf.

Die AsTheDaysGoBy-Anwendung verwendet eine Kombination von Animationen um zu simulieren, die Tage, die aus einem täglichen Schreibtisch Kalender fliegen als in einer alten Film, um die Übergabe von Zeit vorschlagen. Die Kalenderseite Projection-Eigenschaft ist festgelegt auf ein PlaneProjection-Objekt mit den CenterOfRotationX und CenterOfRotationY Eigenschaften, die beide auf 0 festgelegt. RotationX und RotationY werden beide auf die Seite nach oben und nach links bewegen, während Sie die Seite eine animierte Farbverlaufspinsel Bogenkrümmungen animiert. Schließlich scheint die Seite einfach zu verschwinden als seine Opacity-Eigenschaft auf 0 animiert werden. Abbildung 7 zeigt das Programm in Aktion.

Figure 7 The AsTheDaysGoBy Program
Abbildung 7 Das AsTheDaysGoBy-Programm

Die Animation dauert ein zweites, damit die Anwendung 60 Tage lang jede Minute oder ungefähr 10 Jahre pro Stunde durchläuft. Nachdem über einen Monat wird die Anwendung den maximalen DateTime-Wert nähert, und es wird bald mit einer Ausnahme beendet. Bis dahin genießen.

Charles Petzold   Redaktionelle wohne seit an MSDN Magazine*.* Sein neueste Buch ist “ die Annotated Turing: Eine Einführung über Alan Turing historisch Papier auf Computability und die Turing Machine ” (Wiley, 2008). Petzold schreibt einen Blog auf seiner Website charlespetzold.com.