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


/ Published in: VB.NET
Save to your folder(s)

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


Copy this code and paste it in your HTML
  1. Imports System.Drawing, System.Drawing.Drawing2D
  2.  
  3. Public Class Affine
  4. Dim mat As Matrix
  5. ''' <summary>
  6. ''' X value of translation vector.
  7. ''' </summary>
  8. ''' <value></value>
  9. ''' <returns></returns>
  10. ''' <remarks></remarks>
  11. Public ReadOnly Property offsetx() As Single
  12. Get
  13. Return mat.OffsetX
  14. End Get
  15. End Property
  16. ''' <summary>
  17. ''' Y value of translation vector.
  18. ''' </summary>
  19. ''' <value></value>
  20. ''' <returns></returns>
  21. ''' <remarks></remarks>
  22. Public ReadOnly Property offsety() As Single
  23. Get
  24. Return mat.OffsetY
  25. End Get
  26. End Property
  27.  
  28. ''' <summary>
  29. ''' rotation in degrees, clockwise = positive
  30. ''' </summary>
  31. ''' <remarks></remarks>
  32. Public rot As Single
  33.  
  34. ''' <summary>
  35. ''' x and y values of scale vector
  36. ''' </summary>
  37. ''' <remarks></remarks>
  38. Public scalex, scaley As Single
  39. ''' <summary>
  40. ''' x and y values of shear vector
  41. ''' </summary>
  42. ''' <remarks></remarks>
  43. Public shearx, sheary As Single
  44.  
  45. ''' <summary>
  46. ''' Construct a new Affine from the given Drawing2d.Matrix
  47. ''' </summary>
  48. ''' <param name="m"></param>
  49. ''' <remarks></remarks>
  50. Sub New(ByVal m As Matrix)
  51. mat = m
  52. Decompose()
  53. End Sub
  54.  
  55. ''' <summary>
  56. ''' Create a new Affine with default values (corresponding to identity matrix)
  57. ''' </summary>
  58. ''' <remarks></remarks>
  59. Sub New()
  60. mat = New matrix
  61. rot = 0
  62. scalex = 1
  63. scaley = 1
  64. shearx = 0
  65. sheary = 0
  66. End Sub
  67.  
  68. ''' <summary>
  69. ''' Decompose our matrix
  70. ''' </summary>
  71. ''' <remarks></remarks>
  72. Private Sub Decompose()
  73.  
  74. ' the original matrix
  75. Dim m0 As Matrix = mat
  76.  
  77. ' remove translation
  78. Dim m1 As New Matrix
  79. m1.Multiply(m0)
  80. m1.Translate(-m0.OffsetX, -m0.OffsetY)
  81.  
  82. ' get rotation
  83. Dim pts(1) As PointF
  84. pts(0) = New PointF(0, 0)
  85. pts(1) = New PointF(1, 0)
  86. m1.TransformPoints(pts)
  87. rot = Math.Atan2( _
  88. pts(1).Y - pts(0).Y, _
  89. pts(1).X - pts(0).X) * 180.0 / Math.PI
  90.  
  91. ' get scale and shear
  92. pts(0) = New PointF(0, 0)
  93. pts(1) = New PointF(1, 1)
  94. Dim m2 As New Matrix
  95. m2.Rotate(-rot)
  96. m2.Multiply(mat)
  97. m2.TransformPoints(pts)
  98.  
  99. scalex = pts(1).X - pts(0).X
  100. scaley = pts(1).Y - pts(0).Y
  101.  
  102. ' get shear
  103. shearx = pts(1).X - 1.0
  104. sheary = pts(1).Y - 1.0
  105.  
  106. End Sub
  107.  
  108. 'Sub test()
  109. ' Dim m As New Matrix
  110. ' Dim a As New Affine(m)
  111. ' Assert.AreEqual(0.0, a.rot)
  112. ' Assert.AreEqual(1.0, a.scalex)
  113. ' Assert.AreEqual(1.0, a.scaley)
  114. ' Assert.AreEqual(0.0, a.shearx)
  115. ' Assert.AreEqual(0.0, a.sheary)
  116.  
  117. ' m.Rotate(45)
  118. ' m.Scale(2, 3)
  119. ' a = New Affine(m)
  120. ' Assert.AreEqual(45.0, a.rot)
  121. ' Assert.Less(Math.Abs(2.0 - a.scalex), 0.001)
  122. ' Assert.Less(Math.Abs(3.0 - a.scaley), 0.001)
  123.  
  124. 'End Sub
  125. End Class

Report this snippet


Comments

RSS Icon Subscribe to comments

You need to login to post a comment.