该算法比Cohen-Sutherland算法复杂不少, 它允许对非矩形窗口进行线剪裁。它还消除了Cohen-Sutherland算法中所需的重复计算

如下图所示:

如果线段部分位于凸多边形中或者完全在凸边形中,那么必定:
0 <= tE <= tL <= 1
如果线段位于凸边形外部,那么:
tL < tE

demo如下所示:

实现逻辑如下所示:
1.计算每条边的法线。
2.计算剪裁线的向量。
3.计算每个边顶点与剪切线的向量与边的法线之间的点积(对于所有边)。
4.计算剪裁线向量与所有边缘的法线之间的点积,为正则为入点、否则为出点
5.从每组中选择一个't'值,并将其放入线的参数形式中以计算坐标。

代码如下所示:

#include "widget.h"
#include <QPainter>
#include <QPushButton>
#include <QDebug>// 点乘
int dot(QPoint p0, QPoint p1)
{return p0.rx() * p1.rx() + p0.ry() * p1.ry();
}float max(QVector<float> t)
{float maximum = INT_MIN;for (int i = 0; i < t.size(); i++)if (t[i] > maximum)maximum = t[i];return maximum;
}float min(QVector<float> t)
{float minimum = INT_MAX;for (int i = 0; i < t.size(); i++)if (t[i] < minimum)minimum = t[i];return minimum;
}// Cyrus Beck函数
bool CyrusBeck(const QVector<QPoint>& vertices,const QLine& lineSrc, QLine& outLine)
{int n = vertices.length();QVector<QPoint> normal(n);QPoint line[2] = {lineSrc.p1(), lineSrc.p2()};// 1.计算每条边的法线for (int i = 0; i < n; i++) {normal[i].ry() = vertices[(i + 1) % n].x() - vertices[i].x();normal[i].rx() = vertices[i].y() - vertices[(i + 1) % n].y();}// 2 计算剪裁线(P0->P1)的向量QPoint P0_P1 = QPoint(line[1].rx() - line[0].rx(), line[1].ry() - line[0].ry());QVector<QPoint> P0_PEi(n);// 计算所有边的P0 -> PEi的向量值(计算每个边顶点与剪切线的向量)for (int i = 0; i < n; i++) {P0_PEi[i].rx() = vertices[i].x() - line[0].rx();P0_PEi[i].ry() = vertices[i].y() - line[0].ry();}int  numerator[n], denominator[n];//计算分子和分母//使用点乘函数for (int i = 0; i < n; i++) {numerator[i] = dot(normal[i], P0_PEi[i]);denominator[i] = dot(normal[i], P0_P1);}float t[n];QVector<float> tE, tL;for (int i = 0; i < n; i++) {t[i] = (float)(numerator[i]) / (float)(denominator[i]);if (denominator[i] > 0)tE.push_back(t[i]);elsetL.push_back(t[i]);}// 初始化't'的最后两个值tE tLfloat temp[2];// 取所有TE和0的最大值,最大值为0tE.push_back(0.f);temp[0] = max(tE);// 取所有Tl和1的最小值,最小值为1tL.push_back(1.f);temp[1] = min(tL);// 进入的t值如果>退出的t值,则说明在凸多边形外if (temp[0] > temp[1]) {return false;}// 计算获取到的坐标outLine.setP1(QPoint((float)line[0].rx()  + (float)P0_P1.rx() * (float)temp[0],(float)line[0].ry() + (float)P0_P1.ry() * (float)temp[0]));outLine.setP2(QPoint((float)line[0].rx() + (float)P0_P1.rx() * (float)temp[1],(float)line[0].ry() + (float)P0_P1.ry() * (float)temp[1]));qDebug()<<"计算获取到的坐标" << outLine;return true;
}QVector<QPoint> vertices= { QPoint(290, 50),QPoint(150, 100),QPoint(290, 150),QPoint(100, 150),QPoint(50, 100),QPoint(100, 50) };QLine line = QLine(QPoint(10, 10), QPoint(450, 200));//QVector<QPoint> vertices
//    = { QPoint(290, 50),
//        QPoint(150, 100),
//        QPoint(290, 150),
//        QPoint(100, 150),
//        QPoint(50, 100),
//        QPoint(100, 50) };//QLine line = QLine(QPoint(140, 24), QPoint(340, 220));QLine lineChanged;
bool trigger = false;Widget::Widget(QWidget *parent): QWidget(parent)
{QPushButton* btn = new QPushButton(this);btn->setText("剪切/还原");btn->move(300,10);this->resize(400,300);connect(btn, &QPushButton::clicked, this, [&]{trigger = !trigger;update();});CyrusBeck(vertices, line, lineChanged);}Widget::~Widget()
{}void Widget::paintEvent(QPaintEvent *)
{QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing, true);painter.setPen(Qt::blue);painter.drawPolygon(QPolygonF(vertices));if (trigger) {painter.drawLine(lineChanged);}else {painter.drawLine(line);}}

