C#使用GDI对一个矩形进行任意角度旋转

C#对一个矩形进行旋转GDI绘图,可以指定任意角度进行旋转

我们可以认为一张图片Image,本质就是一个矩形Rectangle,旋转矩形也就是旋转图片

在画图密封类 System.Drawing.Graphics中,

矩形旋转的两个关键方法

//设置旋转的中心点

public void TranslateTransform(float dx, float dy);

//旋转指定的角度【单位°】:旋转角度 从 X+ 到 Y+之间的旋转角度认为是正数

public void RotateTransform(float angle);

矩形旋转WindowsForms应用程序

新建窗体应用程序RotatedRectangleDemo,将默认的Form1重命名为FormRotatedRectangle

窗体FormRotatedRectangle设计如图:

窗体设计FormRotatedRectangle设计器代码如下:

文件FormRotatedRectangle.Designer.cs

cs 复制代码
namespace RotatedRectangleDemo
{
    partial class FormRotatedRectangle
    {
        /// <summary>
        /// 必需的设计器变量。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// 清理所有正在使用的资源。
        /// </summary>
        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows 窗体设计器生成的代码

        /// <summary>
        /// 设计器支持所需的方法 - 不要修改
        /// 使用代码编辑器修改此方法的内容。
        /// </summary>
        private void InitializeComponent()
        {
            this.btnRotate = new System.Windows.Forms.Button();
            this.label1 = new System.Windows.Forms.Label();
            this.numRotate = new System.Windows.Forms.NumericUpDown();
            ((System.ComponentModel.ISupportInitialize)(this.numRotate)).BeginInit();
            this.SuspendLayout();
            // 
            // btnRotate
            // 
            this.btnRotate.Font = new System.Drawing.Font("宋体", 13F);
            this.btnRotate.Location = new System.Drawing.Point(271, 7);
            this.btnRotate.Name = "btnRotate";
            this.btnRotate.Size = new System.Drawing.Size(75, 33);
            this.btnRotate.TabIndex = 0;
            this.btnRotate.Text = "旋转";
            this.btnRotate.UseVisualStyleBackColor = true;
            this.btnRotate.Click += new System.EventHandler(this.btnRotate_Click);
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(25, 20);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(119, 12);
            this.label1.TabIndex = 1;
            this.label1.Text = "旋转角度(0°~360°)";
            // 
            // numRotate
            // 
            this.numRotate.DecimalPlaces = 2;
            this.numRotate.Location = new System.Drawing.Point(150, 16);
            this.numRotate.Maximum = new decimal(new int[] {
            360,
            0,
            0,
            0});
            this.numRotate.Name = "numRotate";
            this.numRotate.Size = new System.Drawing.Size(97, 21);
            this.numRotate.TabIndex = 2;
            this.numRotate.Value = new decimal(new int[] {
            30,
            0,
            0,
            0});
            // 
            // FormRotatedRectangle
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(945, 508);
            this.Controls.Add(this.numRotate);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.btnRotate);
            this.Name = "FormRotatedRectangle";
            this.Text = "GDI旋转示例:矩形旋转任意角度";
            ((System.ComponentModel.ISupportInitialize)(this.numRotate)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Button btnRotate;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.NumericUpDown numRotate;
    }
}

旋转矩形示例代码如下:

文件FormRotatedRectangle.cs

cs 复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace RotatedRectangleDemo
{
    public partial class FormRotatedRectangle : Form
    {
        public FormRotatedRectangle()
        {
            InitializeComponent();
            /* 定义了一个名为FormRotatedRectangle的窗体类,
             * 它覆盖(override)了OnPaint方法来绘制旋转的矩形。
             * 在OnPaint方法中,我们首先设置矩形的位置和大小,然后保存图形状态,
             * 接着设置旋转变换的中心点,通过RotateTransform方法设置旋转角度,并绘制旋转后的矩形,最后恢复图形状态。
             * 程序运行时,会显示一个旋转了30度的矩形。
            */
        }

        /// <summary>
        /// 窗体重绘事件
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics g = e.Graphics;

            // 设置矩形的位置和大小
            Rectangle rect = new Rectangle(100, 100, 200, 100);

            RotateRectangle(g, rect, (float)numRotate.Value);
        }

        /// <summary>
        /// 将初始矩形旋转指定的角度数
        /// </summary>
        /// <param name="g">窗体画图对象</param>
        /// <param name="rect">初始矩形对象(x,y,width,height)</param>
        /// <param name="rotateAngle">旋转角度,单位°</param>
        private void RotateRectangle(Graphics g, Rectangle rect, float rotateAngle) 
        {
            // 保存原始状态
            GraphicsState state = g.Save();

            // 设置旋转的中心点为矩形的中心
            g.TranslateTransform(rect.X + rect.Width / 2, rect.Y + rect.Height / 2);

            // 旋转矩形:旋转角度 从 X+ 到 Y+之间的旋转角度认为是正数
            g.RotateTransform(rotateAngle);

            // 恢复变换的中心点
            g.TranslateTransform(-(rect.X + rect.Width / 2), -(rect.Y + rect.Height / 2));

            // 绘制矩形
            g.DrawRectangle(Pens.Black, rect);

            // 恢复图形状态
            g.Restore(state);
        }

        private void btnRotate_Click(object sender, EventArgs e)
        {
            this.Invalidate();//引起触发重绘OnPaint事件
        }
    }
}

程序运行如图:

旋转45°【π/4】

旋转90°【π/2】

相关推荐
神仙别闹1 小时前
基于C#+SQL Server实现(Web)学生选课管理系统
前端·数据库·c#
向宇it2 小时前
【unity组件介绍】URP Decal Projector贴花投影器,将特定材质(贴花)投影到场景中的其他对象上。
游戏·3d·unity·c#·游戏引擎·材质
斯是 陋室11 小时前
在CentOS7.9服务器上安装.NET 8.0 SDK
运维·服务器·开发语言·c++·c#·云计算·.net
inwith13 小时前
C#语法基础总结(超级全面)(二)
开发语言·c#
ヾChen16 小时前
13届蓝桥杯省赛程序设计试题
物联网·学习·蓝桥杯·c#
我是唐青枫21 小时前
C#.NET 泛型详解
开发语言·c#·.net
Yasin Chen21 小时前
C# StringBuilder源码分析
开发语言·c#
格林威1 天前
Baumer工业相机堡盟工业相机如何通过YoloV8模型实现人物识别(C#)
开发语言·人工智能·数码相机·yolo·计算机视觉·c#
Rabbb1 天前
C# JSON 反序列化时,忽略转换失败的属性 JTokenSafeToExtensions
后端·c#·json
三目条件1 天前
C#将类属性保存到Ini文件方法(利用拓展方法,反射方式获取到分组名和属性名称属性值)
java·开发语言·c#