(三)计算机图形学基本图形的生成(二维图形裁剪Cohen-Sutherland算法+图形平移算法+图形旋转算法)--附源码

该文详细介绍了如何在Win10环境下使用VisualStudio2022建立计算机图形学实验平台,涵盖了Cohen-Sutherland裁剪算法、图形平移和旋转算法的实现过程,包括源码和具体步骤,旨在帮助读者熟练掌握这些基本图形操作。
摘要由CSDN通过智能技术生成

系列文章:

(一)计算机图形学实验平台的建立--附源码

(二)计算机图形学基本图形的生成(直线DDA算法,直线中点算法,Bresenham画圆算法)--附源码

(三)计算机图形学基本图形的生成(二维图形裁剪Cohen-Sutherland算法+图形平移算法+图形旋转算法)--附源码

(四)计算机图形学基本图形的生成(扫描线填充算法+图形缩放算法+对称变换算法+消隐算法+金刚石图案算法)--附源码

环境:Win10+Visual Studio 2022 Community

在本次实验中需要用到第一篇文章实验内容的代码及环境,详情请见:传送门

目录

一、实验目的

二、实验步骤

1.Cohen-Sutherland算法

2.平移算法

3.旋转算法


一、实验目的

1.熟练掌握二维图形裁剪的Cohen-Sutherland算法

2.熟练掌握图形的平移算法

3.熟练掌握图形的旋转算法

二、实验步骤

1.Cohen-Sutherland算法

(1)打开工程项目,在菜单项“二维裁剪图形”下建立子菜单“Cohen算法”,在其属性窗口将属性项Name的属性值改为“CohenCut”。

(2)双击菜单项“Cohen算法”,系统建立一个空的菜单响应函数CohenCut_Click。在该函数中加入如下语句:

        private void CohenCut_Click(object sender, EventArgs e)
        {
            MenuID = 21; PressNum = 0;
            Graphics g = CreateGraphics();  //创建图形设备
            XL = 100; XR = 400; YD = 100; YU = 400; //窗口参数
            pointsgroup[0] = new Point(XL, YD);
            pointsgroup[1] = new Point(XR, YD);
            pointsgroup[2] = new Point(XR, YU);
            pointsgroup[3] = new Point(XL, YU);
            g.DrawPolygon(Pens.Blue, pointsgroup);  //创建裁剪窗口
        }

(3)用MenuID变量表示后续的操作都与该算法有关,因为要使用鼠标,因此初始化PressNum变量。用四个变量记录窗口参数,因为其他的很多算法也要使用窗口,因此将这四个变量变为Form类变量,为此要对Form类变量做添加如下;为了方便使用图形相关函数画窗口,设置了一个包含四个点的数组pointsgroup。由于其他算法也需要事先画窗口,将这个数组同样设置为Form类变量公共变量:

        public int MenuID, PressNum, FirstX, FirstY, OldX, OldY, XL, XR, YU, YD;
        Point[] pointsgroup = new Point[4]; //创建一个有4个点的点数组

(4)在Form1_MouseClick函数中,增加菜单指示变量MenuID为21(即开始 Cohen-Sutherland裁剪算法)时的程序操作语句如下:

            if (MenuID == 21)   //Cohen裁剪算法
            {
                if (PressNum == 0)  //保留第一点
                {
                    FirstX = e.X;
                    FirstY = e.Y;
                    PressNum++;
                }
                else    //第二点,调用裁剪算法
                {
                    CohenCut1(FirstX, FirstY, e.X, e.Y);  //Cohencut裁剪
                    PressNum = 0; //清零,为画下一次裁剪做准备
                }
            }

(5)函数CohenCut1是在窗口参数和线段参数都已获取的前提下实现Cohen-Sutherland 裁剪算法的函数。在窗体实现程序Form1.cs中插入以下函数:

        private void CohenCut1(int x1, int y1, int x2, int y2)
        {
            int code1 = 0, code2 = 0, code, x = 0, y = 0;
            Graphics g = CreateGraphics();  //创建图形设备
            g.DrawLine(Pens.Red, x1, y1, x2, y2);   //画原始线段
            code1 = encode(x1, y1); //对线段端点编码
            code2 = encode(x2, y2);
            while (code1 != 0 || code2 != 0)
            {
                if ((code1 & code2) != 0) return;   //完全不可见
                code = code1;
                if (code1 == 0) code = code2;
                if ((1 & code) != 0)    //求线段与窗口左边的交点:0001=1
                {
                    x = XL;
                    y = y1 + (y2 - y1) * (x - x1) / (x2 - x1);
                }
                else if ((2 & code) != 0)
                {
                    x = XR;
                    y = y1 + (y2 - y1) * (x - x1) / (x2 - x1);
                }
                else if ((4 & code) != 0)
                {
                    y = YD;
                    x = x1 + (x2 - x1) * (y - y1) / (y2 - y1);
                }
                else if ((8 & code) != 0)
                {
                    y = YU;
                    x = x1 + (x2 - x1) * (y - y1) / (y2 - y1);
                }
                if (code == code1)
                {
                    x1 = x;
                    y1 = y;
                    code1 = encode(x, y);
                }
                else
                {
                    x2 = x;
                    y2 = y;
                    code2 = encode(x, y);
                }
            }
            Pen MyPen = new Pen(Color.Black, 3);
            g.DrawLine(MyPen, x1, y1, x2, y2);
        }

