精华内容
下载资源
问答
  • } } //裁剪算法 public static List Sutherland_Hodgeman(List points,List vectors){ List result = new ArrayList(); List cur = new ArrayList(); int vectorsSize = vectors.size(); int ...

    点的类,相信大家已经非常熟悉了

    package pow;

    /*点的类*/

    public class Point {

    public double x;

    public double y;

    public Point(double x,double y){

    this.x = x;

    this.y = y;

    }

    public Point(){

    this.x = 0;

    this.y = 0;

    }

    public void setX(double x){

    this.x = x;

    }

    public void setY(double y){

    this.y = y;

    }

    public double getX(){

    return this.x;

    }

    public double getY(){

    return this.y;

    }

    }

    向量的类(线)

    package pow;

    /*向量的类*/

    public class Vector {

    Point start;

    Point end;

    public Vector(Point start,Point end){

    this.start = start;

    this.end = end;

    }

    }

    算法主题,把数据写死了,大家可以把数据更改为输入:

    package pow;

    import java.util.ArrayList;

    import java.util.List;

    public class pow {

    public static void main(String[] arg){

    //初始化赋值过程

    List points = new ArrayList();

    Point point = new Point(0,0);

    points.add(point);

    point = new Point(7,2);

    points.add(point);

    point = new Point(5,9);

    points.add(point);

    point = new Point(3,8);

    points.add(point);

    point = new Point(0,1);

    points.add(point);

    List vectors = new ArrayList();

    vectors.add(new Vector(new Point(8,0), new Point(8,6)));

    vectors.add(new Vector(new Point(8,6), new Point(1,6)));

    vectors.add(new Vector(new Point(1,6), new Point(1,0)));

    vectors.add(new Vector(new Point(1,0), new Point(8,0)));

    //利用算法求出切割后的顶点集合,代表新的多边形

    List result = Sutherland_Hodgeman(points,vectors);

    //将所有的节点打印出来

    for(int k=0;k

    System.out.println(result.get(k).getX()+"|"+result.get(k).getY());

    }

    }

    //裁剪算法

    public static List Sutherland_Hodgeman(List points,List vectors){

    List result = new ArrayList();

    List cur = new ArrayList();

    int vectorsSize = vectors.size();

    int pointSize = points.size();

    Point S = points.get(pointSize-1);

    //初始化操作的集合

    for(int i=0;i

    result.add(points.get(i));

    }

    boolean flag;

    for(int j=0;j

    //flag = false表示在内侧,flag = true表示在外侧

    if(isInside(S,vectors.get(j)))

    flag = false;

    else

    flag = true;

    int resultSize = result.size();

    for(int i=0;i

    //证明其在当前vector的内

    if(isInside(result.get(i),vectors.get(j))){

    //如果前一个点在vector的外侧,那么将他们的交点加入到结果集中

    if(flag){

    flag = false;

    cur.add(Intersection(S, result.get(i), vectors.get(j).start, vectors.get(j).end));

    }

    //并将当前节点加入到结果集中

    cur.add(result.get(i));

    }

    else{

    //前一个点在外侧吗?

    if(!flag){

    flag = true;

    //如果前一个点在vector的内侧,那么将他们的交点加入到结果集中

    cur.add(Intersection(S, result.get(i), vectors.get(j).start, vectors.get(j).end));

    }

    }

    //更新首次比较的节点

    S = result.get(i);

    }

    //将本次结果拷贝出来,作为下次对比的样本,并将本次结果进行清空

    int resultLen = result.size();

    result.clear();

    for(int i=0;i

    result.add(cur.get(i));

    }

    cur.clear();

    }

    return result;

    }

    //求一个点是否在一条边的内侧,在点序为逆时针的时候(如果点在线上,也算在内侧)

    public static boolean isInside(Point p,Vector v){

    return Multi(p,v.start,v.end)>=0?true:false;

    }

    //求叉积p0->p1与p0->p2的叉积

    public static double Multi(Point p0,Point p1,Point p2){

    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);

    }

    public static Point Intersection(Point start0,Point end0,Point start1,Point end1){

    //由正弦定理推出

    double pX = (Multi(start0, end1, start1)*end0.x - Multi(end0, end1, start1)*start0.x)/

    (Multi(start0, end1, start1) - Multi(end0, end1, start1));

    double pY = (Multi(start0, end1, start1)*end0.y - Multi(end0, end1, start1)*start0.y)/

    (Multi(start0, end1, start1) - Multi(end0, end1, start1));

    return new Point(pX,pY);

    }

    }

    展开全文
  • 多边形裁剪算法.rar

    2019-06-17 11:02:57
    代码多边形裁剪算法,为光栅图形学算法续,此代码可以直接运行
  • 使用VS 2017实现多边形裁剪算法,此资源包括完整的项目文件,可以直接使用。此代码仅供学习交流使用。
  • openGL-多边形裁剪算法

    千次阅读 2018-03-24 14:58:04
    该部分代码不具备实际使用功能。 考虑使用4把刀分别裁剪一个图形。核心思想是,有一个点在扫描整个图形的边界。在扫描过程中,如果从刀的内侧(需要自己定义)到刀的外侧那么就记录当前点p0,当再次从外侧进入内...

    综述:

    这里只是简单记录了部分实现思想。该部分代码不具备实际使用功能。
    考虑使用4把刀分别裁剪一个图形。核心思想是,有一个点在扫描整个图形的边界。在扫描过程中,如果从刀的内侧(需要自己定义)到刀的外侧那么就记录当前点p0,当再次从外侧进入内测时,将当前点和记录的p0连起来。对于“覆盖遮挡”的边界可以利用
    (a^b)^b = a来实现“抹去还原”。

    #include <GLUT/GLUT.h>
    #include <iostream>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    float wid = 400;         //设置窗口的大小,约定窗口必须为正方形
    float height = wid;      //设置窗口的大小
    int numbers = 40;       //设置划分的网格的个数
    float t = wid/numbers; //模拟像素下的单位1
    int index_y;                 //记录下斜率为-1时的y的位置
    int con[801][801];         //相当于我们的画布(其中的信息是有层次的)
    int visited[801][801];
    int flag = 0;                //标定移动轨迹的位置
    int x_pos,y_pos,x_1=2*wid,y_1=2*wid;
    int pixel_size = 8;       //统一设定所有的的pixel的大小;
    /*
     参数设置说明:
     您应当确保参数范围在-400~400.且为整数。
     由于使用的是模拟像素,应保持数据为单位模拟像素值的倍数。
     */
    int x=0;
    int y=0;
    int a  = 300;
    int b  = 200;
    void draw_point(float x, float y,float x1,float y1);
    void add(int x, int y ,int data){
        con[x+400][y+400] = data ;
    }
    float translater(int x){
        /*
         函数说明:将像素坐标下的坐标转化为openGL坐标
         参数说明:传入点像素坐标-wid-wid,返回-1~1坐标
         */
        return  x/wid;
    }
    
    
    void draw_point(float x , float y){
        /*
         函数说明:绘制像素的点,这里将点的大小设置为7。
         颜色采用蓝色。利用圆八个部分的坐标对应关系进行绘图。
         加x1与y1是为了进行圆的平移
         参数说明:浮点数x,y是openGl坐标系。
         */
        glPointSize(pixel_size);
        glColor3f(1.0,0.0,0.0);
        glBegin(GL_POINTS);
        glVertex3f(x,y,0.0);
        glVertex3f(-x,y,0.0);              //关于y轴对称
        glVertex3f(x,-y,0.0);              //关于x轴对称
        glVertex3f(-x,-y,0.0);            //关于原点对称
        glEnd();
        glFlush();
    }
    bool out_of_index(int x,int y){
        if(y>=801||x>=801||x<0||y<0){
            return 0;
        }else{
            return 1;
        }
    }
    
    void draw_inner(int x, int y){
        glPointSize(pixel_size);
        glColor3f(0.0,1.0,1.0);
        glBegin(GL_POINTS);
        glVertex3f(translater(x-400),translater(y-400),0.0);
        glEnd();
        glFlush();
    }
    void draw_inner2(int x, int y){
        glPointSize(pixel_size);
        glColor3f(0.0,0.0,1.0);
        glBegin(GL_POINTS);
        glVertex3f(translater(x-400),translater(y-400),0.0);
        glEnd();
        glFlush();
    }
    void draw_line(int x,int y , int xx , int yy){
        for (int i = min(x,xx); i <= max(x,xx); i+=10) {
            for(int j  =min (y,yy);j<=max(y,yy);j+=10){
                if(con[i][j]!=1){
                    int res= con[i][j]^1111;
                if(res  == -1){
                    glPointSize(pixel_size);
                    glColor3f(1.0,0.0,0.0);
                    glBegin(GL_POINTS);
                    glVertex3f(translater(i-400),translater(j-400),0.0);
                    glEnd();
                    glFlush();
                }else{
                    draw_inner(i, j);
                }
                    if(con[i][j] ==0){
                        con[i][j] = 1;
                        visited[i][j] =1;
                    }else{
                        con[i][j] = res;
                    }
                }
            }
        }
    }
    void draw_line2(int x,int y , int xx , int yy){
        for (int i = min(x,xx); i <= max(x,xx); i+=10) {
            for(int j  =min (y,yy);j<=max(y,yy);j+=10){
                if(con[i][j]!=1){
                    int res= con[i][j]^1112;
                    if(res  == -1&&res== ((-1)^1111)){
                        glPointSize(pixel_size);
                        glColor3f(1.0,0.0,0.0);
                        glBegin(GL_POINTS);
                        glVertex3f(translater(i-400),translater(j-400),0.0);
                        glEnd();
                        glFlush();
                    }else{
                        draw_inner2(i, j);
                    }
                    con[i][j] = res;
                }
            }
        }
    }
    
    void search(int x,int y,int index){
        cout << index << " - - "<<endl;
        /*
         函数说明:进行Dfs搜索并模拟四把刀当中的其中一把刀
         可视化着色采用淡蓝色。
         参数说明:x y是坐标,index是指明哪一把刀。
         传入的xy是数组坐标!
         */
        if (visited[x][y] ==1) {
            return;
        }
        if(index == 1){
            //讨论下方的情况
            if(flag ==0){
                //如果本来在外侧
                if(y-400 >= -200){
                    //从外侧进入内侧
                    draw_inner(x, y);
                    y_1 = min(y_1,y);
                    x_1 = min(x_1,x);
                    flag =1;
                    x_pos= x;
                    y_pos = y;
                }else{
                    glPointSize(8);
                    glColor3f(0.5,0.5,0.5);
                    glBegin(GL_POINTS);
                    glVertex3f(translater(x-400),translater(y-400),0.0);
                    glEnd();
                    glFlush();
                    flag =0;
                    con[x][y] = 0;
                }
            }else if(flag==1){
                //如果本来在内侧进入了外侧
                if(y-400 <= -200){
                    draw_inner(x, y);
                    //从内侧进入外侧
                    draw_line(x_pos, y_pos, x, y);
                    x_pos = 0;
                    y_pos  =0;
                    flag =0;
                }else{
                    flag=1;
                    draw_inner(x, y);
                    y_1 = min(y_1,y);
                    x_1 = min(x_1,x);
                }
            }
            visited[x][y] = 1;
            if(out_of_index(x+10, y)&&con[x+10][y]==1&&visited[x+10][y]==0){
                search(x+10,y,index);
                visited[x+10][y] =1;
            }
            if(out_of_index(x,y+10)&&con[x][y+10]==1&&visited[x][y+10]==0){
                search(x,y+10,index);
                visited[x][y+10] =1;
            }
            if(out_of_index(x+10,y+10)&&con[x+10][y+10]==1&&visited[x+10][y+10]==0){
                search(x+10,y+10,index);
                visited[x+10][y+10] =1;
            }
            if(out_of_index(x+10,y-10)&&con[x+10][y-10]==1&&visited[x+10][y-10]==0){
                search(x+10,y-10,index);
                visited[x+10][y-10] =1;
            }
            if(out_of_index(x,y-10)&&con[x][y-10]==1&&visited[x][y-10]==0){
                search(x,y-10,index);
                visited[x][y-10] =1;
            }
            if(out_of_index(x-10,y)&&con[x-10][y]==1&&visited[x-10][y]==0){
                search(x-10,y,index);
                visited[x-10][y] =1;
            }
            if(out_of_index(x-10,y+10)&&con[x-10][y+10]==1&&visited[x-10][y+10]==0){
                search(x-10,y+10,index);
                visited[x-10][y+10] =1;
            }
            if(out_of_index(x-10,y-10)&&con[x-10][y-10]==1&&visited[x-10][y-10]==0){
                search(x-10,y-10,index);
                visited[x-10][y-10] =1;
            }
        }else if(index ==2){
            //讨论左侧的情况
            if(flag ==0){
                //如果本来在外侧
                if(x-400 >= -300){
                    draw_inner2(x, y);
                    //从外侧进入内侧
                    flag =1;
                    x_pos= x;
                    y_pos = y;
                }else{
                    glPointSize(8);
                    glColor3f(1.0,1.0,1.0);
                    glBegin(GL_POINTS);
                    glVertex3f(translater(x-400),translater(y-400),0.0);
                    glEnd();
                    glFlush();
                    flag =0;
                }
            }else if(flag==1){
                //如果本来在内侧进入了外侧
                if(x-400 <= -300){
                    draw_inner2(x, y);
                    //从内侧进入外侧
                    cout << "inner -> outer  "<< endl;
                    cout << x_pos <<" == "<< y_pos <<endl;
                    cout << x <<" === " <<  y <<endl;
                    draw_line2(x_pos, y_pos, x, y);
                    cout << con[x-10][y] <<"here !!  "<< endl;
                    x_pos = 0;
                    y_pos  =0;
                    flag =0;
                }else{
                    flag=1;
                    draw_inner2(x, y);
                }
            }
            visited[x][y] = 1;
            if(out_of_index(x+10, y)&&(con[x+10][y]==1||con[x+10][y]==(-1^1111))&&visited[x+10][y]==0){
                search(x+10,y,index);
                visited[x+10][y] =1;
            }
            if(out_of_index(x,y+10)&&(con[x][y+10]==1||con[x][y+10]==(-1^1111))&&visited[x][y+10]==0){
                search(x,y+10,index);
                visited[x][y+10] =1;
            }
            if(out_of_index(x+10,y+10)&&(con[x+10][y+10]==1||con[x+10][y+10]==(-1^1111))&&visited[x+10][y+10]==0){
                search(x+10,y+10,index);
                visited[x+10][y+10] =1;
            }
            if(out_of_index(x+10,y-10)&&(con[x+10][y-10]==1||con[x+10][y-10]==(-1^1111))&&visited[x+10][y-10]==0){
                search(x+10,y-10,index);
                visited[x+10][y-10] =1;
            }
            if(out_of_index(x,y-10)&&(con[x][y-10]==1||con[x][y-10]==(-1^1111))&&visited[x][y-10]==0){
                search(x,y-10,index);
                visited[x][y-10] =1;
            }
            if(out_of_index(x-10,y)&&(con[x-10][y]==1||con[x-10][y]==(-1^1111))&&visited[x-10][y]==0){
                search(x-10,y,index);
                visited[x-10][y] =1;
            }
            if(out_of_index(x-10,y+10)&&(con[x-10][y+10]==1||con[x-10][y+10]==(-1^1111))&&visited[x-10][y+10]==0){
                search(x-10,y+10,index);
                visited[x-10][y+10] =1;
            }
            if(out_of_index(x-10,y-10)&&(con[x-10][y-10]==1||con[x-10][y-10]==(-1^1111))&&visited[x-10][y-10]==0){
                search(x-10,y-10,index);
                visited[x-10][y-10] =1;
            }
        }
    
    }
    void cutter(int x, int y){
        /*
         函数说明:这里包含四把刀
         参数说明:传入我们的起始坐标
         */
        //首先判断点的位置:框内?框外?
        for (int i = 0; i <801; i++) {
            for (int j  =0; j < 801; j++) {
                visited[i][j] = 0;
            }
        }
        if(y < -200){
            //在下方
            flag =0;            //在下方外侧
            search(x+400,y+400,1);
    
        }
        if(x < -300){
            //在左侧!
            flag = 0;
            for (int i = 0; i <801; i++) {
                for (int j  =0; j < 801; j++) {
                    visited[i][j] = 0;
                }
            }
            glPointSize(pixel_size);
            glColor3f(0.9,0.89,0.1);
            glBegin(GL_POINTS);
            glVertex3f(translater(x_1-400),translater(y_1-400),0.0);
            glEnd();
            glFlush();
            cout << "xx "<< x_1 -400 <<"  " << y_1-400 <<endl;
            search(x_1,y_1,2);
        }
    
    
    }
    void p(float x , float y,float x1,float y1){
        /*
         函数说明:绘制像素的点,这里将点的大小设置为7。
         颜色采用蓝色。利用圆八个部分的坐标对应关系进行绘图。
         加x1与y1是为了进行圆的平移
         参数说明:浮点数x,y是openGl坐标系。
         */
        glPointSize(pixel_size);
        glColor3f(1.0,1.0,0.0);
        glBegin(GL_POINTS);
        glVertex3f(x+x1,y+y1,0.0);
        glEnd();
        glFlush();
    }
    void paint(int x ,int y ){
        add(x,y, 1);
        p(translater(x), translater(y), 0, 0);
    }
    void grid(){
        /*
         函数说明:绘制网格为了便于将真实的像素pixel转化为我们模拟的像素
         */
        glClearColor(0, 0, 0, 0);//这是设置背景色,必须要在glclear之前调用
        glClear(GL_COLOR_BUFFER_BIT);
        int hei_number = numbers;
        float delta_hei = height / hei_number;
        glColor3f(0.0,1.0,0);
        for (int i = 1; i < numbers *2; i ++ ) { //利用循环绘制网格
            glBegin(GL_LINES);
            glVertex2f(-1+i*delta_hei/height, -1);
            glVertex2f(-1+i*delta_hei/height, 1);
            glVertex2f(-1,-1+i*delta_hei/height);
            glVertex2f(1,-1+i*delta_hei/height);
            glEnd();
            glFlush();}
        glColor3f(1.0,0,0);
        glBegin(GL_LINES);          //绘制坐标系,便于观察
        glVertex2f(-1,0);
        glVertex2f(1,0);
        glVertex2f(0,-1);
        glVertex2f(0,1);
        glEnd();
        glFlush();
        //绘制我们的框图
        for (int i = 0; i <= 300; i+=t) {
            draw_point(translater( i),translater(200));
            add(i, 200, -1);
            add(-i, 200, -1);
            add(i, -200, -1);
            add(-i, -200, -1);
    
        }
        for (int i = 0; i <= 200; i+=t) {
            draw_point(translater(300),translater( i));
            add(300,i, -1);
            add(-300,i, -1);
            add(300,-i, -1);
            add(-300,-i, -1);
        }
        //绘制多边形
        int dm = -370;
        //设置偏移量
        for (int i = 140; i<=240; i+=10) {
            paint(i, i+dm);
        }
        for(int i  =240; i <=340 ; i+=10 ){
            paint(240, i+dm);
            //绘制横线
        }
        for(int i = 240;i>=-200;i-=10 ){
            paint(i, 340+dm);
        }
        for(int i  = -200;i>=-380;i-=10){
            paint(i, 540+i+dm);
        }
        for(int i  = -200;i>=-380;i-=10){
            paint(i, 540+i+dm);
        }
        for(int i = 160; i >= -20 ; i-=10){
            paint(-380, i+dm);
        }
        for (int i = 1;i <=30; i++) {
            paint(-380+i*10, -20+i*10+dm);
        }
        for (int i = 1;i <=14; i++) {
            paint(-80+i*10, 280-i*10+dm);
        }
        for(int i  =60; i <=140 ; i+=10 ){
            paint(i, 140+dm);
        }
        cutter(-380, -390);
        //刷新缓冲,保证绘图命令能被执行
    }
    
    
    
    int main(int argc, char *argv[]) {
        //初始化GLUT library
        glutInit(&argc, argv);
        //对窗口的大小进行初始化
        glutInitWindowSize(700,700);
        glutInitWindowPosition(300,200);
        // 设置窗口出现的位置
        //glutInitWindowPosition(int x, int y);
        glutInitDisplayMode(GLUT_RGBA);
        glutCreateWindow("hw_多边形裁剪");
        glutDisplayFunc(&grid);
        glutMainLoop();
        return 0;
    }
    
    展开全文
  • 梁友栋-Barskey裁剪算法 直接上代码吧: // ConsoleApplication2.cpp: 定义控制台应用程序的入口点。 // #include "stdafx.h" #include<gl/GLUT.H> #include<cmath> #include<iostream> #include...

    梁友栋-Barskey裁剪算法

    直接上代码吧:

    // ConsoleApplication2.cpp: 定义控制台应用程序的入口点。
    //
    #include "stdafx.h"
    #include<gl/GLUT.H>
    #include<cmath>
    #include<iostream>
    #include"node.h"
    using namespace std;
    void Initial(void)//初始化函数 
    {
    	glClearColor(1.0f, 1.0f, 1.0f, 1.0f);//白色背景,前3个是RGB,最后是Alpha值,用来控制透明,1.0表示完全不透明
    	glMatrixMode(GL_MODELVIEW);//OpenGL按照三维方式来处理图像,所以需要一个投影变换将三维图形投影到显示器的二维空间中
    	glLoadIdentity();
    	gluOrtho2D(0.0, 400, 0.0, 400.0);//指定使用正投影将一个x坐标在0~200,y坐标0~150范围内的矩形坐标区域投影到显示器窗口
    
    }
    bool ClipT(float p, float q, float *u1, float *u2)
    {
    	float r;
    	if (p < 0)
    	{
    		r = q / p;
    		
    		if (r > *u2)
    			return false;
    		if (r > *u1)
    			* u1 = r;
    	}
    	else if (p > 0)
    	{
    		r = q / p;
    		if (r < *u1)
    			return false;
    		if (r < *u2)
    			*u2 = r;
    	}
    	else
    		return (q >= 0);
    	return true;
    }
    void LB_LineClip(float x1, float y1, float x2, float y2, float XL, float XR, float YB, float YT)
    {
    	float dx, dy, u1, u2;
    	 u1 = 0, u2 = 1;
    	dx = x2 - x1;
    	dy = y2 - y1;
    	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//绘图颜色为黑色  
    	glClear(GL_COLOR_BUFFER_BIT);
    	glColor3f(1.0, 0.0, 0.0);
    	glViewport(0, 0, 400, 400);
    	glBegin(GL_LINES);
    	glVertex2f(x1, y1);
    	glVertex2f(x2, y2);
    	glEnd();
    	//glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//绘图颜色为黑色   
    	//glClear(GL_COLOR_BUFFER_BIT);
    	glColor3f(1.0, 1.0, 1.0);
    	glViewport(0, 0, 400, 400);
    	glBegin(GL_LINES);
    	glVertex2f(XL,YB);
    	glVertex2f(XL,YT);
    	glVertex2f(XL,YT);
    	glVertex2f(XR,YT);
    	glVertex2f(XR, YT);
    	glVertex2f(XR, YB);
    	glVertex2f(XL, YB);
    	glVertex2f(XR, YB);
    	if (ClipT(-dx, x1 - XL, &u1, &u2))
    		if (ClipT(dx, XR - x1, &u1, &u2))
    			if (ClipT(-dy, y1 - YB, &u1, &u2))
    				if (ClipT(dy, YT - y1, &u1, &u2))
    				{
    
    					glVertex2f(x1 + u1 * dx, y1 + u1 * dy);
    					glVertex2f(x1 + u2 * dx, y1 + u2 * dy);
    					
    
    				}
    	glEnd();
    	glFlush();
    }
    node* Sutherland(node *m1, node *m2, side ClipBoundary, int Inlength, int &Outlength)
    {
    	node S, P, ip;
    	int j;
    	Outlength = 0;
    	S = m1[Inlength - 1];
    	for (j = 0; j < Inlength; j++)
    	{
    		P = m1[j];
    		if (Inside(P, ClipBoundary))
    		{
    			if (Inside(S, ClipBoundary))
    				Output(P, Outlength, m2);
    			else
    			{
    				Intersect(S, P, ClipBoundary, ip);
    				Output(ip, Outlength, m2);
    				Output(P, Outlength, m2);
    			}
    		}
    		else if (Inside(S, ClipBoundary))
    		{
    			Intersect(S, P, ClipBoundary, ip);
    			Output(ip, Outlength, m2);
    		}
    		S = P;
    	}
    
    	return m2;
    }
    void drawFront(node m1[],node m2[],int length1,int length2)
    {
    	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//绘图颜色为黑色   
    	glClear(GL_COLOR_BUFFER_BIT);
    	glColor3f(1.0, 1.0, 0.0);
    	glViewport(0, 0, 400, 400);
    	glBegin(GL_LINES);
    	for (int i = 0; i < length1 - 1; i++)
    	{
    		glVertex2d(m1[i].x, m1[i].y);
    		glVertex2d(m1[i+1].x, m1[i+1].y);
    	}
    	glVertex2d(m1[length1-1].x, m1[length1-1].y);
    	glVertex2d(m1[0].x, m1[0].y);
    	glEnd();
    	glColor3f(0.0, 1.0, 0.0);
    	glBegin(GL_LINES);
    	for (int i = 0; i < length2 - 1; i++)
    	{
    		glVertex2d(m2[i].x, m2[i].y);
    		glVertex2d(m2[i + 1].x, m2[i + 1].y);
    	}
    	glVertex2d(m2[length2 - 1].x, m2[length2 - 1].y);
    	glVertex2d(m2[0].x, m2[0].y);
    
    	glEnd();
    	glFlush();
    }
    void drawBack()
    {
    	
    	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//绘图颜色为黑色   
    	glClear(GL_COLOR_BUFFER_BIT);
    	glColor3f(1.0, 1.0, 0.0);	
    	glViewport(0, 0, 400, 400);
    	glBegin(GL_LINES);
    	node *m1=new node[100],*m2=new node[100],*r1=new node[100],*r2=new node[100],*r3=new node[100],*r4=new node[100];
    	node n1(100, 100), n2(100, 200), n3(200, 200), n4(200, 100), n5(50, 150), n6(150, 220),n7(150,150);
        node ploy[3] = { n5,n6,n7};
    	side s1(n2, n1), s2(n1, n4), s3(n4, n3), s4(n3, n2);
    	m1 = &ploy[0];
    	int nodeNum = 0;
    	r1=Sutherland(m1,m2,s1,3,nodeNum);//用第一条边裁剪剩下的图形
    	m2 = new node();
    	r2 = Sutherland(r1, m2, s2, nodeNum, nodeNum);//用第二条边裁剪剩下的图形
    	m2 = new node();
    	r3 = Sutherland(r2, m2, s3, nodeNum, nodeNum); //用第三条边裁剪剩下的
    	m2 = new node();
    	r4 = Sutherland(r3, m2, s4, nodeNum, nodeNum);//最后一条边裁剪后剩下的
    	//r1 = r2 = r3 = m1=r4=NULL;
    	//delete r1, r2, r3, m1,r4;
    	for (int i = 0; i < nodeNum - 1; i++)//画出被裁减后的图形
    	{  
    		glVertex2d(m2[i].x, m2[i].y);
    		glVertex2d(m2[i + 1].x, m2[i + 1].y);
    	}
    	glVertex2d(m2[nodeNum - 1].x, m2[nodeNum - 1].y);
    	glVertex2d(m2[0].x, m2[0].y);
    	//glVertex2d(100, 200);
    	//glVertex2d(200, 300);
    	//cout << m2[0].x << " " << m2[0].y;
    	glEnd();
    	glFlush();
    	
    }
    node *nn = new node[100];
    int nodeNumber = 0;
    void draw()
    {
    	node n1(100, 100), n2(100, 200), n3(200, 200), n4(200, 100), n5(50, 150), n6(150, 220), n7(150, 150);
    	node ploy[3] = { n5,n6,n7 };
    	node ploy2[4] = { n1,n2,n3,n4 };
    	drawFront(ploy,ploy2,3,4);
    	
    	/*result=Bezier(nodeNumber,&nn[0]);
    	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//绘图颜色为黑色   
    	glClear(GL_COLOR_BUFFER_BIT);
    	glColor3f(1.0, 1.0, 0.0);
    	glViewport(0, 0, 400, 400);
    	 glBegin(GL_POINTS);
    	for (int i = 0; i < 100; i++)
    	{  
    		glVertex2f(result[i].x, result[i].y);
    		
    		//cout <<result[i].x<<" "<<result[i].y<<"\n";
    	}
    	//result = NULL;
    	//delete result;
    	glEnd();
    	glColor3f(0.0, 1.0, 1.0);
    	glViewport(0, 0, 400, 400);
    	glBegin(GL_LINES);
    	for (int i = 0; i < nodeNumber-1; i++)
    	{
    		glVertex2f(nn[i].x, nn[i].y);
    		glVertex2f(nn[i+1].x, nn[i+1].y);
    	}
    	glEnd();
    	glFlush();*/
    
    }
    //鼠标响应函数
    void mouseClick(int btn, int state, int x, int y)
    {
    	
    	if (btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
    	node temp(x, 400-y);
    	nn[nodeNumber] = temp;
    	nodeNumber++;
    	glColor3f(0.0, 1.0, 1.0);
    	glViewport(0, 0, 400, 400);
    	glBegin(GL_POINTS);
    	glVertex2d(x,400-y);
    	glEnd();
    	glFlush();
    	}
    	if (btn == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) 
    	{
    		node *result = new node[1000];
    		//drawFront(ploy,ploy2,3,4);
    
    		result = Bezier(nodeNumber, nn);
    		glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//绘图颜色为黑色   
    		//glClear(GL_COLOR_BUFFER_BIT);
    		glColor3f(1.0, 1.0, 0.0);
    		glViewport(0, 0, 400, 400);
    		glBegin(GL_POINTS);
    		for (int i = 0; i < 1000; i++)
    		{
    			glVertex2f(result[i].x, result[i].y);
    
    			//cout <<result[i].x<<" "<<result[i].y<<"\n";
    		}
    		//result = NULL;
    		//delete result;
    		glEnd();
    		glColor3f(0.0, 1.0, 1.0);
    		glViewport(0, 0, 400, 400);
    		glBegin(GL_LINES);
    		for (int i = 0; i < nodeNumber - 1; i++)
    		{
    			glVertex2f(nn[i].x, nn[i].y);
    			glVertex2f(nn[i + 1].x, nn[i + 1].y);
    		}
    		//result = NULL;
    		nn = NULL;
    		nn = new node[100];
    		nodeNumber = 0;
    		glEnd();
    		glFlush();
    		
    
    	}
    }
    //鼠标移动函数
    void display()
    {
    	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//绘图颜色为黑色   
        //glClear(GL_COLOR_BUFFER_BIT);
        glColor3f(1.0, 1.0, 0.0);
    	glViewport(0, 0, 400, 400);
    	LB_LineClip(50, 150, 200, 250, 100, 300, 20, 200);
    }
    int main(int argc, char * argv[])//这是使用glut库函数进行窗口管理
    {
    	glutInit(&argc, argv);//使用glut库需要进行初始化
    	glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);//设定窗口显示模式,颜色模型和缓存,这里是RGB颜色模型和单缓存
    	glutInitWindowPosition(100, 100);//设定窗口的初始位置,屏幕左上角为原点,单位为像素
    	glutInitWindowSize(400, 400);//设定窗口的大小
    
    	glutCreateWindow("裁剪线段图形");//创建一个窗口,参数是窗口标题名 
    	Initial();
    	glutDisplayFunc(&display);//将myDisplay指定为当前窗口的显示内容函数*/
    	
    	glutCreateWindow("初始图形");//创建一个窗口,参数是窗口标题名 
    	Initial();
    	glutDisplayFunc(&draw);//将myDisplay指定为当前窗口的显示内容函数*/
    
    	glutCreateWindow("裁剪后的图");//创建一个窗口,参数是窗口标题名 
    	Initial();
    	glutDisplayFunc(&drawBack);//将myDisplay指定为当前窗口的显示内容函数							 
    	glutMainLoop();//使窗口框架运行起来,使显示回调函数开始工作
    	return 0;
    }
    
    
    加个有关函数的头文件:
    #pragma once
    #pragma once
    struct node//点结构 
    {
    	double x;
    	double y;
    	node()
    	{
    		x = 0.0;
    		y = 0.0;
    	}
    	node(double xx, double yy)
    	{
    		x = xx;
    		y = yy;
    	}
    	/*node & operator=(const node& a)
       {
    		node m;
    		m.x = a.x;
    		m.y = a.y;
    		return m;
        }*/
    };
    
    struct side//边结构
    {
    	node a;
    	node b;
    	side(node aa, node bb)
    	{
    		a.x = aa.x;
    		a.y = aa.y;
    		b.y = bb.y;
    		b.x = bb.x;
    	}
    	side(int n)
    	{
    		a.x = 0;
    		a.y = 0;
    		b.x = 0;
    		b.y = 0;
    	}
    	side()
    	{
    		a.x = 0;
    		a.y = 0;
    		b.x = 0;
    		b.y = 0;
    	}
    };
    
    double sideYmax(side mside)
    {
    	if (mside.a.y < mside.b.y)
    		return mside.b.y;
    	else
    		return mside.a.y;
    }
    bool Inside(node &TestPt, side ClipBoundray)
    {
    	if (ClipBoundray.b.x > ClipBoundray.a.x)//裁剪边为窗口下边
    	{
    		if (TestPt.y >= ClipBoundray.a.y)
    			return TRUE;
    	}
    	else if (ClipBoundray.b.x < ClipBoundray.a.x)//裁剪边为窗口下边
    	{
    		if (TestPt.y <= ClipBoundray.a.y)
    			return TRUE;
    	}
    	else if (ClipBoundray.b.y > ClipBoundray.a.y)
    		{
    			if (TestPt.x <= ClipBoundray.a.x)
    				return TRUE;
    		}
    	else if (ClipBoundray.b.y < ClipBoundray.a.y)
    		{
    			if (TestPt.x >= ClipBoundray.a.x)
    				return TRUE;
    		}
    		return FALSE;
    }
    void Intersect(node &S,node &P,side ClipBoundary,node &IntersectPt)//求两条边的交点
    {
    	if (ClipBoundary.a.y == ClipBoundary.b.y)
    	{
    		IntersectPt.y = ClipBoundary.a.y;
    		IntersectPt.x = S.x + (ClipBoundary.a.y - S.y)*(P.x - S.x) / (P.y - S.y);
    	}
    	else
    	{
    		IntersectPt.x = ClipBoundary.a.x;
    		IntersectPt.y = S.y + (ClipBoundary.a.x - S.x)*(P.y - S.y) / (P.x - S.x);
    	}
    }
    void  Output(node P, int &Outlength, node *m2)
    {
    	m2[Outlength] = P;
    	Outlength++;
    }
    node *Bnode(float t, int nodeNumber,node *n)//求出点集第几次后的在t分段上的点
    {
    
    	node *temp=new node[nodeNumber-1];
    	for (int i = 0; i < nodeNumber-1; i++)
    	{
    		temp[i].x = (1 - t)*n[i].x + t * n[i + 1].x;
    		temp[i].y = (1 - t)*n[i].y + t * n[i + 1].y;
    	}
    	if (nodeNumber == 2)
    		return temp;
    	else
    		return Bnode(t,nodeNumber-1,temp);
    }
    node * Bezier(int nodeNumber,node * n)
    {
    	float t = 0.0; int i = 0;
    	node *result = new node[1000];
    	for (t; t < 1; t = t + 0.001)
    	{
    		result[i].x = Bnode(t, nodeNumber, n)[0].x;
    		result[i].y = Bnode(t, nodeNumber, n)[0].y;
    		//result[i] = Bnode(t, nodeNumber, n)[0];
    		i++;
    		//cout << result[i].x << " " << result[i].y<<"\n";
    	}
    	return result;
    }
    
    显示效果

    图形学裁剪

    展开全文
  • 算法能使用任意多边形对一条直线段进行裁剪。类GLdoublePoint: 公有—GLdouble x ,y;类line: 公有—GLdoublePoint first,second;linelist: line型数据组成的链表,用于描述多边形;伪代码:int CyrusBeck...

    此算法能使用任意多边形对一条直线段进行裁剪。

    类GLdoublePoint: 公有—GLdouble x ,y;

    类line:                 公有—GLdoublePoint first,second;

    linelist:                 line型数据组成的链表,用于描述多边形;

    伪代码:

    int  CyrusBeck(line&  seg , linelist&  l)

    {

    double  numer , denom ;

    double  tIn = 0.0 , tOut = 1.0;

    Vector  c , temp;

    c = seg.second - seg.first;

    for(int  i = 0 ; i < l.num ; i++)

    {

    temp = l.line[i].pt - first ;  // pt为此时多边形某边上的任意一点

    numer = dot(l.line[i].norn , temp);

    denom = dot(l.line[i].norn , c);  // dot()函数为求两向量的点积,自行编写

    if(!chopCI(numer , denom , tIn , tOut))  return  0 ; // chopCI()是用来计算射线与多边型每条边相交 的时间,并判断射线在交点处是射入还是射出,伪代码在后面

    }

    if(tOUt < 1.0)                                                                   //进行裁剪

    {

    seg.second.x = seg.first.x + c.x * tOut ;

    seg.second.y = seg.first.y + c.y * tOut ;

    }

    if(tIn > 0.0)

    {

    seg.first.x = seg.first.x + c.x * tIn ;

    seg.first.y = seg.first.y + c.y * tIn ;

    }

    return 1;

    }

    int  chopCI(double  numer , double  denom ,double  tIn ,double  tOut)

    {

    double  tHit;

    if(denom < 0)                                                              //射线射入

    {

    tHit = numer / denom ;

    if (tHit > tOut) return 0;

    else  if(tHit > tIn)   tIn = tHit ;

    }

    else if(denom > 0)                                                       // 射线射出

    {

    tHit = numer / denom ;

    if(tHit < hIn) return 0;

    else  if(tHIt > tIn) tOut = tHIt ;

    }

    else                                                                            //射线与边平行

    if(numer <= 0 )  return 0;

    return 1;

    }

    说明:

    设某射线起始点为A,单位向量为c;某直线l,其上任意一点B,法向量n;先判断A和B的关系。

    假设A与B相交,则焦点A+t*c与B形成的向量与n垂直,则有:

    n ●(A+c*t — B)= 0 (1)

    此处可以将参数t看为是时间,则t为射线击中l的时间,记为tHit。

    (1)式经变换可得:tHit = n ●(B—A)/ (n ● c)

    由向量点积的性质可得:若n ● c>0 ,则射线沿法线方向

    若n ● c<0 ,则射线与法线相反

    若n ● c=0 ,则法线与射线平行

    代码中的tIn和tOut可以理解为候选区间,也就是射线现存的部分,剪裁时就是根据射线是射入还是射出以及tHIt和tIn与tOut的关系来修改tOut和tIn,避免了频繁进行改变点的运算,因为计算机图形学中点与向量的定义很相似,容易出错。

    Cyrus-Beck裁剪算法就是依据以上方法用多边形的每条边对seg进行判断,并把剪裁后的线段返回到seg中,思路简单但是运算量较大,也不实用来计算边数多的多边形,同时此算法也只适用于凸多边形。

    展开全文
  • 多边形裁剪

    2015-06-04 15:34:15
    多边形裁剪算法代码,以可视化建立面图层、线图层,进行多边形裁剪
  • Sutherland-Hodgman算法进行多边形裁剪

    热门讨论 2010-06-24 21:07:39
    用Sutherland-Hodgman算法进行多边形裁剪 鼠标画多边形,然后裁剪...算法有点问题,有时正确,有时错误.... 但其中技巧望大家认真看代码
  • 基本思想是一次用窗口的一条边裁剪多边形。 考虑窗口的一条边以及延长线构成的裁剪线,该线把平面分成两个部分:可见一侧;不可见一侧。 多边形的各条边的两端点S、P。它们与裁剪线的位置关系只有四种, 如图: ...
  • 算法原理比较简单,用裁剪区域的四条边分别去分割多边形。 假设边p1,p2,用区域某条边进行裁剪。方向为p1-&amp;amp;amp;gt;p2 1.p1在边外,p2在边外 无操作 2.p1外,p2内 保存交点p和p2 3.p1内,p2内 ...
  • 本资源包含了Cohen-Sutherland算法、Liang-Barsky算法实现直线段裁剪以及自创的多边形裁剪(老师都没查出BUG)的cpp源代码和实验报告。重点是多边形裁剪,400多行代码,最终实现了任意多边形裁剪,下载即可运行
  • #include "stdafx.h"#include"math.h"// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的// ATL 项目中进行定义,并允许与该项目共享文档代码。#ifndef SHARED_HANDLERS#include "计算机图形学.h"#endif ...
  • 图形学多边形裁剪,在屏幕客户区绘制多边形(可以用鼠标绘制或直接给定坐标),用代码绘制“裁剪窗口”(也可以使用鼠标绘制裁减窗口)按下“鼠标右键”按钮,利用sutherland-Hodgman算法多边形进行裁剪,用不同...
  • 代码 /*INTRODUCTION // Mouse: // - LEFT button: // 1. add point to draw the polygon // - RIGHT button: // clip the polygon // Keyboard: // - SPACE: // clear the window */ #include <GLFW/glfw3.h&...
  • 在一个重写的View,主要绘制在View的OnDraw()方法中, 首先:先绘制出几个点,当然是任意多 ...当然裁剪的功能没有实现 代码如下 View--------: --*************************************************************
  • 本实现主要参考了发表于2003年《软件学报》的《一个有效的多边形裁剪算法》(刘勇奎,高云,黄有群)这篇论文,所使用的理论与算法大都基于本文,对论文中部分阐述进行了详细解释,并提取了论文中一些重要的理论加以汇总...
  • 编码裁剪算法

    2019-09-30 20:43:49
    由于任何线段相对于凸多边形窗口进行裁剪后,落于窗口内的线段不会多于一条,因此,对线段的裁剪,只要求出其保留部分的两个端点即可。 任意平面线段和矩形窗口的位置关系只会有以下... 1 /* 编码裁剪算法 */ 2 i...
  • 在一个重写的View,主要绘制在View的OnDraw()方法中, 首先:先绘制出几个点,当然...当然裁剪的功能没有实现 代码如下: public class MyView extends View{ public int doWhat = 0; ArrayList> list = new Arra
  • 实验四 编码裁剪算法

    2018-01-11 15:53:00
    1.了解二维图形裁剪的原理(点的裁剪、直线的裁剪、多边形的裁剪),利用VC+OpenGL实现直线的裁剪算法。 二、实验内容及主要步骤代码 (1) 理解直线裁剪的原理(Cohen-Surtherland算法、梁友栋算法) (2) ...
  • (1)算法设计原理 (2)程序关键代码 void S_L_Line(int inlen,POINT inpoints[],int &outlen,POINT outpoints[],POINT point0,POINT point1) { outlen=0; POINT P2,P1,I; int j; P2=inpoints[inlen-1]; /...
  • Cyrus-Beck图像裁剪算法归纳

    千次阅读 2010-10-11 00:38:00
    算法能使用任意多边形对一条直线段进行裁剪。 类GLdoublePoint: 公有—GLdouble x ,y;类line: 公有—GLdoublePoint first,second;linelist: line型数据组成的链表,用于描述多边形; 伪代码:int ...
  • 裁剪直线段和多边形

    2011-12-11 17:00:17
    很好的代码裁剪直线段和多边形,Cohen-Sutherland算法、中点分割算法、梁友栋-Barsky算法,并且利用Sutherland-Hodgman算法实现对多边形裁剪
  • 北京工业大学计算机图形学实验代码,里面包含两个实验,实验一,多边形扫描算法,实验二,多边形裁剪算法
  • 计算机图形学实习代码,在MFC中实现包括DDA直线,中点直线,Bresenham 圆,正负法圆,Bezier 曲线,多边形及字符的绘制等算法。 以及图像平移旋转缩放对称变换算法,扫描线填充算法,种子填充,边缘填充,二维裁剪...
  • 计算机图形学的五个实验报告包括:直线的扫描生成算法,圆和椭圆的扫描生成算法,多边形区域填充算法,多边形裁剪算法

空空如也

空空如也

1 2 3
收藏数 52
精华内容 20
关键字:

多边形裁剪算法代码