Cohen Sutherland线段裁剪算法(C#实现)
来源:互联网 发布:好学而近乎知 编辑:程序博客网 时间:2024/05/17 13:41
Cohen Sutherland线段裁剪算法(C#实现)
一、问题说明:
平面上有一个矩形框和一条线段,将线段画到平面上,只显示线段在矩形框中的部分,即矩形框中的部分为可见的。已知矩形框的四个边框的坐标值Left,Right,Top,Buttom和线段的两个端点的坐标P1、P2。通过算法实现该过程。
二、算法思想:
该算法将矩形边框分别延长(即沿着边框做直线)将平面分成九个部分,对九个部分分别编码,并将两个端点按所在的区域进行编码。线段与矩形有五种位置情况。
1、 判断端点是否在中间区域,都在就将线段画出来。
2、端点在四个边框的同一侧就不用画出
3、不在其中就求线段与边框的交点,将外边的部分去掉。对于剩余的部分当做新的线段的处理,从头开始再判断。循环两次就能判断剩余部分是保留还是舍去。
三、程序代码
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;namespace Cohen_Sutherland{ public partial class Form1 : Form { public Form1() { InitializeComponent(); } //设置矩形窗口的四条边 private int left = 100, right = 200, top = 100, buttom = 200; //设置裁剪直线的端点 private Point P1 = new Point(100, 100), P2 = new Point(200, 200); //设置编码 最后四位对应上 下 右 左 private int CodeLeft = 1; private int CodeRight = 2; private int CodeButtom = 4; private int CodeTop = 8; private void btnCut_Click(object sender, EventArgs e) { Graphics g = pictureBox1.CreateGraphics(); Pen p = new Pen(Color.Blue); g.DrawLine(p, new Point(left, top), new Point(right, top)); g.DrawLine(p, new Point(left, top), new Point(left, buttom)); g.DrawLine(p, new Point(right, top), new Point(right, buttom)); g.DrawLine(p, new Point(right, buttom), new Point(left, buttom)); g.DrawLine(new Pen(Color.Gray), P1, P2); CohenSutherland(P1.X, P1.Y, P2.X, P2.Y); } private void CohenSutherland(int P1x, int P1y, int P2x, int P2y) { int C1 = Code(P1x, P1y), C2 = Code(P2x, P2y); int C; int Px = 0, Py = 0;//记录交点 while (C1 != 0 || C2 != 0)//两个点(P1x,P1y),(P2x,P2y)不都在矩形框内;都在内部就画出线段 { if ((C1 & C2) != 0) //两个点在矩形框的同一外侧 → 不可见 { P1x = 0; P1y = 0; P2x = 0; P2y = 0; break; } C = C1; if (C1 == 0)// 判断P1 P2谁在矩形框内(可能是P1,也可能是P2) { C = C2; } if ((C & CodeLeft) != 0)//用与判断的点在左侧 { Px = left; Py = P1y + (int)(Convert.ToDouble(P2y - P1y) / (P2x - P1x) * (left - P1x)); } else if ((C & CodeRight) != 0)//用与判断的点在右侧 { Px = right; Py = P1y + (int)(Convert.ToDouble(P2y - P1y) / (P2x - P1x) * (right - P1x)); } else if ((C & CodeTop) != 0)//用与判断的点在上方 { Py = top; Px = P1x + (int)(Convert.ToDouble(P2x - P1x) / (P2y - P1y) * (top - P1y)); } else if ((C & CodeButtom) != 0)//用与判断的点在下方 { Py = buttom; Px = P1x + (int)(Convert.ToDouble(P2x - P1x) / (P2y - P1y) * (buttom - P1y)); } if (C == C1) //上面判断使用的是哪个端点就替换该端点为新值 { P1x = Px; P1y = Py; C1 = Code(P1x, P1y); } else { P2x = Px; P2y = Py; C2 = Code(P2x, P2y); } } Graphics g = pictureBox1.CreateGraphics(); Pen p = new Pen(Color.Red); g.DrawLine(p, new Point(P1x, P1y), new Point(P2x, P2y)); } private int Code(int x, int y) //端点编码函数 左右上下分别对应一位 { int c = 0; if (x < left) { c = c | CodeLeft; } if (x > right) { c = c | CodeRight; } if (y < top) { c = c | CodeTop; } if (y > buttom) { c = c | CodeButtom; } return c; } private void btnParameter_Click(object sender, EventArgs e) { left = Convert.ToInt32(txtLeft.Text); right = Convert.ToInt32(txtRight.Text); top = Convert.ToInt32(txtTop.Text); buttom = Convert.ToInt32(txtButtom.Text); P1.X = Convert.ToInt32(txtP1X.Text); P1.Y = Convert.ToInt32(txtP1Y.Text); P2.X = Convert.ToInt32(txtP2X.Text); P2.Y = Convert.ToInt32(txtP2Y.Text); } private void btnClear_Click(object sender, EventArgs e) { pictureBox1.Refresh(); } private void pictureBox1_MouseMove(object sender, MouseEventArgs e) { toolStripStatusLabelAxis.Text = "X:" + e.X + " Y:" + e.Y; } }}
四、结果显示
显示线段与矩形框的五种位置关系,红线为裁剪所得,灰色为参考的整条线段
- Cohen Sutherland线段裁剪算法(C#实现)
- Cohen-Sutherland线段裁剪算法
- Cohen-Sutherland算法线段裁剪
- Cohen-Sutherland线段裁剪算法
- Cohen-Sutherland线段裁剪算法
- Cohen-Sutherland算法裁剪线段
- Cohen-Sutherland线段裁剪算法
- Cohen-Sutherland 窗口裁剪线段算法
- 计算机图形学 - 线段裁剪 - Cohen Sutherland算法
- Cohen-Sutherland裁剪算法
- Cohen-Sutherland裁剪算法
- Cohen-SutherLand 裁剪算法 (vc++)
- 【裁剪】线段的裁剪——Cohen-Sutherland算法及代码实现
- 计算机图形学-直线裁剪(Cohen-Sutherland编码裁剪算法)
- 裁剪算法 - Cohen Sutherland Clipping的原理及Java实现
- opengl 直线裁剪Cohen-Sutherland算法
- Cohen-Sutherland直线段的裁剪算法
- 编码实现Cohen-Sutherland端点编码算法
- 字符串匹配算法总结
- 转:IT恐怖战国:通往终极垄断的最后几级台阶
- 初始化顺序 java c# c++
- Mysql基础命令(Dos下)
- BUG xib中的连接没有 去掉
- Cohen Sutherland线段裁剪算法(C#实现)
- My First Plug-in - Inventor API .NET 开发从0开始-课程2
- My C# CookBook
- outlook 迁移 备份
- S5PV210和S5PC110,S5PC210和S5PV310,S3C2440和S3C2442的区别
- 【转】分享discuz网站地图(免安装)自己正在用!
- Jquery基础1
- 关于synchronized的测试
- Jquery基础二 选择符