(6)其中,函数encode的功能是对线段的一个端点进行编码,目前还没有,需要立即实现。如果严格按照算法描述方法逐个生成每个裁剪线段端点4个二进制码位,编程繁复。这里根据窗口参数先确定9个区域,然后根据端点落在哪个区域直接赋予编码。encode函数实现如下:

        private int encode(int x, int y)
        {
            int code = 0;
            if (x >= XL && x <= XR && y >= YD && y <= YU) code = 0; //窗口区域:0000
            if (x < XL && y >= YD && y <= YU) code = 1; //窗口左区域:0001
            if (x > XR && y >= YD && y <= YU) code = 2; //窗口右边域:0010
            if (x >= XL && x <= XR && y > YU) code = 8; //窗口上区域:1000
            if (x >= XL && x <= XR && y < YD) code = 4; //窗口下区域:0100
            if (x <= XL && y > YU) code = 9; //窗口左上区域:1001
            if (x >= XR && y > YU) code = 10; //窗口右上区域:1010
            if (x <= XL && y < YD) code = 5; //窗口左下区域:0101
            if (x >= XR && y < YD) code = 6; //窗口右下区域:0110
            return code;
        }

(6)运行结果

2.平移算法

(1)在菜单项“二维图形变换”下添加子菜单项“图形平移”,将其属性项Name的属性值改为英文字符“TransMove”。

(2)双击菜单项建立菜单响应函数,在系统建立的空的响应函数TransMove_Click中加入语句如下:

        private void TransMove_Click(object sender, EventArgs e)
        {
            MenuID = 11;
            PressNum = 0;
            Graphics g = CreateGraphics();  //创建图形设备
            pointsgroup[0] = new Point(100, 100);   //设置变换图形
            pointsgroup[1] = new Point(200, 100);
            pointsgroup[2] = new Point(200, 200);
            pointsgroup[3] = new Point(100, 200);
            g.DrawPolygon(Pens.Red, pointsgroup);   //显示图形
        }

(3)平移量用鼠标操作确定,即用鼠标先后确定两个点,第二点减去第一点的坐标增量就是平移量,将坐标增量分别加到原图形坐标上,就得到平移以后的图形,显示这个图形,就完成了平移变换,具体做法是在Form1_MouseClick函数中加入如下语句:

            if (MenuID == 11)   //平移
            {
                if (PressNum == 0)  //保留第一点
                {
                    FirstX = e.X;
                    FirstY = e.Y;
                }
                else    //第二点,确定平移量,改变图形参数
                {
                    for (int i = 0; i < 4; i++)
                    {
                        pointsgroup[i].X += e.X - FirstX;
                        pointsgroup[i].Y += e.Y - FirstY;
                    }
                    g.DrawPolygon(Pens.Blue, pointsgroup);
                }
                PressNum++;
                if (PressNum >= 2)
                {
                    PressNum = 0;           //完毕,清零,为下一次做准备
                }
            }

(4)运行结果

3.旋转算法

(1)在菜单项“二维图形变换”下建立子菜单项“图形旋转”,将其属性项Name的属性值改为英文字符“TransRotate”。

(2)双击菜单项建立菜单响应函数TransRotate_Click。在系统建立的空的响应函数中加入语句如下:

        private void TransRotate_Click(object sender, EventArgs e)
        {
            MenuID = 12;
            PressNum = 0;
            Graphics g = CreateGraphics();  //创建图形设备
            pointsgroup[0] = new Point(100, 100);
            pointsgroup[1] = new Point(200, 100);
            pointsgroup[2] = new Point(200, 200);
            pointsgroup[3] = new Point(100, 200);
            g.DrawPolygon(Pens.Red, pointsgroup);   //画出被旋转图形
        }

