Übersicht über 3D-Transformationen
Aktualisiert: November 2007
In diesem Thema wird beschrieben, wie Transformationen für 3D-Modelle im Windows Presentation Foundation (WPF)-Grafiksystem angewendet werden. Mithilfe von Transformationen können Entwickler Modelle neu positionieren, ihre Größe ändern und sie neu ausrichten, ohne die Basiswerte zu ändern, die sie definieren.
Dieses Thema enthält folgende Abschnitte.
- 3D-Koordinatenraum
- Transformieren von Modellen
- Übersetzungstransformationen
- Skalieren von Transformationen
- Drehungstransformationen
- Verwenden von Transformationsauflistungen
- Animieren von Transformationen
- Verwandte Abschnitte
3D-Koordinatenraum
3D-Grafikinhalte in Windows Presentation Foundation (WPF) werden in einem Element gekapselt, Viewport3D, das an der zweidimensionalen Elementstruktur beteiligt sein kann. Das Grafiksystem behandelt Viewport3D in Windows Presentation Foundation (WPF) wie viele andere Elemente als zweidimensionales visuelles Element. Viewport3D funktioniert als Fenster (Viewport) in eine dreidimensionale Szene. Genauer gesagt handelt es sich um eine Oberfläche, auf die eine 3D-Szene projiziert wird. Auch wenn Sie Viewport3D mit anderen 2D-Zeichnungsobjekten in demselben Szenendiagramm verwenden können, dürfen sich 2D- und 3D-Objekte in einem Viewport3D nicht überschneiden. In der folgenden Erläuterung ist der beschriebene Koordinatenraum im Viewport3D-Element enthalten.
Im Windows Presentation Foundation (WPF)-Koordinatensystem für 2D-Grafiken befindet sich der Ursprung in der linken oberen Ecke der Renderingoberfläche (in der Regel der Bildschirm). Im 2D-System verlaufen die positiven x-Achsenwerte nach rechts und die positiven y-Achsenwerte nach unten. Im 3D-Koordinatensystem befindet sich der Ursprung hingegen in der Mitte des Bildschirms. In diesem Fall verlaufen die positiven x-Achsenwerte nach rechts, die positiven y-Achsenwerte aber nach oben und die positiven z-Achsenwerte vom Ursprung nach außen in Richtung des Betrachters.
Vergleich der Koordinatensysteme
Der von diesen Achsen definierte Bereich ist der feststehende Verweisrahmen für 3D-Objekte in Windows Presentation Foundation (WPF). Wenn Sie in diesem Bereich Modelle und Lichter und Kameras zur Anzeige der Modelle erstellen, ist es hilfreich, diesen feststehenden Verweisrahmen (auch "Weltkoordinatensystem" genannt) vom lokalen Verweisrahmen zu unterscheiden, den Sie beim Anwenden von Transformationen für jedes Modell erstellen. Beachten Sie außerdem, dass je nach Licht- und Kameraeinstellung die Objekte innerhalb des Weltkoordinatensystems möglicherweise komplett unterschiedlich oder überhaupt nicht angezeigt werden. Die Position der Kamera verändert die Position der Objekte innerhalb des Weltkoordinatensystems jedoch nicht.
Transformieren von Modellen
Wenn Sie Modelle erstellen, haben sie eine bestimmte Position in der Szene. Um diese Modelle in der Szene zu verschieben, zu drehen oder um ihre Größe zu ändern, sollten Sie nicht die Eckpunkte ändern, die das Modell selbst definieren. Stattdessen wenden Sie wie in 2D Transformationen auf die Modelle an.
Jedes Modellobjekt verfügt über eine Transform-Eigenschaft, mit der Sie das Modell verschieben, neu ausrichten oder in der Größe verändern können. Wenn Sie eine Transformation anwenden, versetzen Sie alle Punkte im Modell um den durch die Transformation angegebenen Vektor oder Wert. Mit anderen Worten: Sie haben den Koordinatenraum transformiert, in dem das Modell definiert ist ("Modellraum"). Dabei haben Sie jedoch nicht die Werte geändert, aus denen sich die Geometrie des Modells im Koordinatensystem der gesamten Szene ("Weltkoordinatensystem") zusammensetzt.
Übersetzungstransformationen
3D-Transformationen erben von der abstrakten Transform3D-Basisklasse. Dazu zählen die affinen Transformationsklassen TranslateTransform3D, ScaleTransform3D und RotateTransform3D. Das Windows Presentation Foundation (WPF)-3D-System stellt außerdem eine MatrixTransform3D-Klasse bereit, mit der Sie dieselben Transformationen in mehreren präzisen Matrixvorgängen angeben können.
TranslateTransform3D verschiebt alle Punkte im Model3D in die Richtung des Offsetvektors, den Sie mit den Eigenschaften OffsetX, OffsetY und OffsetZ angeben. Beispiel: Wenn der Eckpunkt eines Würfels (2,2,2) lautet, verschiebt ein Offsetvektor von (0,1.6,1) diesen Eckpunkt (2,2,2) nach (2,3.6,3). Der Eckpunkt des Würfels im Modellraum lautet immer noch (2,2,2). Dieser Modellraum hat jedoch die Beziehung zum Weltkoordinatensystem geändert, sodass (2,2,2) im Modellraum jetzt (2,3.6,3) im Weltkoordinatensystem entspricht.
Übersetzung mit Offset
Die folgenden Codebeispiele zeigen, wie eine Übersetzung angewendet wird.
<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" >
<DockPanel>
<Viewbox>
<Canvas Width="600" Height="201">
<!-- The Viewport3D provides a rendering surface for 3-D visual content. -->
<Viewport3D Name="MyAnimatedObject"
ClipToBounds="True" Width="600" Height="150"
Canvas.Left="0" Canvas.Top="10">
<!-- Defines the camera used to view the 3D object. -->
<Viewport3D.Camera>
<PerspectiveCamera x:Name="myPerspectiveCamera" Position="0,0,2" LookDirection="0,0,-1"
FieldOfView="60" />
</Viewport3D.Camera>
<!-- The ModelVisual3D children contain the 3D models -->
<Viewport3D.Children>
<!-- This ModelVisual3D defines the light cast in the scene. Without light, the
3D object cannot be seen. -->
<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight Color="#FFFFFF" Direction="-0.612372,-0.5,-0.612372" />
</ModelVisual3D.Content>
</ModelVisual3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<GeometryModel3D>
<!-- The geometry specifes the shape of the 3D plane. In this case, a flat sheet is created. -->
<GeometryModel3D.Geometry>
<MeshGeometry3D
TriangleIndices="0,1,2 3,4,5 "
Normals="0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 "
TextureCoordinates="0,0 1,0 1,1 1,1 0,1 0,0 "
Positions="-0.5,-0.5,0.5 0.5,-0.5,0.5 0.5,0.5,0.5 0.5,0.5,0.5 -0.5,0.5,0.5 -0.5,-0.5,0.5 " />
</GeometryModel3D.Geometry>
<!-- The material specifies the material applied to the plane. In this case it is a linear gradient.-->
<GeometryModel3D.Material>
<MaterialGroup>
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<SolidColorBrush Color="Cyan" Opacity="0.3"/>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</MaterialGroup>
</GeometryModel3D.Material>
<!-- The Transform specifies how to transform the 3D object. The OffsetX property is animated
in the Storyboard below. -->
<GeometryModel3D.Transform>
<TranslateTransform3D x:Name="myTranslateTransform3D" OffsetX="0" OffsetY="0" OffsetZ="0" />
</GeometryModel3D.Transform>
</GeometryModel3D>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D.Children>
<!-- Trigger the TranslateTransform3D animation when the 3D object loads. -->
<Viewport3D.Triggers>
<EventTrigger RoutedEvent="Viewport3D.Loaded">
<BeginStoryboard>
<Storyboard>
<!-- This animation animates the OffsetX property of the TranslateTransform3D. -->
<DoubleAnimation
Storyboard.TargetName="myTranslateTransform3D"
Storyboard.TargetProperty="OffsetX"
To="-0.8"
AutoReverse="True" RepeatBehavior="Forever" />
<!-- If you want to animate OffsetY and/or OffsetZ, create similar DoubleAnimations
respectively. -->
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Viewport3D.Triggers>
</Viewport3D>
</Canvas>
</Viewbox>
</DockPanel>
</Page>
Skalieren von Transformationen
ScaleTransform3D ändert die Skalierung des Modells um einen angegebenen Skalierungsvektor mit Bezug auf einen Mittelpunkt. Geben Sie eine einheitliche Skalierung an, die das Modell an x-, y- und z-Achse um denselben Wert skaliert, um die Größe des Modells proportional zu ändern. Beispiel: Wenn die Transformationseigenschaften ScaleX, ScaleY und ScaleZ auf 0,5 festgelegt werden, wird die Größe des Modells halbiert. Werden dieselben Eigenschaften auf 2 festgelegt, wird die Skalierung an allen drei Achsen verdoppelt.
ScaleVector-Beispiel
Wenn Sie keine einheitliche Skalierungstransformation angeben (eine Skalierungstransformation, bei der die x-, y- und z-Werte nicht gleich sind) hat das zur Folge, dass das Modell nur eindimensional oder zweidimensional gestreckt oder verkleinert wird, und die anderen Dimensionen unverändert bleiben. Beispiel: Wenn Sie ScaleX auf 1, ScaleY auf 2 und ScaleZ auf 1 festlegen, wird die Höhe des transformierten Modells verdoppelt, während an x- und y-Achse keine Änderung erfolgt.
Standardmäßig bewirkt ScaleTransform3D, dass Eckpunkte um den Ursprung (0,0,0) erweitert oder verkleinert werden. Wenn das zu transformierende Modell nicht vom Ursprung aus gezeichnet ist, bewirkt eine Skalierung des Modells um den Ursprung keine Skalierung des Modells "an der Stelle". Wenn die Eckpunkte des Modells mit dem Skalierungsvektor multipliziert werden, wirkt sich der Skalierungsvorgang stattdessen sowohl auf die Übersetzung als auch auf die Skalierung des Modells aus.
ScaleCenter-Beispiel
Um das Modell "an der Stelle" zu skalieren, geben Sie den Mittelpunkt des Modells an, indem Sie die ScaleTransform3D-Eigenschaften CenterX, CenterY und CenterZ festlegen. Auf diese Weise wird sichergestellt, dass das Grafiksystem den Modellraum skaliert und anschließend in den Mittelpunkt für das angegebene Point3D übersetzt. Wenn Sie das Modell dagegen um den Ursprung erstellt haben und einen anderen Mittelpunkt angeben, wird das Modell vom Ursprung weg übersetzt.
Drehungstransformationen
Sie können ein Modell in 3D auf mehrere Weisen drehen. Eine typische Drehungstransformation gibt eine Achse und einen Drehungswinkel um diese Achse an. Die RotateTransform3D-Klasse ermöglicht es Ihnen, ein Rotation3D mit der zugehörigen Rotation-Eigenschaft zu definieren. Dann geben Sie die Eigenschaften Axis und Angle für Rotation3D an, in diesem Fall AxisAngleRotation3D, um die Transformation zu definieren. In den folgenden Beispielen wird ein Modell um 60 Grad um die y-Achse gedreht.
<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" >
<DockPanel>
<Viewbox>
<Canvas Width="321" Height="201">
<!-- The Viewport3D provides a rendering surface for 3-D visual content. -->
<Viewport3D Name="MyAnimatedObject"
ClipToBounds="True" Width="150" Height="150"
Canvas.Left="0" Canvas.Top="10">
<!-- Defines the camera used to view the 3D object. -->
<Viewport3D.Camera>
<PerspectiveCamera x:Name="myPerspectiveCamera" Position="0,0,2" LookDirection="0,0,-1"
FieldOfView="60" />
</Viewport3D.Camera>
<!-- The ModelVisual3D children contain the 3D models -->
<Viewport3D.Children>
<!-- Two ModelVisual3D define the lights cast in the scene. Without light, the
3D object cannot be seen. Also, the direction of the lights affect shadowing. -->
<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight Color="#FFFFFF" Direction="-0.612372,-0.5,-0.612372" />
</ModelVisual3D.Content>
</ModelVisual3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight Color="#FFFFFF" Direction="0.612372,-0.5,-0.612372" />
</ModelVisual3D.Content>
</ModelVisual3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<GeometryModel3D>
<!-- The geometry specifes the shape of the 3D plane. In this case, a flat sheet is created. -->
<GeometryModel3D.Geometry>
<MeshGeometry3D
TriangleIndices="0,1,2 3,4,5 "
Normals="0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 "
TextureCoordinates="0,0 1,0 1,1 1,1 0,1 0,0 "
Positions="-0.5,-0.5,0.5 0.5,-0.5,0.5 0.5,0.5,0.5 0.5,0.5,0.5 -0.5,0.5,0.5 -0.5,-0.5,0.5 " />
</GeometryModel3D.Geometry>
<!-- The material specifies the material applied to the plane. In this case it is a linear gradient.-->
<GeometryModel3D.Material>
<MaterialGroup>
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
<LinearGradientBrush.GradientStops>
<GradientStop Color="Yellow" Offset="0" />
<GradientStop Color="Red" Offset="0.25" />
<GradientStop Color="Blue" Offset="0.75" />
<GradientStop Color="LimeGreen" Offset="1" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</MaterialGroup>
</GeometryModel3D.Material>
<!-- The Transform specifies how to transform the 3D object. The properties of the
Rotation object are animated causing the 3D object to rotate and "wobble" (see Storyboard below).-->
<GeometryModel3D.Transform>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D x:Name="myAngleRotation" Axis="0,3,0" Angle="40" />
</RotateTransform3D.Rotation>
</RotateTransform3D>
</GeometryModel3D.Transform>
</GeometryModel3D>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D.Children>
<!-- Trigger the rotation animation when the 3D object loads. -->
<Viewport3D.Triggers>
<EventTrigger RoutedEvent="Viewport3D.Loaded">
<BeginStoryboard>
<Storyboard>
<!-- This animation animates the Angle property of the AxisAngleRotation3D
making the 3D object rotate from -60 degrees to 60 degrees. -->
<DoubleAnimation
Storyboard.TargetName="myAngleRotation"
Storyboard.TargetProperty="Angle"
From="-60" To="60" Duration="0:0:4" AutoReverse="True" RepeatBehavior="Forever"/>
<!-- This animation animates the Axis property of the AxisAngleRotation3D
making the 3D wobble as it rotates. -->
<Vector3DAnimation
Storyboard.TargetName="myAngleRotation"
Storyboard.TargetProperty="Axis"
From="0,3,0" To="1,0,1" Duration="0:0:4" AutoReverse="True" RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Viewport3D.Triggers>
</Viewport3D>
</Canvas>
</Viewbox>
</DockPanel>
</Page>
Hinweis: Das Windows Presentation Foundation (WPF)-3D-System ist ein rechtshändiges System. Daher führt ein positiver Wert für den Drehungswinkel zu einer Drehung gegen den Uhrzeigersinn um die Achse.
Bei Achsen-/Winkeldrehungen wird eine Drehung um den Ursprung angenommen, wenn kein Wert für die Eigenschaften CenterX, CenterY und CenterZ für RotateTransform3D angegeben ist. Wie bei der Skalierung sollte beachtet werden, dass die Drehung den ganzen Koordinatenraum des Modells transformiert. Wenn das Modell nicht um den Ursprung erstellt oder bereits übersetzt wurde, erfolgt die Drehung möglicherweise um den Ursprung und nicht an der Stelle.
Drehung mit angegebenem neuen Mittelpunkt
Um das Modell "an der Stelle" zu drehen, geben Sie den tatsächlichen Mittelpunkt des Modells als Mittelpunkt der Drehung an. Da die Geometrie in der Regel um den Ursprung modelliert wird, erhalten Sie das erwartete Ergebnis eines Transformationssatzes häufig dann, wenn Sie zunächst die Größe des Modells ändern (skalieren), dann die Ausrichtung festlegen (drehen) und es abschließend an die gewünschte Position verschieben (übersetzen).
Drehungsbeispiel
Achsen-/Winkeldrehungen sind für statische Transformationen und einige Animationen gut geeignet. Gehen Sie aber nun davon aus, dass Sie ein Würfelmodell um 60 Grad um die x-Achse und dann um 45 Grad um die z-Achse drehen. Sie können diese Transformation als zwei einzelne affine Transformationen beschreiben oder als Matrix. Es könnte jedoch schwierig sein, eine auf diese Weise definierte Drehung reibungslos zu animieren. Obwohl die in beiden Ansätzen berechneten Start- und Endpositionen des Modells übereinstimmen, sind die Zwischenpositionen des Objekts rechnerisch unbestimmt. Quaternionen stellen eine alternative Möglichkeit zur Berechnung der Interpolation zwischen Start und Ende einer Drehung dar.
Eine Quaternion stellt eine Achse in einem 3D-Raum und eine Drehung um diese Achse dar. Beispielsweise könnte eine Quaternion eine (1,1,2)-Achse und eine Drehung von 50 Grad darstellen. Die Leistungsfähigkeit von Quaternionen bei der Definition von Drehungen lässt sich auf zwei Vorgänge zurückführen, die für sie ausgeführt werden können: Komposition und Interpolation. Die Komposition von zwei Quaternionen, die auf eine Geometrie angewendet werden, bedeutet Folgendes: "Drehen Sie die Geometrie um Drehung2 um Achse2 und anschließend um Drehung1 um Achse1." Durch Verwenden der Komposition können Sie zwei Drehungen der Geometrie kombinieren, um eine einzelne Quaternion zu erhalten, die das Ergebnis darstellt. Da mit der Quaternionsinterpolation ein glatter und sinnvoller Pfad von einer Achse und ihrer Ausrichtung zu einer anderen berechnet werden kann, können Sie eine Interpolation von der ursprünglichen zur komponierten Quaternion ausführen, um einen glatten Übergang zu erzielen, damit Sie die Transformation animieren können. Sie können für Modelle, die Sie animieren möchten, eine Ziel-Quaternion für die Drehung mit einem QuaternionRotation3D für die Rotation-Eigenschaft angeben.
Verwenden von Transformationsauflistungen
Beim Erstellen einer Szene werden in der Regel mehrere Transformationen auf ein Modell angewendet. Fügen Sie Transformationen zur Children-Auflistung der Transform3DGroup-Klasse hinzu, um Transformationen bequem für die Anwendung auf verschiedene Modelle in der Szene zu gruppieren. Häufig ist es bequem, eine Transformation in mehreren verschiedenen Gruppen wieder zu verwenden, so wie Sie ein Modell wieder verwenden können, indem Sie auf jede Instanz einen anderen Satz von Transformationen anwenden. Beachten Sie, dass die Reihenfolge, in der Transformationen der Auflistung hinzugefügt werden, wichtig ist: Die Transformationen in der Auflistung werden von der ersten zur letzten angewendet.
Animieren von Transformationen
Die Windows Presentation Foundation (WPF)-3D-Implementierung gehört zum gleichen Zeitsteuerungs- und Animationssystem wie 2D-Grafiken. Mit anderen Worten: Zur Animation einer 3D-Szene animieren Sie die Eigenschaften ihrer Modelle. Sie können die Eigenschaften von Primitiven direkt animieren. In der Regel ist es jedoch einfacher, die Transformationen zu animieren, anhand derer die Position oder die Darstellung der Modelle geändert werden. Da sich Transformationen sowohl auf Model3DGroup-Objekte als auch auf einzelne Modelle anwenden lassen, können Sie einen Satz von Animationen auf die Elemente einer Model3DGroup und einen weiteren Satz von Animationen auf eine Gruppe von Objekten anwenden. Hintergrundinformationen über das Windows Presentation Foundation (WPF)-Zeitsteuerungs- und Animationssystem finden Sie unter Übersicht über Animationen und unter Übersicht über Storyboards.
Um ein Objekt in Windows Presentation Foundation (WPF) zu animieren, erstellen Sie eine Zeitachse, definieren eine Animation (tatsächlich eine Änderung einiger Eigenschaftenwerte im Zeitablauf) und geben die Eigenschaft an, auf die die Animation angewendet werden soll. Diese Eigenschaft muss eine Eigenschaft für ein FrameworkElement sein. Da alle Objekte in einer 3D-Szene untergeordnete Elemente von Viewport3D sind, handelt es sich bei den Eigenschaften, auf die sich die in der Szene anzuwendenden Animationen beziehen, um Eigenschaften von Viewport3D. Arbeiten Sie den Eigenschaftenpfad für die Animation sorgfältig aus, da die Syntax sehr ausführlich sein kann.
Angenommen, Sie möchten ein Objekt an der Stelle drehen, aber auch eine schwingende Bewegung anwenden, um einen größeren Teil des Objekts in der Ansicht verfügbar zu machen. Dazu sollten Sie RotateTransform3D auf das Modell anwenden und dessen Drehungsachse von einem Vektor auf einen anderen animieren. Im folgenden Codebeispiel wird das Anwenden einer Vector3DAnimation auf die Achseneigenschaft der Rotation3D-Transformation veranschaulicht. Es wird angenommen, dass RotateTransform3D als eine von mehreren Transformationen mit einer TransformGroup auf das Modell angewendet wird.
//Define a rotation
RotateTransform3D myRotateTransform = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 1));
Vector3DAnimation myVectorAnimation = new Vector3DAnimation(new Vector3D(-1, -1, -1), new Duration(TimeSpan.FromMilliseconds(5000)));
myVectorAnimation.RepeatBehavior = RepeatBehavior.Forever;
Verwenden Sie eine ähnliche Syntax, um das Objekt mit anderen Transformationseigenschaften zu verschieben oder zu skalieren. Wenden Sie z. B. bei einer Skalierungstransformation eine Point3DAnimation auf die ScaleCenter-Eigenschaft an, damit bei einem Modell dessen Form geglättet verzerrt wird.
Auch wenn in den vorherigen Beispielen die Eigenschaften von GeometryModel3D transformiert werden, ist auch eine Transformation von Eigenschaften anderer Modelle in der Szene möglich. Durch Animieren von Übersetzungen, die auf Lichtobjekte angewendet wurden, können Sie sich bewegende Licht- und Schatteneffekte erzeugen, die die Darstellung der Modelle erheblich verändern können.
Da Kameras auch Modelle sind, ist auch eine Transformation von Kameraeigenschaften möglich. Sie können die Darstellung der Szene durch die Transformation von Kameraposition oder Ebenenabständen (also durch Transformation der gesamten Szenenprojektion) durchaus ändern. Beachten Sie jedoch, dass viele Effekte, die Sie auf diese Weise erzielen, für den Betrachter visuell nicht nachvollziehbar sind, da die Transformationen auf die Position des Modells in der Szene angewendet werden.
Siehe auch
Aufgaben
Beispiel für 2D-Transformation