Ok, here is a routine you can tweak/add to your routines.
First the remarks.
1. Rotating and scaling an image relative to a destination rectangle can produce undesirable effects. For example rotating a square within the same square without having the rotated shape escape the original square's bounds, produces a rubber-band effect on the rotated shape -- changing sizes as angle changes.
2. In most cases, I would think rubber-banding would not be desirable. For example, a clock hand rotating.
Anyway, here is the algo that will rubberband. Adjust as needed.
a. New form, add 2 shape controls, 1 command button
b. Leave all controls at default names, properties, positions
c. Copy & paste the following into the form and run it
Code:
Option Explicit
Private Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)
Private Type POINTAPI
X As Long
Y As Long
End Type
Private Sub Form_Load()
Me.ForeColor = vbBlue
With Shape1
.Move 135, 135, 2550, 1485
End With
With Shape2
.Move 3105, 135, 1485, 1485
End With
With Command1
.Move 2250, 1710, 1215, 495
.Caption = "Do It"
End With
Me.Move Me.Left, Me.Top, 4875, 2805
End Sub
Private Sub Command1_Click()
Dim Angle As Single, A As Single, d2r As Double
Dim sinT As Double, cosT As Double
Dim h1 As Long, h2 As Long, hh As Long, ww As Long
d2r = (4& * Atn(1)) / 180 ' conversion factor for degree>radian
For A = 0 To 360
Angle = Abs(A) ' keep range between -90 to 90 for bounds calcs
Select Case Angle
Case Is < 91
Case Is < 181
Angle = 180 - Angle
Case Is < 271
Angle = Angle - 180
Case Else
Angle = 360 - Angle
End Select
sinT = Sin(Angle * d2r)
cosT = Cos(Angle * d2r)
With Shape1
h1 = .Height * .Height / (.Width * sinT + .Height * cosT)
h2 = .Width * .Width / (.Width * cosT + .Height * sinT)
If h1 < h2 Then hh = h1 Else hh = h2
ww = hh * .Width / .Height
End With
Me.Cls
Call ShowResults(A, ww, hh, Shape1)
With Shape2
h1 = .Height * .Height / (.Width * sinT + .Height * cosT)
h2 = .Width * .Width / (.Width * cosT + .Height * sinT)
If h1 < h2 Then hh = h1 Else hh = h2
ww = hh * .Width / .Height
End With
Call ShowResults(A, ww, hh, Shape2)
Me.Caption = A & " Degree Rotation"
DoEvents
Sleep 10
Next
Me.Caption = "Done"
End Sub
Private Sub ShowResults(Angle As Single, ScaledCx As Long, ScaledCy As Long, sampleShape As Shape)
' following is not part of the rotation/resizing routine
Dim tPTs(1 To 4) As POINTAPI, X As Long
Dim ctrSrc As POINTAPI, ctrDest As POINTAPI
Dim d2r As Double
Dim sinT As Double, cosT As Double
ctrSrc.X = ScaledCx \ 2
ctrSrc.Y = ScaledCy \ 2
With sampleShape
ctrDest.X = .Width \ 2 + .Left
ctrDest.Y = .Height \ 2 + .Top
End With
d2r = (4& * Atn(1)) / 180
sinT = Sin((Angle Mod 360) * d2r)
cosT = Cos((Angle Mod 360) * d2r)
tPTs(1).X = (-ctrSrc.X * cosT) - (-ctrSrc.Y * sinT) + ctrDest.X
tPTs(1).Y = (-ctrSrc.X * sinT) + (-ctrSrc.Y * cosT) + ctrDest.Y
tPTs(2).X = (ScaledCx - ctrSrc.X) * cosT - (-ctrSrc.Y * sinT) + ctrDest.X
tPTs(2).Y = (ScaledCx - ctrSrc.X) * sinT + (-ctrSrc.Y * cosT) + ctrDest.Y
tPTs(3).X = (ScaledCx - ctrSrc.X) * cosT - (ScaledCy - ctrSrc.Y) * sinT + ctrDest.X
tPTs(3).Y = (ScaledCx - ctrSrc.X) * sinT + (ScaledCy - ctrSrc.Y) * cosT + ctrDest.Y
tPTs(4).X = (-ctrSrc.X * cosT) - (ScaledCy - ctrSrc.Y) * sinT + ctrDest.X
tPTs(4).Y = (-ctrSrc.X * sinT) + (ScaledCy - ctrSrc.Y) * cosT + ctrDest.Y
For X = 1 To 3
Me.Line (tPTs(X).X, tPTs(X).Y)-(tPTs(X + 1).X, tPTs(X + 1).Y)
Next
Me.Line (tPTs(X).X, tPTs(X).Y)-(tPTs(1).X, tPTs(1).Y)
End Sub
Edited: ww & hh would be the scaled width/height in relation to the target rectangle and angle of rotation. Rendering must be done from center of target rectangle to prevent image drawing over target bounds.
Edited yet again. Now if you wanted to know what would be the scaled size of an image in a target rectangle so that the image can be rotated at any angle without rubberbanding, you can use this formula (refering to the GetScaledImageSizes code):
Code:
Dim rotSize As Long
rotSize = Sqr(m_Size.nWidth *m_Size.nWidth + m_Size.nHeight * m_Size.nHeight)
xRatio = destWidth / rotSize
yRatio = destHeight / rotSize
If xRatio > yRatio Then xRatio = yRatio
.... rest of code