天天看點

Direct2D教程VII——變換幾何(TransformedGeometry)對象

目前部落格園中成系列的Direct2D的教程有

本系列的前幾篇文章:

<a href="http://www.cnblogs.com/grenet/p/3249664.html" target="_blank">Direct2D教程I——簡介及首個例子</a>

<a href="http://www.cnblogs.com/grenet/p/3250828.html" target="_blank">Direct2D教程II——繪制基本圖形和線型(StrokeStyle)的設定詳解</a>

<a href="http://www.cnblogs.com/grenet/p/3252512.html" target="_blank">Direct2D教程III——幾何(Geometry)對象</a>

<a href="http://www.cnblogs.com/grenet/archive/2013/08/14/3256175.html" target="_blank">Direct2D教程IV——筆刷(Brush)對象</a>

<a href="http://www.cnblogs.com/grenet/p/3265016.html" target="_blank">Direct2D教程V——位圖(Bitmap)和位圖筆刷(BitmapBrush)</a>

<a href="http://www.cnblogs.com/grenet/p/3269941.html" target="_blank">Direct2D教程VI——轉換(Transform)</a>

變換幾何(TransformedGeometry)的運用

在一些精度要求不高的場景下,為了提高效率,重視元件重用(即一個元件,多次使用)。變換幾何(TransformedGeometry)就應運而生,它是把一個源元件通過轉換(Transform)得到一個新元件,而不需要重新用大量的代碼增加新元件(可以省去很多的關于點的計算)。

和其他的幾何對象一樣,變換幾何(TransformedGeometry)也得通過D2DFactory對象的CreateTransformedGeometry方法來建立,來看看該方法的原型定義

Public Function CreateTransformedGeometry(sourceGeometry As Direct2D1.Geometry, transform As Direct2D1.Matrix3x2F) As Direct2D1.TransformedGeometry

從該函數的原型定義來看,隻有兩個參數:sourceGeometry,源幾何對象,類型是Geometry類;transform,對源幾何對象進行的轉換,類型是結構Matrix3x2F。

通過該方法獲得一個新的幾何對象

接下來,我們用一個例子來說明變換幾何(TransformedGeometry)的用法

Direct2D教程VII——變換幾何(TransformedGeometry)對象

上圖是一個簡單的圖形,分為左山、右山、小河、太陽、太陽光芒這幾部分。

我們先用路徑幾何(PathGeometry)對象建立右山,然後利用CreateTransformedGeometry方法建立了左山,并對它進行了縮放轉換(SacleTransform)。

太陽光芒的部分,先用路徑幾何(PathGeometry)對象建立基本的光芒,然後利用CreateTransformedGeometry方法建立光芒數組,并依次對數組中的光芒進行了旋轉轉換(RotateTransform)。

下面是示例代碼

