Return to Snippet

Revision: 15167
at June 26, 2009 14:36 by rpresser


Initial Code
Imports System.Drawing, System.Drawing.Drawing2D

Public Class Affine
    Dim mat As Matrix
    ''' <summary>
    ''' X value of translation vector.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property offsetx() As Single
        Get
            Return mat.OffsetX
        End Get
    End Property
    ''' <summary>
    ''' Y value of translation vector.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property offsety() As Single
        Get
            Return mat.OffsetY
        End Get
    End Property

    ''' <summary>
    ''' rotation in degrees, clockwise = positive
    ''' </summary>
    ''' <remarks></remarks>
    Public rot As Single

    ''' <summary>
    ''' x and y values of scale vector
    ''' </summary>
    ''' <remarks></remarks>
    Public scalex, scaley As Single
    ''' <summary>
    ''' x and y values of shear vector
    ''' </summary>
    ''' <remarks></remarks>
    Public shearx, sheary As Single

    ''' <summary>
    ''' Construct a new Affine from the given Drawing2d.Matrix
    ''' </summary>
    ''' <param name="m"></param>
    ''' <remarks></remarks>
    Sub New(ByVal m As Matrix)
        mat = m
        Decompose()
    End Sub

    ''' <summary>
    ''' Create a new Affine with default values (corresponding to identity matrix)
    ''' </summary>
    ''' <remarks></remarks>
    Sub New()
        mat = New matrix
        rot = 0
        scalex = 1
        scaley = 1
        shearx = 0
        sheary = 0
    End Sub

    ''' <summary>
    ''' Decompose our matrix
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub Decompose()

        ' the original matrix
        Dim m0 As Matrix = mat

        ' remove translation
        Dim m1 As New Matrix
        m1.Multiply(m0)
        m1.Translate(-m0.OffsetX, -m0.OffsetY)

        ' get rotation
        Dim pts(1) As PointF
        pts(0) = New PointF(0, 0)
        pts(1) = New PointF(1, 0)
        m1.TransformPoints(pts)
        rot = Math.Atan2( _
            pts(1).Y - pts(0).Y, _
            pts(1).X - pts(0).X) * 180.0 / Math.PI

        ' get scale and shear
        pts(0) = New PointF(0, 0)
        pts(1) = New PointF(1, 1)
        Dim m2 As New Matrix
        m2.Rotate(-rot)
        m2.Multiply(mat)
        m2.TransformPoints(pts)

        scalex = pts(1).X - pts(0).X
        scaley = pts(1).Y - pts(0).Y

        ' get shear
        shearx = pts(1).X - 1.0
        sheary = pts(1).Y - 1.0

    End Sub

    'Sub test()
    '    Dim m As New Matrix
    '    Dim a As New Affine(m)
    '    Assert.AreEqual(0.0, a.rot)
    '    Assert.AreEqual(1.0, a.scalex)
    '    Assert.AreEqual(1.0, a.scaley)
    '    Assert.AreEqual(0.0, a.shearx)
    '    Assert.AreEqual(0.0, a.sheary)

    '    m.Rotate(45)
    '    m.Scale(2, 3)
    '    a = New Affine(m)
    '    Assert.AreEqual(45.0, a.rot)
    '    Assert.Less(Math.Abs(2.0 - a.scalex), 0.001)
    '    Assert.Less(Math.Abs(3.0 - a.scaley), 0.001)

    'End Sub
End Class

Initial URL


Initial Description
Thanks to some messages on CodeProject.com for the final answers, here assembled in one place

Initial Title
Get translation, rotation, scale and shear out of a System.Drawing.Drawing2d.Matrix affine transformation

Initial Tags


Initial Language
VB.NET