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】

相关推荐
friklogff1 小时前
【无标题】云端之C#:全面解析6种云服务提供商的SDK
开发语言·flask·c#
c#上位机2 小时前
C#事件的用法
java·javascript·c#
chnyi6_ya2 小时前
一些写leetcode的笔记
笔记·leetcode·c#
IT规划师3 小时前
C#|.net core 基础 - 扩展数组添加删除性能最好的方法
c#·.netcore·数组
时光追逐者3 小时前
分享6个.NET开源的AI和LLM相关项目框架
人工智能·microsoft·ai·c#·.net·.netcore
friklogff4 小时前
【C#生态园】提升C#开发效率:深入了解自然语言处理库与工具
开发语言·c#·区块链
__water12 小时前
『功能项目』回调函数处理死亡【54】
c#·回调函数·unity引擎
__water12 小时前
『功能项目』眩晕图标显示【52】
c#·unity引擎·动画事件
__water13 小时前
『功能项目』第二职业法师的平A【57】
c#·unity引擎·魔法球伤害传递
__water15 小时前
『功能项目』战士的伤害型技能【45】
c#·unity引擎·战士职业伤害型技能