(3)在Form1_MouseClick函数中加入处理旋转的鼠标操作指令如下:

if (MenuID == 12)   //旋转
            {
                if (PressNum == 0)  //保留第一点
                {
                    FirstX = e.X;
                    FirstX = e.Y;
                }
                else    //第二点,确定旋转角度,改变图形参数
                {
                    double a;
                    if (e.X == FirstX && e.Y == FirstY) return; //排除两点重合的异常情况
                    if (e.X == FirstX && e.Y > FirstY)  //排除分母为0的异常情况
                    {
                        a = 3.1415926 / 2.0;
                    }
                    else if (e.X == FirstX && e.Y < FirstY)
                    {
                        a = 3.1415926 / 2.0 * 3.0;
                    }
                    else
                    {
                        //计算旋转弧度
                        a = Math.Atan((double)(e.Y - FirstY) / (double)(e.X - FirstX));
                    }
                    a = a / 3.1415926 * 180.0;  //弧度转化为角度
                    int x0 = 150, y0 = 150; //指定旋转中心
                    Matrix myMatrix = new Matrix(); //创建矩阵对象,以利用矩阵工具
                    myMatrix.Translate(-x0, -y0);   //创建平移量为(-x0,-y0)的平移矩阵
                    myMatrix.Rotate((float)a, MatrixOrder.Append);  //右乘角度为a的旋转矩阵
                    myMatrix.Translate(x0, y0, MatrixOrder.Append); //右乘平移量为(x0,y0)的平移矩阵
                    g.Transform = myMatrix;     //用复合矩阵变换图形设备
                    g.DrawPolygon(Pens.Blue, pointsgroup);  //显示旋转结果
                }
                PressNum++;
                if (PressNum >= 2)
                {
                    PressNum = 0;           //完毕,清零,为下一次做准备
                }
            }

(4)为了能够直接使用系统提供的矩阵设置、计算、处理工具,我们需要引进定义了矩阵的命名空间,添加语句如下:

using System.Drawing.Drawing2D;

(5)运行结果

VS 平台C#实现 1. 实验内容 用基本增量算法和Bresenham算法画直线 2.实验目的 1)理解在显示器上画图与在纸上画图的本质区别; 2)掌握直线的光栅扫描转换过程; 3)掌握不同算法绘制直线的思路和优缺点。 3. 实验要求 1)将像素网格表现出来,建立网格坐标系; 2)用橡皮筋的形式输入参数; 3)鼠标移动时,显示鼠标当前位置; 4)显示判别式的计算过程和下一点的选择策略; 5)记录生成点的坐标,建议用表的形式; 6)图形生成过程可以重复进行。 1. 实验内容 用正负法和Bresenham算法画圆弧 2.实验目的 1)掌握圆及圆弧的光栅扫描转换过程; 2)掌握不同算法绘制圆弧的技巧和优缺点。 3. 实验要求 1)将像素网格表现出来,建立网格坐标系; 2)用橡皮筋的形式输入参数; 3)鼠标移动时,显示鼠标当前位置; 4)显示判别式的计算过程和下一点的选择策略; 5)记录生成点的坐标,建议用表的形式; 6)图形生成过程可以重复进行。 1. 实验内容 用Cohen-SutherLand算法和liang _barsky算法进行线段裁剪 2.实验目的 1)理解裁剪的相关概念 2)掌握直线段的一般裁剪过程; 3)理解并掌握Cohen-SutherLand 算法的编码思想; 4)理解并掌握Liang_Barsky算法的参数化裁剪思想; 3. 实验要求 1)将像素网格表现出来,建立网格坐标系; 2)用橡皮筋的形式输入剪裁线段和裁剪窗口; 3)鼠标移动时,显示鼠标当前位置; 4)对于线段裁剪,线段被窗口的四条边裁剪的过程要显示出来; 6)裁剪过程可以重复进行。 1. 实验内容 用Sutherland-Hodgman算法进行多边形裁剪 2.实验目的 1)理解多边形裁剪与直线段裁剪的区别; 2)掌握多边形的裁剪过程; 3)理解并掌握Sutherland-Hodgman算法裁剪思想。 3. 实验要求 1)将像素网格表现出来,建立网格坐标系; 2)用橡皮筋的形式输入剪裁多边形和裁剪窗口; 3)鼠标移动时,显示鼠标当前位置; 4)多边形被窗口的四条边裁剪的过程以及多边形顶点增删的过程要显示出来; 5)裁剪过程可以重复进行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

juechen333

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值