Public Class clsDirect2DSample16

    Inherits clsDirect2DSample

    Public Shadows Sub Render()

        If Not _renderTarget Is Nothing Then

            Dim ColorBackground As New Direct2D1.ColorF(Color.Chocolate.ToArgb)

            Dim ColorBorder As New Direct2D1.ColorF(0, 0, 0)

            Dim ColorLeftMountain As New Direct2D1.ColorF(Color.OliveDrab.ToArgb)

            Dim ColorRightMountain As New Direct2D1.ColorF(Color.YellowGreen.ToArgb)

            Dim ColorRiver As New Direct2D1.ColorF(Color.LightSkyBlue.ToArgb)

            'Create Sun Brush

            Dim gradientStops(2) As Direct2D1.GradientStop

            gradientStops(0).Color = New Direct2D1.ColorF(Color.Gold.ToArgb)

            gradientStops(0).Position = 0

            Dim TC As New Direct2D1.ColorF(Color.Orange.ToArgb)

            TC.Alpha = 0.8

            gradientStops(1).Color = TC

            gradientStops(1).Position = 0.85

            TC = New Direct2D1.ColorF(Color.OrangeRed.ToArgb)

            TC.Alpha = 0.7

            gradientStops(2).Color = TC

            gradientStops(2).Position = 1

            Dim GS As Direct2D1.GradientStopCollection = _renderTarget.CreateGradientStopCollection(gradientStops, Direct2D1.Gamma.Linear, Direct2D1.ExtendMode.Clamp)

            Dim RBS As Direct2D1.RadialGradientBrushProperties

            RBS.Center = New Direct2D1.Point2F(185, 250)

            RBS.GradientOriginOffset = New Direct2D1.Point2F(80, 80)

            RBS.RadiusX = 85

            RBS.RadiusY = 85

            Dim RB As Direct2D1.RadialGradientBrush = _renderTarget.CreateRadialGradientBrush(RBS, GS)

            Dim BorderBrush As Direct2D1.SolidColorBrush = _renderTarget.CreateSolidColorBrush(ColorBorder)

            Dim FillBrush As Direct2D1.SolidColorBrush = _renderTarget.CreateSolidColorBrush(ColorBorder)

            'Create Right Mountain

            Dim rightMountainGeometry As Direct2D1.PathGeometry = _d2DFactory.CreatePathGeometry()

            Dim sink As Direct2D1.GeometrySink = rightMountainGeometry.Open

            sink.SetFillMode(Direct2D1.FillMode.Winding)

            sink.BeginFigure(New Direct2D1.Point2F(395, 263), Direct2D1.FigureBegin.Filled)

            Dim points() As Direct2D1.Point2F = { _

                                                            New Direct2D1.Point2F(301, 146), _

                                                            New Direct2D1.Point2F(269, 181), _

                                                            New Direct2D1.Point2F(253, 159), _

                                                            New Direct2D1.Point2F(221, 214), _

                                                            New Direct2D1.Point2F(201, 199), _

                                                            New Direct2D1.Point2F(143, 263), _

                                                            New Direct2D1.Point2F(395, 263)

                                                            }

            sink.AddLines(points)

            sink.EndFigure(Direct2D1.FigureEnd.Closed)

            sink.Close()

            'Create Left Mountain

            Dim leftMountainGeometry As Direct2D1.TransformedGeometry = _d2DFactory.CreateTransformedGeometry(rightMountainGeometry, Direct2D1.Matrix3x2F.Scale(-0.5, 0.6, New Direct2D1.Point2F(160, 250)))

            'Create Sun

            Dim sunGeometry As Direct2D1.PathGeometry = _d2DFactory.CreatePathGeometry

            sink = sunGeometry.Open

            sink.BeginFigure(New Direct2D1.Point2F(100, 250), Direct2D1.FigureBegin.Filled)

            sink.AddArc(New Direct2D1.ArcSegment(New Direct2D1.Point2F(270, 250), _

                                                                  New Direct2D1.SizeF(85, 85), _

                                                                  0, Direct2D1.SweepDirection.Clockwise, Direct2D1.ArcSize.Small))

            'Create Base Sun Light

            Dim sunLightGeometry As Direct2D1.PathGeometry = _d2DFactory.CreatePathGeometry

            sink = sunLightGeometry.Open

            sink.BeginFigure(New Direct2D1.Point2F(185, 140), Direct2D1.FigureBegin.Hollow)

            sink.AddBezier(New Direct2D1.BezierSegment(New Direct2D1.Point2F(170, 125), _

                                                                         New Direct2D1.Point2F(200, 125), _

                                                                         New Direct2D1.Point2F(185, 110)))

            sink.EndFigure(Direct2D1.FigureEnd.Open)

            'Create some Sun Lights

            Dim sunLights(4) As Direct2D1.TransformedGeometry

            Dim I As Integer

            For I = 0 To 4

                sunLights(I) = _d2DFactory.CreateTransformedGeometry(sunLightGeometry, Direct2D1.Matrix3x2F.Rotation(I * 20 - 40, New Direct2D1.Point2F(185, 250)))

            Next

            'Create River

            Dim riverGeometry As Direct2D1.PathGeometry = _d2DFactory.CreatePathGeometry

            sink = riverGeometry.Open

            sink.BeginFigure(New Direct2D1.Point2F(23, 392), Direct2D1.FigureBegin.Filled)

            sink.AddBezier(New Direct2D1.BezierSegment(New Direct2D1.Point2F(58, 284), _

                                                                         New Direct2D1.Point2F(312, 345), _

                                                                         New Direct2D1.Point2F(196, 303)))

            sink.AddBezier(New Direct2D1.BezierSegment(New Direct2D1.Point2F(77, 261), _

                                                                         New Direct2D1.Point2F(163, 256), _

                                                                         New Direct2D1.Point2F(163, 256)))

            sink.AddBezier(New Direct2D1.BezierSegment(New Direct2D1.Point2F(165, 257), _

                                                                         New Direct2D1.Point2F(81, 261), _

                                                                         New Direct2D1.Point2F(251, 306)))

            sink.AddBezier(New Direct2D1.BezierSegment(New Direct2D1.Point2F(414, 350), _

                                                                         New Direct2D1.Point2F(128, 324), _

                                                                         New Direct2D1.Point2F(136, 392)))

            With _renderTarget

                .BeginDraw()

                .Clear(ColorBackground)

                .DrawGeometry(sunGeometry, BorderBrush, 2)

                .FillGeometry(sunGeometry, RB)

                For I = 0 To 4

                    .DrawGeometry(sunLights(I), BorderBrush, 1)

                Next

                .DrawGeometry(riverGeometry, BorderBrush, 2)

                FillBrush.Color = ColorRiver

                .FillGeometry(riverGeometry, FillBrush)

                .DrawGeometry(rightMountainGeometry, BorderBrush, 2)

                FillBrush.Color = ColorRightMountain

                .FillGeometry(rightMountainGeometry, FillBrush)

                .DrawGeometry(leftMountainGeometry, BorderBrush, 2)

                FillBrush.Color = ColorLeftMountain

                .FillGeometry(leftMountainGeometry, FillBrush)

                .EndDraw()

            End With

        End If

    End Sub

End Class

通過上面的示例代碼說明了變換幾何(TransformedGeometry)對象的用法。它實際上是一種元件複用的思路,利用已知的元件,通過轉換(Transform)得到一個新的元件,簡化繪圖的難度。當然,變換幾何(TransformedGeometry)對象要想用的好,得和轉換(Transform)配合起來才行。

繼續閱讀