数学问题关于.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

上一篇: Maths question about point rotation in .Net

下一篇: Delpoying play application on heroku