У меня есть частичный ответ.Начиная с:
newHeight = Высота * cos (радианы) + Ширина * sin (радианы)
newWidth = Высота * sin (радианы) + Ширина * cos (радианы)
Я могупереверните уравнения, чтобы получить:
temp = sqr (cos (радианы)) - sqr (sin (радианы))
высота = newHeight * cos (радианы) - newWidth * sin (радианы) / temp
Width = newWidth * cos (радианы) - newHeight * sin (радианы) / temp
Приведенные выше уравнения действуют только для угловых диапазонов 0-28, 62-90, 180-208 и 242-270.Из этих диапазонов расчетные границы слишком велики и приводят к переполнению при 45, 135, 225 и 315.
Полагаю, мне нужно определить, в каком квадранте я нахожусь, и немного изменить уравнения.Есть идеи?
Я изо всех сил пытался понять, что именно я спрашиваю в этом вопросе, так что, надеюсь, следующий пример прояснит ситуацию.
То, что делает пример, это взять квадрат 100x100,поверните его на 12 градусов и добавьте 100 к ширине.То, что я хочу сделать, это выяснить размеры прямоугольника, который при повороте на 12 градусов приведет к тому же прямоугольнику, не добавляя потом 100 к ширине:
Рисованные прямоугольники являются границамиповернутая фигура, а не сама фигура:
Dim radAngle = Math.PI * 12 / 180.0R
Dim widthChange = 100
Dim b2 = New RectangleF(200, 200, 100, 100)
b2 = GetBoundsAfterRotation(b2, radAngle)
b2.Width += widthChange
g.DrawRectangle(Pens.Red, ToRectangle(b2))
Dim offsetY = 21
Dim offsetX = -7
b2 = New RectangleF(200, 200, 100 + widthChange - offsetX, 100 - offsetY)
b2 = GetBoundsAfterRotation(b2, radAngle)
b2.X += CInt(offsetX / 2)
b2.Y += CInt(offsetY / 2)
g.DrawRectangle(Pens.Green, ToRectangle(b2))
Путем следа и ошибки я нашел значения offsetX и offsetY, которые приведут к одному и тому же прямоугольнику для этого конкретного случая: квадрат 100x100, повернутый на 12 градусов с 100добавлен к ширине.Я уверен, что это связано с грехом, потому что или где-то и то и другое, но замораживание мозга мешает мне построить формулу.
ETA: В этом случае я увеличиваю ширину, но мне нужно общее решение для ширины, высоты илиоба изменяются.
ETA2: Для этого случая размер результирующей прямоугольной границы был 218,6 x 118,6.Чтобы получить эти границы после поворота на 12 градусов, начальные границы прямоугольника были около 207 x 79.
Оригинал:
Я использую следующие стандартные процедуры, чтобы получить границыизображение после его поворота на заданный угол относительно его центра.Границы смещены таким образом, что центр изображения всегда находится в одном и том же месте:
Public Function GetBoundsAfterRotation(ByVal imageBounds As RectangleF, ByVal radAngle As Double) As RectangleF
Dim w = imageBounds.Width
Dim h = imageBounds.Height
Dim rotationPoints As PointF() = {New PointF(0, 0), New PointF(w, 0), New PointF(0, h), New PointF(w, h)}
RotatePoints(rotationPoints, New PointF(w / 2.0F, h / 2.0F), radAngle)
Dim newBounds = GetBoundsF(rotationPoints)
Dim x = imageBounds.X + newBounds.X //Offset the location to ensure the centre point remains the same
Dim y = imageBounds.Y + newBounds.Y
Return New RectangleF(New PointF(x, y), newBounds.Size)
End Function
//
Public Shared Sub RotatePoints(ByVal pnts As PointF(), ByVal origin As PointF, ByVal radAngle As Double)
For i As Integer = 0 To pnts.Length - 1
pnts(i) = RotatePoint(pnts(i), origin, radAngle)
Next
End Sub
//
Public Shared Function RotatePoint(ByVal pnt As PointF, ByVal origin As PointF, ByVal radAngle As Double) As PointF
Dim newPoint As New PointF()
Dim deltaX As Double = pnt.X - origin.X
Dim deltaY As Double = pnt.Y - origin.Y
newPoint.X = CSng((origin.X + (Math.Cos(radAngle) * deltaX - Math.Sin(radAngle) * deltaY)))
newPoint.Y = CSng((origin.Y + (Math.Sin(radAngle) * deltaX + Math.Cos(radAngle) * deltaY)))
Return newPoint
End Function
//
Public Shared Function GetBoundsF(ByVal pnts As PointF()) As RectangleF
Dim left As Single = pnts(0).X
Dim right As Single = pnts(0).X
Dim top As Single = pnts(0).Y
Dim bottom As Single = pnts(0).Y
For i As Integer = 1 To pnts.Length - 1
If pnts(i).X < left Then
left = pnts(i).X
ElseIf pnts(i).X > right Then
right = pnts(i).X
End If
If pnts(i).Y < top Then
top = pnts(i).Y
ElseIf pnts(i).Y > bottom Then
bottom = pnts(i).Y
End If
Next
Return New RectangleF(left, top, CSng(Math.Abs(right - left)), CSng(Math.Abs(bottom - top)))
End Function
Мой вопрос:
У меня есть несколько BoundsAfterRotation, которые были повернуты на угол вокруг его центра.Я изменяю ширину и / или высоту границ.Как я могу работать в обратном направлении, чтобы найти оригинальное изображение Bounds, которое могло бы создать BoundsAfterRotation?