-2

我使用此过程将 4 个边框的矩形旋转为 wpf 中的角:

    'find the center
    Dim center As New Point(((topRight.Margin.Left - topLeft.Margin.Left) / 2) + topLeft.Margin.Left,
                            ((topLeft.Margin.Top - bottomLeft.Margin.Top) / 2) + bottomLeft.Margin.Top)

    'shift the points to center and calculate the rotation
    Dim tl As Point = getRotatedPoint(New Point(topLeft.Margin.Left - center.X,
                                                topLeft.Margin.Top - center.Y), 1)
    Dim tr As Point = getRotatedPoint(New Point(topRight.Margin.Left - center.X,
                                                topRight.Margin.Top - center.Y), 1)
    Dim bl As Point = getRotatedPoint(New Point(bottomLeft.Margin.Left - center.X,
                                                bottomLeft.Margin.Top - center.Y), 1)
    Dim br As Point = getRotatedPoint(New Point(bottomRight.Margin.Left - center.X,
                                                bottomRight.Margin.Top - center.Y), 1)

    'shift the points back from center and move
    topLeft.Margin = New Thickness(tl.X + center.X, tl.Y + center.Y, 0, 0)
    topRight.Margin = New Thickness(tr.X + center.X, tr.Y + center.Y, 0, 0)
    bottomLeft.Margin = New Thickness(bl.X + center.X, bl.Y + center.Y, 0, 0)
    bottomRight.Margin = New Thickness(br.X + center.X, +br.Y + center.Y, 0, 0)

getRotatedPoint 函数是:

'rotating the borders
Private Function getRotatedPoint(ByVal pnt As Point, ByVal degrees As Double)
    Dim rAngle As Double = degrees * (Math.PI / 180)
    Dim x As Double = pnt.X * Math.Cos(rAngle) - pnt.Y * Math.Sin(rAngle)
    Dim y As Double = pnt.X * Math.Sin(rAngle) + pnt.Y * Math.Cos(rAngle)
    Return New Point(x, y)
End Function

但我得到非常混乱的结果,我不知道,任何想法都会受到欢迎:)

edit1:我将 getRotatedPoint 函数更改为双精度,并添加了弧度到度数的转换。

edit2:修正弧度转换函数。

edit3:更正了中心坐标,但仍然会发生一些偏移。

edit4:这里是测试人员的示例项目:http: //dl.dropbox.com/u/33417300/testapp.zip

4

1 回答 1

2

如前所述,不清楚您所说的“混乱结果”是什么意思,因此我想到了几种解释:

如果您的旋转不正确,可能是因为您以度为单位传递角度,而 SIN 和 COS 函数需要弧度。这似乎很可能,因为您将角度作为整数而不是浮点表示形式传递。如果要将它们作为度数传递,请在将它们传递给三角函数之前转换为弧度。

其次,如果杂乱的结果意味着代码很复杂,您可能希望将仿射变换表示为矩阵。对于 2-D 情况,您可以通过添加 1 作为第三个元素来将 2-D 向量扩展为 3-D。您的转换是 3x3 矩阵,您可以将它们相乘以创建旋转、缩放、倾斜、平移等序列。生成的转换可以用作向量 - 矩阵乘法。

更新:

这个函数有一些问题:

Private Function getRotatedPoint(ByVal pnt As Point, ByVal angle As Integer)
    Dim x As Integer = pnt.X * Math.Cos(angle) - pnt.Y * Math.Sin(angle)
    Dim y As Integer = pnt.X * Math.Sin(angle) + pnt.Y * Math.Cos(angle)
    Return New Point(x, y)
End Function

除了度数/弧度混淆的问题外,整数和浮点之间的类型转换留给编译器和 .Net 框架,这可能与您的意图不一致。我将重写如下:

Private Function getRotatedPoint(ByVal pnt As Point, ByVal radians As Double)
    Dim x As Double = CDbl(pnt.X) * Math.Cos(radians) - CDbl(pnt.Y) * Math.Sin(radians)
    Dim y As Double = CDbl(pnt.X) * Math.Sin(radians) + CDbl(pnt.Y) * Math.Cos(radians)
    Return New Point(CInt(x), CInt(y))
End Function

不过,我仍然建议使用矩阵库来执行此操作。它将让您专注于开发程序的核心功能,而不是调试和排除已被多次编写和重写的内容。

更新 2:

这也是有问题的:

Dim center As New Point((topLeft.Margin.Left + topRight.Margin.Left) / 2,
                            (topLeft.Margin.Left + bottomLeft.Margin.Left) / 2)

这不应该是:

Dim center As New Point((topLeft.Margin.Left + topRight.Margin.Right) / 2,
                            (topLeft.Margin.Top + bottomLeft.Margin.Bottom) / 2)

如果我错了,那么您将需要详细解释您的 topLeft、topRight、bottomLeft 和 bottomRight 值所代表的内容,足以让任何人帮助您……请参阅 Kendall Frey 对SSCCE的评论。

于 2012-06-25T16:41:44.807 回答