winforms 旋转图像的矩形边界

xxslljrj  于 2022-11-17  发布在  其他
关注(0)|答案(1)|浏览(145)

我正在绘制使用图形转换旋转的图像,但无法获得旋转图像的位置和大小。
绘画事件:

graphics.TranslateTransform(BaseX, BaseY);
graphics.RotateTransform((float)Rotation);
graphics.DrawImage(Image, X - BaseX, Y - BaseY, Image.Width, Image.Height);

ToRectangle方法:

public Rectangle ToRotatedRectangle() {
    // Code here to rotate X, Y, Image.Width and Image.Height values
    return new Rectangle(rotatedX, rotatedY, rotatedWidth, rotatedHeight);
}

我看过其他几个帖子可以得到旋转后的大小,但是没有一个包含X和Y值。我尝试过单独旋转它们,但是the location is not correct

at0kjp5o

at0kjp5o1#

请注意:“graphics.RotateTransform(X)”将图像顺时针旋转X,而“Math.Cos(X)”和“Math.Sin(X)”基于X弧度进行计算。
根据您的平移/旋转,我们可以使用三角函数计算sin和cos值。

graphics.TranslateTransform(BaseX, BaseY);
graphics.RotateTransform((float)Rotation);

...

var sin = Math.Sin(Rotation * Math.PI / 180.0);
var cos = Math.Cos(Rotation * Math.PI / 180.0);

使用如下的线性代数将所得到的图形矩阵乘以任何给定的(X,Y

// (X, Y) =>
// | cos  -sin  BaseX | | X |   | X*cos-Y*sin+BaseX |
// | sin   cos  BaseY | | Y | = | X*sin+Y*cos+BaseY |
// |  0     0     1   | | 1 |   |        1          |
// => (X*cos-Y*sin+BaseX, X*sin+Y*cos+BaseY)

在图形上绘制的4个角点是:

var (x1, y1) = (X-BaseX, Y-BaseY);
var (x2, y2) = (X-BaseX+Image.Width, Y-BaseY);
var (x3, y3) = (X-BaseX, Y-BaseY+Image.Height);
var (x4, y4) = (X-BaseX+Image.Width, Y-BaseY+Image.Height);

因此在平移/旋转之后,它们变成

var (X1, Y1) = (cos*(X-BaseX)-sin*(Y-BaseY)+BaseX, sin*(X-BaseX)+cos*(Y-BaseY)+BaseY);
var (X2, Y2) = (cos*(X-BaseX+Image.Width)-sin*(Y-BaseY)+BaseX, sin*(X-BaseX+Image.Width)+cos*(Y-BaseY)+BaseY);
var (X3, Y3) = (cos*(X-BaseX)-sin*(Y-BaseY+Image.Height)+BaseX, sin*(X-BaseX)+cos*(Y-BaseY+Image.Height)+BaseY);
var (X4, Y4) = (cos*(X-BaseX+Image.Width)-sin*(Y-BaseY+Image.Height)+BaseX, sin*(X-BaseX+Image.Width)+cos*(Y-BaseY+Image.Height)+BaseY);

要得到左上角,您需要每个X和Y值中的最小值。宽度和高度将是最大和最小X和Y值之间的差值,可以简化如下所示。

var (X, Y) = (Math.Min(Math.Min(X1, X2), Math.Min(X3, X4)), Math.Min(Math.Min(Y1, Y2), Math.Min(Y3, Y4)));
var (Width, Height) = (Math.Abs(cos*Image.Width)+Math.Abs(sin*Image.Height), Math.Abs(sin*Image.Width)+Math.Abs(cos*Image.Height));

相关问题