计算机图形 直线的裁剪代码,计算机图形学 直线裁剪代码.doc

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

namespace LineCut_Cohen

{

public partial class Form1 : Form

{

public Form1()

{

InitializeComponent();

}

//定义钻石参数

int x0 = 100;

int y0 = 100;

int n = 13;

int r = 50;

int[] x;

int[] y;

//

//计算钻石顶点 by tiantian

//

public void ZuanShi()

{

float t = (float)3.14159 * 2 / n;

x = new int[n];

y = new int[n];

for (int i = 0; i < n; i++)

{

x[i] = (int)(r * Math.Cos(i * t) + x0);

y[i] = (int)(r * Math.Sin(i * t) + y0);

}

}

//

//计算点(x,y)的编码

//

void CompOutCode(int x, int y, Rectangle rect, OutCode outCode)

{

outCode.all = 0;

outCode.top = outCode.bottom = 0;

if (y < rect.Top) //rect类的top相当于我们惯常用的坐标系的bottom by:tiantian

{

outCode.bottom = 1;

outCode.all += 1;

}

else if (y > rect.Bottom)//rect类的bottom相当于我们惯常用的坐标系的top by:tiantian

{

outCode.top = 1;

outCode.all += 1;

}

outCode.right = outCode.left = 0;

if (x > rect.Right)

{

outCode.right = 1;

outCode.all += 1;

}

else if (x < rect.Left)

{

outCode.left = 1;

outCode.all += 1;

}

}

//

//线段裁剪,p0(x0,y0),p1(x1,y1)为待裁剪线断,rect为裁剪窗口

//

bool ChoenSutherlandLineClip(ref int x0, ref int y0, ref int x1, ref int y1, Rectangle rect) //这里必须是引用传递!by:tiantian

{

Boolean accept, done;

OutCode outCode0 = new OutCode();

OutCode outCode1 = new OutCode();

OutCode outCodeOut = new OutCode();

int x = 0;

int y = 0;

accept = false;

done = false;

CompOutCode(x0, y0, rect, outCode0);

CompOutCode(x1, y1, rect, outCode1);

do

{

int code0 = outCode0.Code();

int code1 = outCode1.Code();

if ((outCode0.all == 0) && (outCode1.all == 0)) //完全可见

{

accept = true;

done = true;

}

else if ((code0 & code1) != 0) //显然不可见 by tt

done = true;

else //进行求交测试

{

if (outCode0.all != 0) //判断哪一点位于窗口之外

outCodeOut = outCode0;

else outCodeOut = outCode1;

if (outCodeOut.left == 1)//线段与窗口的左边相交

{

x = rect.Left;

y = y0 + (y1 - y0) * (x - x0) / (x1 - x0);

}

else if (outCodeOut.right == 1)//线段与窗口的右边相交

{

x = rect.Right;

y = y0 + (y1 - y0) * (x - x0) / (x1 - x0);

}

else if (outCodeOut.top == 1)//线段与窗口的上边相交

{

y = rect.Bottom;

x = x0 + (x1 - x0) * (y - y0) / (y1 - y0);

}

else if (outCodeOut.bottom == 1)//线段与窗口的下边相交

{

y = rect.Top;

x = x0 + (x1 - x0) * (y - y0) / (y1 - y0);

}

//以交点为界,将线段位于窗口边所在的直线的外侧的部分丢弃。

//对剩余的继续裁剪

if (outCodeOut.all == outCode0.all)

{

x0 = x;

y0 = y;

CompOutCode(x0, y0, rect, outCode0);

}

else

{

x1 = x;

y1 = y;

CompOutCode(x1, y1, rect, outCode1);

}

}

} while (!done);

return accept;

}

//

//画图函数

//

private void Form1_Paint_1(object sender, PaintEventArgs e)

{

Graphics g = e.Graphics;

Pen myPen = new Pen(Color.Blue, 1f);

g.Clear(Color.Black);

ZuanShi();

for (int i = 0; i <= n - 2; i++)

for (int j = i + 1; j <= n - 1; j++)

g.DrawLine(myPen, x[i], y[i], x[j], y[j]);

}

//

//裁剪按钮

//

private void button1_Click(object sender, EventArgs e)

{

//定义矩形

Point p = new Point(50, 50);

Size size = new Size(50, 50);

Rectangle rect = new Rectangle(p, size);

Graphics g = this.CreateGraphics();

Pen myPen = new Pen(Color.Yellow, 1f);

g.Clear(Color.Black);

ZuanShi();

int xi, xj, yi, yj;//用来存储顶点值的变量 by tiantian

for (int i = 0; i <= n - 2; i++)

for (int j = i + 1; j <= n - 1; j++)

{

xi = x[i]; xj = x[j];//裁剪函数为引用传递,会改变顶点的值,先把这些值存储起来 by:tiantian

yi = y[i]; yj = y[j];

if (ChoenSutherlandLineClip(ref x[i], ref y[i], ref x[j], ref y[j], rect))

{

g.DrawLine(myPen, x[i], y[i], x[j], y[j]);

x[i] = xi; x[j] = xj;//恢复顶点值

y[i] = yi; y[j] = yj;

}

}

}

private void button2_Click(object sender, EventArgs e)

{

Graphics g = this.CreateGraphics();

Pen myPen = new Pen(Color.Blue, 1f);

g.Clear(Color.Black);

ZuanShi();

for (int i = 0; i <= n - 2; i++)

for (int j = i + 1; j <= n - 1; j++)

g.DrawLine(myPen, x[i], y[i], x[j], y[j]);

}

}

}

using System;

using System.Collections.Generic;

using System.Text;

namespace LineCut_Cohen

{

class OutCode

{//顶点编码值类 by tiantian

public OutCode()

{ }

public int all;

public int left, right, top, bottom;

//

//计算编码值 by tiantian

//

public int Code()

{ return top * 2 * 2 * 2 + bottom * 2 * 2 + left * 2 + right; }

}

}

展开阅读全文

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值