找回密码
 立即注册
查看: 140|回复: 0

Cohen-Sutherland 算法(编码算法)——计算机图形学笔记 ...

[复制链接]
发表于 2022-12-16 14:02 | 显示全部楼层 |阅读模式
思路

将每条直线段分三种情况处理:

  • 完全可见
  • 不完全可见
  • 完全不可见




具体流程

1.求出两端点的编码值
2.进行“与”、“或”运算

  • 若“或”运算后为0,则说明该线段完全可见,取该线段
  • 若“与”运算后不为0,则说明该线段完全不为0,弃该线段
  • 若上述两条件均不成立,则说明该线段不完全可见,按左右下上的顺序用窗各边界裁剪直线段,求出直线段与窗口边界的交点,将完全在窗口外的线段删除
代码
1.初始化
struct point
{
        float x;
        float y;
        float z = 0;
        float ratio;
        struct message color;
};

double x_left,x_right,y_top,y_bottom;//定义窗口左右上下边界
2.求编码代码
unsigned int enCode(double x, double y)
{
//用1 2 4 8 编码裁剪框的左、右、下、上区域
    unsigned int code = 0;
    if (x < x_left)
    {
         code = code | 1;
     }
     else if (x > x_right)
     {
         code = code | 2;
     }
     if (y < y_bottom)
     {
         code = code | 4;
      }
      else if (y > y_top)
     {
         code = code | 8;
      }
      return code;
}3.裁剪
void cilpping(point point1,point point2)
{
    point p1 = point1;//用p1、p2储存直线两个端点
    point p2 = point2;
    float x; //储存变化后的x,y坐标
    float y;
    int code1 = enCode(p1.x, p1.y); //code1、code2记录顶点的编码
    int code2 = enCode(p2.x, p2.y);
    int code = 0;

    while (code1 != 0 || code2 != 0) //两直线至少有一点在区域外
    {
        if ((code1 & code2) != 0)//线段完全不可见,跳出循环
        {
            return;
        }

        //将在区域外的点编码给code
        code = code1;
        if (code1 == 0) \\端点p1在窗口内
            code = code2;

        if ((1 & code) != 0) //直线段与左边界相交
        {
            x = x_left;
            y = p1.y + (p2.y - p1.y) / (p2.x - p1.x)* (x_left - p1.x);
        }
        else if ((2 & code) != 0) //直线段与右边界相交
        {
            x = x_right;
            y = p1.y + (p2.y -p1.y)/ (p2.x - p1.x) * (x_right - p1.x);
        }
        else if ((4 & code) != 0) //直线段与下边界相交
        {
            y = y_bootom;
            x = p1.x + (p2.x - p1.x)/ (p2.x - p1.x) * (y_bottom - p1.y) ;
        }
        else if ((8 & code) != 0) //直线段与上边界相交
       {
            y = y_top;
            x = p1.x + (p2.x - p1.x)/ (p2.x - p1.x) * (y_top - p1.y);
        }
        //将求出的点重新赋值
        if (code == code1)
        {
             point1.x = x;
             point1.y = y;
             code1 = enCode(x, y);
        }
        else
        {
            point2.x = x;
            point2.y = y;
            code2 = enCode(x, y);
        }
    }
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-24 15:25 , Processed in 0.089442 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表