精华内容
下载资源
问答
  • 通过c++实现图形学多边形裁剪,简单有效。
  • 编写应用程序实现多边形裁剪。要求首先采用鼠标确定裁剪区域(矩形区域),然后用鼠标输入待裁剪的多边形(可分别使用鼠标左键和右键来确定裁剪区域和待裁剪的多边形)。 多边形绘制完毕后进行裁剪,以不同颜色显示...
  • 使用C#实现计算机图形学中的多边形裁剪算法,界面友好,功能完善
  • 自己控制裁剪窗口和多边形大小,处理各种多边形裁剪区域的位置关系
  • 提供给要交作业的各位!这是一个关于多边形裁剪的代码,希望能帮到大家!
  • 能够在TC上实现任意多边形裁剪,并在计算机上运行成功,为方便同学学习,特此给大家下载。
  • 网上有很多这类算法,都是有很多错,拿 来运行不起,保证此程序经运行上传;
  • 计算机图形学作业,不需修改直接在WINtc下运行
  • 基于MFC的计算机图形学中点裁剪算法多边形裁剪算法
  • 计算机图形学简单多边形裁剪程序

    热门讨论 2013-06-03 16:42:08
    计算机图形学简单多边形裁剪程序,开发环境VC++6.0,语言C++
  • Suther land-Hodgeman多边形裁剪 核心思想 将多边形作为一个整体 每次用窗口的一条边对要裁剪的多边形和中间结果多边形进行裁剪 分治思想 先用窗口的左边界对多边形进行裁剪 就会得到1 ,2两个点 然后和多边形其他...

    Suther land-Hodgeman多边形裁剪

    核心思想

    将多边形作为一个整体 每次用窗口的一条边对要裁剪的多边形和中间结果多边形进行裁剪 分治思想
    在这里插入图片描述
    先用窗口的左边界对多边形进行裁剪 就会得到1 ,2两个点 然后和多边形其他点作为下一个输入 在这里插入图片描述

    四种情况

    在这里插入图片描述
    交点I和定点P被加入
    2.在这里插入图片描述
    顶点P加入 因为S在之前会被加入 也就是判断S那条直线时就会被加入
    3.
    在这里插入图片描述
    S和I加入
    4.
    在这里插入图片描述
    S和P都不加入

    例子

    在这里插入图片描述

    不足之处

    对于凹多边形会产生多余线段
    在这里插入图片描述

    展开全文
  • 本资源包含了Cohen-Sutherland算法、Liang-Barsky算法实现直线段裁剪以及自创的多边形裁剪(老师都没查出BUG)的cpp源代码和实验报告。重点是多边形裁剪,400多行代码,最终实现了任意多边形裁剪,下载即可运行
  • 二维图形的裁剪算法研究与改进 机械制造及其自动化 2011 硕士 摘要 本文对计算机图形学中的基础裁剪算法进行了研究针对目前的conhen-sutherland线段裁剪算法不能有效地判断出线段是否完全在窗口外的问题,提出了一种...
  • #include , line(left,top,right,top); line(left,bottom,right,bottom); line(left,top,left,bottom); line(right,top,right,bottom); //绘制边框和裁剪图形
  • 计算机图形学多边形裁剪与填充 MFC实现代码,还有其他直线消隐等,需要的留言
  • 计算机图形学多边形裁剪算法,本程序中包括直线画法,直线裁剪,多边形画法和多边形裁剪过程,可以实现。
  • 上述多边形裁剪对于凸多边形适用,但对于部分凹多边形会出现错误如下图,向外凹陷地位置裁剪结果包含了一条本不应该有的线,对于该问题由于时间问题,还没有完成,但已经形成一定可行的改进思路。 首先还是要先求...

    用窗口的四条边的边界分别对所画多边形进行裁剪,每次裁剪后的结果都会生成一个新的多边形,再将这一多边形作为输入多边形再以裁剪窗口其他边界裁剪,最终达到裁剪多边形的目的。上述多边形裁剪对于凸多边形适用,但对于部分凹多边形会出现错误如下图,向外凹陷地位置裁剪结果包含了一条本不应该有的线,对于该问题由于时间问题,还没有完成,但已经形成一定可行的改进思路。

    首先还是要先求出多边形与裁剪区域的交点,同时类似于梁友栋算法的入边出边,把交点分成进入点和出点,然后将交点和原来的顶点按照多边形的顺序存储到同一个数组里,同样将裁剪区域和产生的交点也按照顺序存储起来。从多边形的某一顶点出发,开始遍历,遇到第一个进入点,此时进入裁剪区域,记录这个点,继续遍历直到找到第一个从边界“出去”的点,这时候开始在裁剪窗口里进行遍历,找到一个进入点再转换为多边形序列继续遍历,不断重复,直到发现回到第一个进入边界的点,将这些点组成的多边形绘制出来,就完成了裁剪。这样可以有效地解决凹多边形出现错误的问题。具体代码还没有实现。

    private void 裁剪(Point[] ArrPoint, Point[] rect)
            {
                Point[] ArrPoint2 = new Point[100];//每判断一条边就会改变多边形顶点顺序,存入此数组
                Graphics g = pictureBox1.CreateGraphics();
                Pen p2 = new Pen(Color.Red, 2);
                int i = 0;
                int xmin = rect[0].X;
                int xmax = rect[1].X;
                int ymin = rect[0].Y;
                int ymax = rect[2].Y;
                int j = 0;
                //rect[0]和rect[1]相连的边
                for (i = 0; i < num1; i++)
                {
                    //均在可见一侧
                    if (ArrPoint[i].Y >= ymin && ArrPoint[(i + 1) % num1].Y >= ymin)
                    {
                        ArrPoint2[j] = ArrPoint[(i + 1) % num1];
                        j = j + 1;
                    }
                    //均在不可见一侧
                    if (ArrPoint[i].Y < ymin && ArrPoint[(i + 1) % num1].Y < ymin)
                    {
                        //啥也不做
                    }
                    //起点在可见一侧,终点在不可见一侧
                    if (ArrPoint[i].Y >= ymin && ArrPoint[(i + 1) % num1].Y < ymin)
                    {
                        ArrPoint2[j] = 交点(ArrPoint[i], ArrPoint[(i + 1) % num1],
                       rect[0], rect[1]);//存储交点
                        j = j + 1;
                    }
                    //起点不可见,终点可见
                    if (ArrPoint[i].Y < ymin && ArrPoint[(i + 1) % num1].Y >= ymin)
                    {
                        ArrPoint2[j] = 交点(ArrPoint[i], ArrPoint[(i + 1) % num1], rect[0],
                       rect[1]);//存储交点
                        j = j + 1;
                        ArrPoint2[j] = ArrPoint[(i + 1) % num1];
                        j = j + 1;
                    }
                }
                num1 = j;
                j = 0;
                //rect[0]和rect[2]相连的边
                for (i = 0; i < num1; i++)
                {
                    //均在可见一侧
                    if (ArrPoint2[i].X >= xmin && ArrPoint2[(i + 1) % num1].X >= xmin)
                    {
                        ArrPoint[j] = ArrPoint2[(i + 1) % num1];
                        j = j + 1;
                    }
                    //均在不可见一侧
                    if (ArrPoint2[i].X < xmin && ArrPoint2[(i + 1) % num1].X < xmin)
                    {
                        //啥也不做
                    }
                    //起点在可见一侧,终点在不可见一侧
                    if (ArrPoint2[i].X >= xmin && ArrPoint2[(i + 1) % num1].X < xmin)
                    {
                        ArrPoint[j] = 交点(ArrPoint2[i], ArrPoint2[(i + 1) % num1],
                       rect[0], rect[2]);//存储交点
                        j = j + 1;
                    }
                    //起点不可见,终点可见
                    if (ArrPoint2[i].X < xmin && ArrPoint2[(i + 1) % num1].X >= xmin)
                    {
                        ArrPoint[j] = 交点(ArrPoint2[i], ArrPoint2[(i + 1) % num1],
                       rect[0], rect[2]);//存储交点
                        j = j + 1;
                        ArrPoint[j] = ArrPoint2[(i + 1) % num1];
                        j = j + 1;
                    }
                }
                num1 = j;
                j = 0;
                //rect[2]和rect[3]相连的边
                for (i = 0; i < num1; i++)
                {
                    //均在可见一侧
                    if (ArrPoint[i].Y <= ymax && ArrPoint[(i + 1) % num1].Y <= ymax)
                    {
                        ArrPoint2[j] = ArrPoint[(i + 1) % num1];
                        j = j + 1;
                    }
                    //均在不可见一侧
                    if (ArrPoint[i].Y > ymax && ArrPoint[(i + 1) % num1].Y > ymax)
                    {
                        //啥也不做
                    }
                    //起点在可见一侧,终点在不可见一侧
                    if (ArrPoint[i].Y <= ymax && ArrPoint[(i + 1) % num1].Y > ymax)
                    {
                        ArrPoint2[j] = 交点(ArrPoint[i], ArrPoint[(i + 1) % num1],
                       rect[2], rect[3]);//存储交点
                        j = j + 1;
                    }
                    //起点不可见,终点可见
                    if (ArrPoint[i].Y > ymax && ArrPoint[(i + 1) % num1].Y <= ymax)
                    {
                        ArrPoint2[j] = 交点(ArrPoint[i], ArrPoint[(i + 1) % num1],
                       rect[2], rect[3]);//存储交点
                        j = j + 1;
                        ArrPoint2[j] = ArrPoint[(i + 1) % num1];
                        j = j + 1;
                    }
                }
                num1 = j;
                j = 0;
                //rect[1]和rect[3]相连的边
                for (i = 0; i < num1; i++)
                {
                    //均在可见一侧
                    if (ArrPoint2[i].X <= xmax && ArrPoint2[(i + 1) % num1].X <= xmax)
                    {
                        ArrPoint[j] = ArrPoint2[(i + 1) % num1];
                        j = j + 1;
                    }
                    //均在不可见一侧
                    if (ArrPoint2[i].X > xmax && ArrPoint2[(i + 1) % num1].X > xmax)
                    {
                        //啥也不做
                    }
                    //起点在可见一侧,终点在不可见一侧
                    if (ArrPoint2[i].X <= xmax && ArrPoint2[(i + 1) % num1].X > xmax)
                    {
                        ArrPoint[j] = 交点(ArrPoint2[i], ArrPoint2[(i + 1) % num1],
                       rect[1], rect[3]);//存储交点
                        j = j + 1;
                    }
                    //起点不可见,终点可见
                    if (ArrPoint2[i].X > xmax && ArrPoint2[(i + 1) % num1].X <= xmax)
                    {
                        ArrPoint[j] = 交点(ArrPoint2[i], ArrPoint2[(i + 1) % num1],
                       rect[1], rect[3]);//存储交点
                        j = j + 1;
                        ArrPoint[j] = ArrPoint2[(i + 1) % num1];
                        j = j + 1;
                    }
                }
                num1 = j;
                for (i = 0; i < num1; i++)
                {
                    g.DrawLine(p2, ArrPoint[i], ArrPoint[(i + 1) % num1]);
                }
            }
    
            private Point 交点(Point firstpoint, Point secondpoint, Point s1, Point s2)
            {
                Point jiaodian = new Point(0, 0);
                double k;
                if (s1.X == s2.X)
                {
                    if (firstpoint.X == secondpoint.X)
                    {
                        //啥也不做
                    }
                    else
                    {
                        k = ((double)(firstpoint.Y) - secondpoint.Y) / (firstpoint.X - secondpoint.X);
                        double y = k * (s1.X - firstpoint.X) + firstpoint.Y;
                        jiaodian.X = s1.X;
                        jiaodian.Y = (int)(y);
                    }
                }
                if (s1.Y == s2.Y)
                {
                    if (firstpoint.Y == secondpoint.Y)
                    {
                        //啥也不做
                    }
                    else
                    {
                        k = ((double)(firstpoint.X) - secondpoint.X) / (firstpoint.Y -
                       secondpoint.Y);
                        double x = k * (s1.Y - firstpoint.Y) + firstpoint.X;
                        jiaodian.X = (int)(x);
                        jiaodian.Y = s1.Y;
                    }
                }
                return jiaodian;
            }

    书写比较复杂,还请见谅

    以上就是我在学习多边形裁剪算法过程中所写的程序,如果有什么可以改进的地方欢迎来探讨;如果有错误也麻烦指正。

    下面是我整合学习图形学的程序包

    https://download.csdn.net/download/gygygyyyyyy/12550827

    展开全文
  • 多边形裁剪是一个复杂而又常用的功能,然而自己造轮子是万万不能的。所以花了一个下午浏览了网上现在能够找到所有可以进行多边形裁剪的库,除去没有代码(Polygon Clipper library)、库太庞大(CGAL)、难以编译...

    背景

    多边形裁剪是一个复杂而又常用的功能,然而自己造轮子是万万不能的。所以花了一个下午浏览了网上现在能够找到所有可以进行多边形裁剪的库,除去没有代码(Polygon Clipper library)、库太庞大(CGAL)、难以编译(clipoly);最终选定Clipper,并将其稍加修改转移到CMake下方便使用。

    代码地址

    https://github.com/Yannnnnnnnnnnn/polygon_clipper

    工具介绍

    Clipper是由Angus Johnson开发的多边形裁剪库,能够支持交、并、差、异或等运算,以下是我根据其原始代码编写的一些demo的结果。

    这里写图片描述

    这里写图片描述

    这里写图片描述

    异或

    这里写图片描述

    展开全文
  • 二维图形裁剪算法: 参考博客: https://blog.csdn.net/m0_46359746/article/details/106392352 Liang-Barsky 线段裁剪算法: //Liang-Barsky 线段裁剪算法 class wcPt2D { public: GLfloat x,y; public: /* ...

    二维图形裁剪算法:

    参考博客:

    https://blog.csdn.net/m0_46359746/article/details/106392352

    image-20200930153345235

    Liang-Barsky 线段裁剪算法:

    //Liang-Barsky 线段裁剪算法
    
    class wcPt2D {
    
    public:
    	GLfloat x,y;
    public:
    	/*
    Default Constructor:initalize position 48(0.0,0.0).*/
    	wcPt2D(){
    		x=y=0.0;
    	}
    
    	wcPt2D(GLfloat nx, GLfloat ny): x(nx), y(ny){}
    
    	wcPt2D(const wcPt2D& pCopy){
    		this->x=pCopy.x;
    		this->y=pCopy.y;
    	}
    
    	void setCoords(GLfloat xCoord,GLfloat yCoord){
    		x = xCoord;
    		y = yCoord;
    		return ;
    	}
    
    	wcPt2D& operator= (wcPt2D p2){
    		this->x=p2.getx ();
    		this->y=p2.gety ();
    		return *this;
    	}
    
    
    	GLfloat getx()const{
    		return x;
    	}
    	GLfloat gety ( ) const {
    		return y;
    	}
    };
    
    inline GLint round(const GLfloat a){
    	return GLint(a + 0.5);
    }
    
    GLint clipTest(GLfloat p, GLfloat q, GLfloat * u1, GLfloat *u2){
    	GLfloat r;
    	GLint returnValue=true;
    	if(p<0.0){
    		r=q/p;
    		if(r>*u2){
    			returnValue = false;
    		}else if(r>*u1){
    			*u1=r;
    		}
    	}else{
    		if(p>0.0){
    			r=q/p;
    			if(r<*u1){
    				returnValue=false;
    			}else if(r<*u2){
    				*u2=r;
    			}
    		}else{
    
    			if(q<0.0){
    				returnValue=false;
    			}
    		}
    	}
    	return (returnValue);
    }
    
    
    void lineClipLiangBrask(wcPt2D winMin, wcPt2D winMax, wcPt2D p1, wcPt2D p2){
    	GLfloat u1=0.0, u2=1.0, dx=p2.getx ()-p1.getx (),dy;
    	if(clipTest (-dx, p1.getx ()-winMin.getx (),&u1, &u2)){
    		if(clipTest (dx, winMax.getx ()-p1.getx (),&u1, &u2)){
    			dy=p2.gety ()-p1.gety ();
    			if(clipTest (-dy, p1.gety ()-winMin.gety (), &u1, &u2)){
    				if(clipTest (dy,winMax.gety ()-p1.gety (),&u1, &u2)){
    					if(u2<1.0){
    						p2.setCoords(p1.getx ()+u2*dx,p1.gety ()+u2*dy);
    					}
    					if(u1>0.0){
    						p1.setCoords(p1.getx ()+u1*dx, p1.gety ()+u1*dy);
    					}
    					lineDDA (round(p1.getx ()), round (p1.gety ()),round(p2.getx ()),round(p2.gety ()));
    				}
    			}
    		}
    	}
    
    	return ;
    }
    

    display:

    //	Liang-Barsky线段裁剪算法
    //初始直线
    glColor3f (0.0,0.0,1.0);
    lineBres (0,100,400,300);
    glFlush ();
    
    //可视化边界:
    glColor3f(1.0,0.0,0.0);
    lineBres (100,100,100,300);
    lineBres (100,100,300,100);
    lineBres (300,300,100,300);
    lineBres (300,300,300,100);
    
    
    glColor3f (0.0,1.0,0.0);
    lineClipLiangBrask (wcPt2D(100,100), wcPt2D(300, 300), wcPt2D(0,100),wcPt2D(400, 300));
    glFlush ();
    

    Liang-Barsky 多边形裁剪算法:

    //-----------------------------------------
    //Liang-Barsky 线段裁剪算法
    
    class wcPt2D {
    
    public:
    	GLfloat x,y;
    public:
    	/*
    Default Constructor:initalize position 48(0.0,0.0).*/
    	wcPt2D(){
    		x=y=0.0;
    	}
    
    	wcPt2D(GLfloat nx, GLfloat ny): x(nx), y(ny){}
    
    	wcPt2D(const wcPt2D& pCopy){
    		this->x=pCopy.x;
    		this->y=pCopy.y;
    	}
    
    	void setCoords(GLfloat xCoord,GLfloat yCoord){
    		x = xCoord;
    		y = yCoord;
    		return ;
    	}
    
    	wcPt2D& operator= (wcPt2D p2){
    		this->x=p2.getx ();
    		this->y=p2.gety ();
    		return *this;
    	}
    
    
    	GLfloat getx()const{
    		return x;
    	}
    	GLfloat gety ( ) const {
    		return y;
    	}
    };
    
    inline GLint round(const GLfloat a){
    	return GLint(a + 0.5);
    }
    
    GLint clipTest(GLfloat p, GLfloat q, GLfloat * u1, GLfloat *u2){
    	GLfloat r;
    	GLint returnValue=true;
    	if(p<0.0){
    		r=q/p;
    		if(r>*u2){
    			returnValue = false;
    		}else if(r>*u1){
    			*u1=r;
    		}
    	}else{
    		if(p>0.0){
    			r=q/p;
    			if(r<*u1){
    				returnValue=false;
    			}else if(r<*u2){
    				*u2=r;
    			}
    		}else{
    
    			if(q<0.0){
    				returnValue=false;
    			}
    		}
    	}
    	return (returnValue);
    }
    
    
    void lineClipLiangBrask(wcPt2D winMin, wcPt2D winMax, wcPt2D p1, wcPt2D p2){
    	GLfloat u1=0.0, u2=1.0, dx=p2.getx ()-p1.getx (),dy;
    	if(clipTest (-dx, p1.getx ()-winMin.getx (),&u1, &u2)){
    		if(clipTest (dx, winMax.getx ()-p1.getx (),&u1, &u2)){
    			dy=p2.gety ()-p1.gety ();
    			if(clipTest (-dy, p1.gety ()-winMin.gety (), &u1, &u2)){
    				if(clipTest (dy,winMax.gety ()-p1.gety (),&u1, &u2)){
    					if(u2<1.0){
    						p2.setCoords(p1.getx ()+u2*dx,p1.gety ()+u2*dy);
    					}
    					if(u1>0.0){
    						p1.setCoords(p1.getx ()+u1*dx, p1.gety ()+u1*dy);
    					}
    					lineDDA (round(p1.getx ()), round (p1.gety ()),round(p2.getx ()),round(p2.gety ()));
    					//					return 2;
    				}
    			}
    		}
    	}
    
    	return ;
    }
    
    int lineClipLiangBrask(wcPt2D winMin, wcPt2D winMax, wcPt2D p1, wcPt2D p2, wcPt2D pOut[]){
    	GLfloat u1=0.0, u2=1.0, dx=p2.getx ()-p1.getx (),dy;
    	if(clipTest (-dx, p1.getx ()-winMin.getx (),&u1, &u2)){
    		if(clipTest (dx, winMax.getx ()-p1.getx (),&u1, &u2)){
    			dy=p2.gety ()-p1.gety ();
    			if(clipTest (-dy, p1.gety ()-winMin.gety (), &u1, &u2)){
    				if(clipTest (dy,winMax.gety ()-p1.gety (),&u1, &u2)){
    					if(u2<1.0){
    						p2.setCoords(p1.getx ()+u2*dx,p1.gety ()+u2*dy);
    					}
    					if(u1>0.0){
    						p1.setCoords(p1.getx ()+u1*dx, p1.gety ()+u1*dy);
    					}
    					pOut[0]=p1;
    					pOut[1]=p2;
    //					lineDDA (round(p1.getx ()), round (p1.gety ()),round(p2.getx ()),round(p2.gety ()));
    					return 2;
    				}
    			}
    		}
    	}
    
    	return 0;
    }
    
    void display(){
    	glClear (GL_COLOR_BUFFER_BIT);
    	//可视化边界:
    	const int minX=100, minY=100, maxX=300, maxY=300;
    	glColor3f(1.0,0.0,0.0);
    	lineDDA (minX,minY,minX,maxY);
    	lineDDA (minX,minY,maxX,minY);
    	lineDDA (maxX,maxY,minX,maxY);
    	lineDDA (maxX,maxY,maxX,minY);
    
    	glColor3f(0.0,1.0,0.0);
    	GLint n=5;
    	wcPt2D pIn[n];
    	pIn[0].setCoords (0,200);
    	pIn[1].setCoords (150,250);
    	pIn[2].setCoords (250,250);
    	pIn[3].setCoords (400,200);
    	pIn[4].setCoords (200,50);
    
    	for(int i=0;i<n;++i){
    		lineDDA (pIn[i].x,pIn[i].y,pIn[(i+1)%n].x,pIn[(i+1)%n].y);
    	}
    
    
    	wcPt2D pOut[20];
    	wcPt2D tempPOut[2];
    	int outCount=0;
    	int flag=0;
    	for(int i=0;i<n;++i){
    		flag=lineClipLiangBrask (wcPt2D(minX,minY), wcPt2D(maxX, maxY), pIn[i],pIn[(i+1)%n],tempPOut);
    		if(flag==2){
    			for(int j=0;j<2;++j){
    				pOut[outCount++]=tempPOut[j];
    			}
    		}
    	}
    
    	glColor3f(0.0,0.0,1.0);
    	int i=1;
    	for(;i<=outCount;++i){
    		lineDDA (pOut[i-1].x,pOut[i-1].y,pOut[i%outCount].x,pOut[i%outCount].y);
    	}
    
    	glFlush ();
    
    
    	return ;
    }
    

    效果:

    image-20201009120216266

    Sutherland-Hodgman多边形裁剪算法

    #define NDEBUG
    #ifndef GLUT_DISABLE_ATEXIT_HACK
    #define GLUT_DISABLE_ATEXIT_HACK
    #endif
    #include <windows.h>
    #include <gl/glut.h>
    #include <math.h>
    #include <stdio.h>
    
    const int windowWidge=600, windowHeight=600;
    
    
    void setPixel(GLint xCoord, GLint yCoord){
    	glBegin (GL_POINTS);
    	glVertex2i (xCoord, yCoord);
    	glEnd();
    }
    
    
    //-----------------------------------------
    
    void lineDDA (int x0, int y0, int xEnd, int yEnd){
    	int dx=xEnd-x0,dy=yEnd-y0,steps,k;
    	float xIncrement,yIncrement,x=x0,y=y0;
    	if(fabs(dx)> fabs(dy)){
    		steps = fabs(dx);
    	}else {
    		steps = fabs(dy);
    	}
    	xIncrement = float(dx)/float(steps);
    	yIncrement = float(dy)/ float(steps);
    	setPixel(round(x),round(y));
    	for(k = 0;k< steps;k++){
    		x += xIncrement;
    		y += yIncrement;
    		setPixel(round(x),round(y));
    	}
    	return ;
    }
    
    
    
    //---------------------------------------------
    //Sutherland-Hodgman多边形裁剪算法
    
    class wcPt2D {
    
    public:
    	GLfloat x,y;
    public:
    	/*
    Default Constructor:initalize position 48(0.0,0.0).*/
    	wcPt2D(){
    		x=y=0.0;
    	}
    
    	wcPt2D(GLfloat nx, GLfloat ny): x(nx), y(ny){}
    
    	wcPt2D(const wcPt2D& pCopy){
    		this->x=pCopy.x;
    		this->y=pCopy.y;
    	}
    
    	void setCoords(GLfloat xCoord,GLfloat yCoord){
    		x = xCoord;
    		y = yCoord;
    		return ;
    	}
    
    	wcPt2D& operator= (wcPt2D p2){
    		this->x=p2.getx ();
    		this->y=p2.gety ();
    		return *this;
    	}
    
    
    	GLfloat getx()const{
    		return x;
    	}
    	GLfloat gety ( ) const {
    		return y;
    	}
    };
    
    
    //枚举类的替代, C++中enum的操作与C有很大不同
    const int Left=0, Right=1, Bottom=2, Top=3;
    
    //typedef enum{
    //	Left, Right, Bottom, Top
    //} Boundary;
    
    using namespace std;
    
    const GLint nClip = 4;
    
    
    //判断点p是否在显示框内
    GLint inside(wcPt2D p, int b, wcPt2D wMin, wcPt2D wMax){
    	int flag=true;
    	switch(b){
    		case Left:{
    			if(p.getx ()<wMin.getx ()){
    				flag=false;
    			}
    			break;
    		}
    		case Right:{
    			if(p.getx ()>wMax.getx ()){
    				flag=false;
    			}
    			break;
    		}
    		case Bottom:{
    			if(p.gety ()<wMin.gety ()){
    				flag=false;
    			}
    			break;
    		}
    		case Top:{
    			if(p.gety ()>wMax.gety ()){
    				flag=false;
    			}
    			break;
    		}
    	}
    	return flag;
    }
    
    //判断向量(p1, p2)是否与边界相交
    GLint cross(wcPt2D p1, wcPt2D p2, int winEdge, wcPt2D wMin, wcPt2D wMax){
    	if(inside (p1,winEdge,wMin,wMax)==inside (p2, winEdge, wMin, wMax)){
    		return false;
    	}else{
    		return true;
    	}
    }
    
    //返回向量(p1, p2)与相应边界的交点
    wcPt2D intersect(wcPt2D p1, wcPt2D p2, int winEdge, wcPt2D wMin, wcPt2D wMax){
    	wcPt2D iPt;
    	GLfloat m;
    
    	if(p1.x!= p2.x){
    		m=(p1.gety ()-p2.gety ())/(p1.getx ()-p2.getx ());
    	}
    	switch (winEdge) {
    		case Left:{
    			iPt.x=wMin.x;
    			iPt.y=p2.y+(wMin.x-p2.x)*m;
    			break;
    		}
    		case Right:{
    			iPt.x=wMax.x;
    			iPt.y=p2.y+(wMax.x-p2.x)*m;
    			break;
    		}
    		case Bottom:{
    			iPt.y=wMin.y;
    			if(p1.x!=p2.x){
    				iPt.x=p2.x+(wMin.y-p2.y)/m;
    			}else{
    				iPt.x=p2.x;
    			}
    			break;
    		}
    		case Top:{
    			iPt.y=wMax.y;
    			if(p1.x!=p2.x){
    				iPt.x=p2.x+(wMax.y-p2.y)/m;
    			}else{
    				iPt.x=p2.x;
    			}
    			break;
    		}
    	}
    	return iPt;
    }
    
    void clipPoint(wcPt2D &p, int winEdge, wcPt2D wMin, wcPt2D wMax, wcPt2D * pOut,
    			   int *cnt, wcPt2D first[], wcPt2D *s){
    	wcPt2D iPt;
    
    	//判断first[winEdge]为nullPtr
    	if(first[winEdge].x==0 && first[winEdge].y==0){
    		first[winEdge]=p;
    	}else{
    		if(cross(p,s[winEdge], winEdge, wMin, wMax)){
    			iPt=intersect (p, s[winEdge], winEdge, wMin, wMax);
    			if(winEdge<Top){
    				clipPoint (iPt, winEdge+1, wMin, wMax, pOut, cnt, first, s);
    			}else{
    				//存交点
    				pOut[*cnt] =iPt;
    				(*cnt)++;
    			}
    		}
    	}
    	s[winEdge]=p;
    	if(inside (p,winEdge, wMin, wMax)){
    		if(winEdge<Top){
    			clipPoint (p, winEdge+1, wMin, wMax, pOut, cnt, first, s);
    		}else{
    			pOut[*cnt]=p;
    			(*cnt)++;
    		}
    	}
    }
    
    void closeClip(wcPt2D wMin, wcPt2D wMax, wcPt2D *pOut, GLint *cnt,
    			   wcPt2D first[],wcPt2D *s){
    	wcPt2D pt;
    	int winEdge;
    	for(winEdge=Left; winEdge<=Top;winEdge++){
    		if(cross(s[winEdge],first[winEdge],winEdge, wMin, wMax)){
    			pt=intersect (s[winEdge], first[winEdge], winEdge, wMin, wMax);
    			if(winEdge<Top){
    				clipPoint (pt, winEdge+1, wMin, wMax, pOut, cnt, first, s);
    			}else{
    				pOut[*cnt]=pt;
    				(*cnt)++;
    			}
    		}
    	}
    }
    
    GLint polygonClipSuthHodg(wcPt2D wMin, wcPt2D wMax, GLint n, wcPt2D *pIn, wcPt2D *pOut){
    	wcPt2D first[nClip] , s[nClip];
    	GLint k, cnt=0;
    	for(k=0;k<n;k++){
    		clipPoint (pIn[k],Left, wMin, wMax, pOut, &cnt, first, s);
    	}
    	closeClip (wMin, wMax, pOut, &cnt, first, s);
    	return cnt;
    }
    
    
    //---------------------------------------------
    
    
    //绘制程序
    void display(){
    
    	//Sutherland-Hodgman多边形裁剪算法
    	glClear (GL_COLOR_BUFFER_BIT);
    	//可视化边界:
    	const int minX=100, minY=100, maxX=300, maxY=300;
    	glColor3f(1.0,0.0,0.0);
    	lineDDA (minX,minY,minX,maxY);
    	lineDDA (minX,minY,maxX,minY);
    	lineDDA (maxX,maxY,minX,maxY);
    	lineDDA (maxX,maxY,maxX,minY);
    
    	//定义多边形的颜色和顶点
    	glColor3f(0.0,1.0,0.0);
    	GLint n=6;
    	wcPt2D pIn[n];
    	pIn[0].setCoords (50,200);
    	pIn[1].setCoords (150,250);
    	pIn[2].setCoords (250,250);
    	pIn[3].setCoords (350,200);
    	pIn[4].setCoords (250,50);
    	pIn[5].setCoords (150,50);
    	//绘制原始多边形
    	for(int i=0;i<n;++i){
    		lineDDA (pIn[i].x,pIn[i].y,pIn[(i+1)%n].x,pIn[(i+1)%n].y);
    	}
    
    	//获取裁剪后的点集
    	wcPt2D pOut[20];
    	int count=polygonClipSuthHodg (wcPt2D(minX,minY),wcPt2D(maxX,maxY),n,pIn,pOut);
    
    	//定义裁剪后的多边形颜色
    	glColor3f(0.0,0.0,1.0);
    	//绘制裁剪后的多边形
    	for(int i=1;i<=count;++i){
    		lineDDA (pOut[i-1].x,pOut[i-1].y,pOut[i%count].x,pOut[i%count].y);
    	}
    
    	glFlush ();
    
    
    	return ;
    }
    
    //初始化绘制
    void init(){
    	glClearColor(1.0,1.0,1.0,0.0);//清除颜色设置
    	glMatrixMode(GL_PROJECTION);//设置投影方式
    	gluOrtho2D (0.0,windowWidge*1.0,0.0,windowHeight*1.0);
    	return ;
    }
    
    int main(int argc, char** argv){
    	glutInit(&argc, argv);//初始化glut
    	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//设置显示模式为单缓冲,RGB模式
    	glutInitWindowPosition(0,0);//设置窗口位置
    	glutInitWindowSize(windowWidge,windowHeight);//设置窗口大小
    	glutCreateWindow("lineClipLiangBrask");//设置窗口标题
    	init();
    	glutDisplayFunc(display);
    	glutMainLoop();
    	return 0;
    }
    
    

    效果:

    image-20201009153730699

    展开全文
  • 逐次多边形裁剪算法算法的思想发窗口四条边界单一逐次对多边形进行裁剪,每次用窗口的一条边界(包括延长线)对要裁剪的多边形进行裁剪,裁剪时,顺序地测试多边形各顶点,保留边界内侧的顶点,删除外侧的顶点,同时,...
  • 窗口是固定的,如果需要随意给定的窗口,可以对代码稍作修改,用ButtonDown和ButtonUp实现
  • 基于VC++6.0中MFC的计算机图形学程序,实现了画点画线画多边形多边形裁剪填充消隐,二、三维图形变换(对称,镜像,拉伸,放大缩小,动画等等)
  • //定义两个临时数组,用于每次裁剪后新生成的多边形顶点 UINT m_nA, m_nB; int x, y; long tem1, tem2; int i; //原始多边形顶点个数 //原始多边形顶点数组的第一个顶点和最后一个顶点相同,因此实际顶点个数...
  • 计算机图形学图像裁剪。主要功能为利用Cohen-Sutherland端点编码算法编程实现任意线段的裁剪、利用Sutherland-Hodgman逐次多边形裁剪算法编程实现任意多边形裁剪~~~
  • 图形学直线生成、圆生成、直线裁剪、多边形裁剪。只提供两个类咯,具体实现靠大家~
  • 计算机图形学课设 橡皮筋,多边形裁剪 直接可用的TC源代码
  • 包含多种计算机图像的基本算法:DDA画线,Bresenhen算法,画圆,画多边形,Cohen-Sutherland裁剪算法,Liang-Barsky裁剪算法,扫描线填充算法,三次样条曲线,Bezier曲线,三次B样条曲线,二维图形变换(平移,...
  • 多边形裁剪 在实际问题中,我们往往需要处理的是用矩形裁剪一个多边形,找到多边形落在屏幕区域内的部分。如下图: 一般有两种算法来处理多边形裁剪问题:Sutherland-Hodgeman算法和Weiler-Atherton算法。 下面...
  • 裁剪裁剪裁剪裁剪

空空如也

空空如也

1 2 3 4 5 ... 14
收藏数 263
精华内容 105
关键字:

图形学多边形裁剪