数学问题关于.Net中的点旋转
我有一个部分答案。 从...开始:
newHeight = Height * cos(弧度)+ Width * sin(弧度)
newWidth = Height * sin(弧度)+ Width * cos(弧度)
我可以通过反转方程来得到:
temp = sqr(cos(弧度)) - sqr(sin(弧度))
Height = newHeight * cos(弧度) - newWidth * sin(弧度)/ temp
宽度= 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是围绕它的中心旋转一个角度。 我改变边界的宽度和/或高度。 我如何向后查找原本可能创建BoundsAfterRotation的imageBounds?
只需将其旋转回相同的角度即可。 请注意,您可以考虑使用System.Drawing.Matrix类。 它有一个RotateAt()方法。 使用TransformPoints()方法来应用旋转。 Invert()方法创建一个将点映射回来的矩阵。
你可以从图像转到旋转,但不能从旋转到图像。 这是因为当你旋转时,你必须四舍五入像素位置,新图像看起来有点不同。
因此,您必须始终坚持原始图像,并为每次循环制作图像副本。
简单地旋转回来将会加倍舍入。
我没有时间给出完整的答案,但请考虑以下事项:如果以π/ 2旋转的方块开始,使其看起来像<>
,并且让alpha为连接中心的线之间的角度然后相当基本的三角函数告诉你,旋转的正方形的宽度是cos(alpha)*d
,其中d是正方形的对角线,如果alpha在-pi / 4和pi / 4。
现在,你“只是”必须从你的角度计算alpha,检查极其重要的那些边缘是知道宽度的重要因素,并从对角线计算“未旋转”的宽度。
链接地址: http://www.djcxy.com/p/95147.html