2.qt-Cyrus-Beck算法(凸多边形的线裁剪算法-C++实现)相关推荐

  1. java实现裁剪算法代码_Cyrus-Beck图像裁剪算法归纳

    此算法能使用任意多边形对一条直线段进行裁剪. 类GLdoublePoint: 公有-GLdouble x ,y: 类line:                 公有-GLdoublePoint fir ...

  2. 光栅图形学算法基础其二 (裁剪算法)

    光栅图形学算法的研究内容      直线段的扫描转换算法 多边形的扫描转换与区域填充算法 直线裁剪算法 反走样算法 消隐算法 一.裁剪简述         使用计算机处理图形信息时,计算机内部存储的图 ...

  3. java实现线段裁剪算法,多边形裁剪算法java

    Weiler-Atherton 任意多边形裁剪 Sutherland-Hodgeman 算法解决了裁剪窗口为凸多边形窗口的问题,但一些应用需要涉及 任意多边形窗口(含凹多边形窗口)的裁剪.Weiler ...

  4. 实验二 实现中点分割直线段裁剪算法

    一.目的 1. 了解直线裁剪的基本原理和常用方法. 2. 掌握中点分割直线段裁剪算法的基本原理和步骤. 3. 使用C++.OpenGL编程实现如下内容:输入直线段的起始点和终止点坐标位置.用四边形模拟 ...

  5. 梁友栋-Barsky裁剪算法原理分析

    梁友栋-Barsky算法是一种参数线裁剪算法. 为两个参数方程,为两点的差值,其中的由来是整理参数方程中三角函数的值得出,因为取值需要在裁剪框内,所以u只需要取0~1范围内的就足够. 是结合四条边界线 ...

  6. 《计算机图形学》实验报告 Cohen Sutherland裁剪算法

    一.实验目的和要求 熟悉光栅图形学中的相关直线段裁剪算法.理解Cohen-Sutherland裁剪算法. 二.实验内容 实现Cohen-Sutherland编码线段裁剪算法,能看到裁剪前后的屏幕显示效 ...

  7. 中点分割裁剪算法 c语言,裁剪算法——中点分割算法/Liang-Barsky算法

    三.中点分割法 首先对直线段的端点进行编码. [核心思想:通过二分逼近来确定直线段与窗口的交点.] 具体方法: 1.若中点不在窗口内,则把[中点]和离窗口边界[最远点]构成的线段丢掉,以线段上的另一点 ...

  8. 多边形的单边裁剪算法-JS

    裁剪算法 多边形的单边裁剪算法 多边形的单边裁剪算法 之前我们讲到直线段的代码裁剪算法,现在来讲讲多边形的单边裁剪算法,其实两者在数学上区别不是很大,只不过多边形的边是首尾相连的,闭合的,其实多边形的 ...

  9. 计算机图形剪裁程序说明,计算机图形学实验报告实验2裁剪算法实验

    裁剪算法实验 一. 实验目的: 直线段的裁剪:编码裁剪算法,中点分割裁剪算法. 二.实验内容: //BasicGraph.cpp //请将下列裁剪程序补充完整,并用注释说明是何种裁剪算法 void E ...

最新文章

  1. Asp.net支持的最大上传文件大小
  2. 高考与机器学习训练测试
  3. PCA与LDA算法的解释,浅显易懂
  4. mysql怎么模糊查询名字_mysql中模糊查询的四种用法:
  5. cf 786 B 线段树优化建图
  6. YTU 2924: 文件操作--二进制文件读入
  7. python美化输出模块_美化输出结果之Python模块PrettyTable介绍
  8. OpenShift 4 之AMQ Streams(1) - 多个Consumer从Partition接收数据
  9. REHL 5.4 下编译安装LNMP(上)
  10. Atitit 大数据体系树 艾提拉著 数据采集 gui自动化 爬虫 Nui自动化  Ocr技术 Tts语音处理 文档处理(office zip等) html文档处理解析 转换与处理
  11. matlab K近邻均值平滑滤波,K近邻均值滤波
  12. 鸿合一体机触屏没反应怎么办_一体机屏幕触摸不准的原因以及解决方法
  13. 数据挖掘:数据清洗——缺失值处理
  14. 业余草尚硅谷Java视频教程_SpringBoot视频教程免费下载
  15. 计算机思维是运用计算机科学的什么,计算思维是运用计算机科学的基础概念进行问题求解、系统设计以及人类行为理解等涵盖计算机科学之广度的一系列计算机的思维活动。...
  16. java变量不声明可以直接使用吗_Java基础_变量的声明与使用
  17. mysqlError: Can't connect to MySQL server on 'localhost' (10061)
  18. 算法与数据结构(邓俊辉)第一章
  19. 计算机设备预计净残值,电子设备折旧年限及残值率
  20. 【头歌】顺序表的基本操作

热门文章

  1. Jenkins任务分组
  2. 全网最全的免费献爱心方式,每天几分钟让世界变得更美好!
  3. nodeType(节点类型) 属性值说明
  4. Java泛型真的是鸡肋吗?
  5. 题目 2091: 求存款
  6. Haroopad使用
  7. 远程桌面无法复制粘贴的解决方法汇总
  8. nacos cp集群架构解析
  9. linux系统上安装ntp服务,linux时间同步ntp服务的安装与配置
  10. Java微服务——SpringCloud实战篇2:整合Gateway、Config、Bus