我有一个部分答案。从:
开始 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加到宽度。我确定它涉及到罪恶,cos或者两者兼而有之,但大脑冻结阻止我建立公式。
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围绕其中心旋转一个角度。我改变了边界的宽度和/或高度。我如何向后工作以找到原本会创建BoundsAfterRotation的imageBounds?
答案 0 :(得分:1)
将它向后旋转相同的角度,为负。请注意,您可以考虑使用System.Drawing.Matrix类。它有一个RotateAt()方法。使用TransformPoints()方法应用旋转。并使用Invert()方法创建一个将点映射回来的矩阵。
答案 1 :(得分:0)
您可以从图像转到旋转,但不能从旋转转换为图像。这是因为当你旋转时,你必须围绕像素位置,新图像看起来有点不同。
因此,您必须始终保持原始图像并为每个动作制作图像副本。
简单地向后旋转将会加倍舍入。
答案 2 :(得分:0)
我没有时间给出完整的答案,但请考虑以下内容:如果您从以pi / 2旋转的方块开始,那么它看起来像<>
,并让alpha为角度在连接正方形中心与其最右边和x轴的直线之间,然后非常基本的三角学告诉你,旋转方形的宽度是cos(alpha)*d
,d是正方形的对角线,如果alpha介于-pi / 4和pi / 4之间。
现在,你“只需”从你的角度计算alpha,检查哪些边缘是重要的知道宽度,并计算对角线的“未旋转”宽度。