梁友栋算法用多边形裁剪线段

// 计算机图形学View.cpp : C计算机图形学View 类的实现
//

#include "stdafx.h"
#include"math.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义,并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "计算机图形学.h"
#endif

#include "计算机图形学Doc.h"
#include "计算机图形学View.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// C计算机图形学View

IMPLEMENT_DYNCREATE(C计算机图形学View, CView)

BEGIN_MESSAGE_MAP(C计算机图形学View, CView)
// 标准打印命令
ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)
ON_COMMAND(ID_32773, &C计算机图形学View::liang)
END_MESSAGE_MAP()

// C计算机图形学View 构造/析构

C计算机图形学View::C计算机图形学View()
{
// TODO: 在此处添加构造代码

}

C计算机图形学View::~C计算机图形学View()
{
}

BOOL C计算机图形学View::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: 在此处通过修改
// CREATESTRUCT cs 来修改窗口类或样式

return CView::PreCreateWindow(cs);
}

// C计算机图形学View 绘制

void C计算机图形学View::OnDraw(CDC* /*pDC*/)
{
C计算机图形学Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;

CDC* pDC=GetDC();
pDC->Rectangle(10,20,90,80);
int x1=20,y1=10,x2=80,y2=90;
pDC->MoveTo(x1,y1);
pDC->LineTo(x2,y2);
}

// C计算机图形学View 打印

BOOL C计算机图形学View::OnPreparePrinting(CPrintInfo* pInfo)
{
// 默认准备
return DoPreparePrinting(pInfo);
}

void C计算机图形学View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: 添加额外的打印前进行的初始化过程
}

void C计算机图形学View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: 添加打印后进行的清理过程
}

// C计算机图形学View 诊断

#ifdef _DEBUG
void C计算机图形学View::AssertValid() const
{
CView::AssertValid();
}

void C计算机图形学View::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}

C计算机图形学Doc* C计算机图形学View::GetDocument() const // 非调试版本是内联的
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(C计算机图形学Doc)));
return (C计算机图形学Doc*)m_pDocument;
}
#endif //_DEBUG

// C计算机图形学View 消息处理程序

void C计算机图形学View::liang()
{
int x1,x2,y1,y2,xl,xr,yb,yt;
xl=10,xr=90,yb=20,yt=80;
x1=20,y1=10,x2=80,y2=90;
int dx=x2-x1,dy=y2-y1;
int p1=-dx,p2=dx,p3=-dy,p4=dy;
int q1=x1-xl,q2=xr-x1,q3=y1-yb,q4=yt-y1;
float u1,u2,u3,u4;
float umax,umin;
int x11,y11,x22,y22;

if(dx==0)
{ u3=q3/p3,u4=q4/p4;
if(q1<0||q2<0)
exit(0);
if(q1>=0&&q2>=0)
umax=max(u3,0);
umin=min(u4,1);
/* if(p3>0)
{
umin=min(u3,1);
umax=max(u4,0);
}
if(p3<0)
{
umax=max(u3,0);
umin=min(u4,1);
}
if(umax>umin)
exit(0);
if(umax<=umin)
{
x11=x1+umax*(x2-x1);
y11=y1+umax*(y2-y1);
x22=x1+umin*(x2-x1);
y22=x1+umin*(y2-y1);
}
*/

}

if(dy==0)
{
u1=q1/p1;u2=p2/q2;
if(q3<0||q4<0)
exit(0);
if(q3>=0&&q4>=0)
{
umax=(u3,0);
umin=min(u4,1);
}
/*if(p1>0)
{
umin=min(u1,1);
umax=max(u2,0);
}
if(p1<0)
{
umax=max(u1,0);
umin=min(u2,1);
}

if(umax>umin)
exit(0) ;
if(umax<=umin)
{
x11=x1+umax*(x2-x1);
y11=y1+umax*(y2-y1);
x22=x1+umin*(x2-x1);
y22=x1+umin*(y2-y1);
}*/

}

if(dx!=0&&dy!=0)
{
u1=(float)q1/(float)p1,u2=(float)q2/(float)p2,u3=(float)q3/(float)p3,u4=(float)q4/(float)p4;
float umin1,umax1;
umin1=min(u2,1);
umin=min(umin1,u4);
umax1=max(u1,0);
umax=max(umax1,u3);
/* int umin1,umax1;
if(p1>0&&p3>0)
{
umin1=min(u1,1);
umin=min(umin1,u3);
umax1=max(u2,0);
umax=max(umax1,u4);
}
if(p1>0&&p3<0)
{
umin1=min(u1,1);
umin=min(umin1,u4);
umax1=max(u2,0);
umax=max(umax1,u3);
}
if(p1<0&&p3<0)
{
umin1=min(u2,1);
umin=min(umin1,u4);
umax1=max(u3,0);
umax=max(umax1,u1);
}
if(p1<0&&p3>0)
{
umin1=min(u2,1);
umin=min(umin1,u3);
umax1=max(u1,0);
umax=max(umax1,u4);
}
if(umax>umin)
exit(0) ;
if(umax<=umin)
{
x11=x1+umax*(x2-x1);
y11=y1+umax*(y2-y1);
x22=x1+umin*(x2-x1);
y22=x1+umin*(y2-y1);
}
*/
}

if(umax>umin)
exit(0) ;
if(umax<=umin)
{
x11=x1+umax*dx;
y11=y1+umax*dy;
x22=x1+umin*dx;
y22=y1+umin*dy;
}

CDC* pDC=GetDC(); CPen penBlack;
penBlack.CreatePen(PS_SOLID, 3, RGB(0, 0, 255));
CPen* pOldPen = pDC->SelectObject(&penBlack);
pDC->MoveTo(x11,y11);
pDC->LineTo(x22,y22);

}

原文地址:https://www.cnblogs.com/qin5429/p/8986474.html

时间: 2024-11-09 05:11:37

梁友栋算法用多边形裁剪线段的相关文章

计算机图形学 - 线段裁剪 - Liang Barsky算法(梁友栋算法)

算法描述: Liang_Barsky算法的基本出发点是直线的参数方程.给出任意一条直线段,两端点分别为和,令, 则直线的参数方程为: 如果直线上任意一点位于窗口内,则必须满足下列关系式: 上述不等式可以表示为: 其中p和q定义为: 任何一条直线如果平行于某一条裁剪边界,则有,下标k 对应于直线段平行的窗口边界(,并且分别表示裁剪窗口的左.右.下.上边界).如果对于某一个k值,满足,那么直线完全在窗口的外面,可以抛弃.如果,则该直线在它所平行的窗口边界的内部,还需要进一步计算才能确定直线是否在窗口

[图形学]Chapter 8.7.2 梁友栋-Barsky线段裁剪算法

这节简单介绍了梁友栋-Barsky裁剪算法的原理,只有结论并没有过程,看过http://blog.csdn.net/daisy__ben/article/details/51941608这篇文章后,大概有了新的认识. " 假设点P1P2W1W2的横坐标分别是x1,x2,w1,w2,线段P1P2与蓝色裁剪窗口W1W2(蓝色的线之间)的存在公共部分(可见部分)的充要条件是: max(min(x1,x2), min(w1,w2))≤ min(max(x1,x2), max(w1,w2)) 即所谓左端点

张正友标定算法理论及算法实现

张正友标定算法理论及算法实现 理论基础 1999年,微软研究院的张正友提出了基于移动平面模板的相机标定方法.此方法是介于传统标定方法和自标定方法之间的一种方法,传统标定方法虽然精度高设备有较高的要求,其操作过程也比较繁琐,自标定方法的精度不高,张正友标定算法克服了这两者的缺点同时又兼备二者的优点,因此对办公.家庭的场合使用的桌面视觉系统(DVS)很适合. 设三维世界中坐标的点为:和二维相机平面坐标的点为: 为方便运算,模板被定义在世界坐标系中与X-y平面平行(即Z=0)的平面上,为模板平面上点的

算法5-5:线段交叉问题

问题 给定一系列线段,每条线段可以是水平或者竖直.求相交的线段 解决 算法的基本思想是先将线段以x坐标进行排序.做一条扫描线,从左往右扫描,也就是下图中的红线. 当进入一条水平的线时,记录该线段的y坐标. 当走出水平线时,从二叉查找树中删除该线段的y坐标. 当遇到竖直的线时,判断该线段范围内有无之前记录的坐标即可判断两线是否相交. 算法5-5:线段交叉问题,布布扣,bubuko.com

张正友标定算法解读(转)

一直以来想写篇相机标定方面的东西,最近组会上也要讲标定方面东西,所以顺便写了.无论是OpenCV还是matlab标定箱,都是以张正友棋盘标定算法为核心实现的,这篇PAMI的文章<<A Flexible New Technique for Camera Calibration>>影响力极大,张正友是zju的机械系出身,貌似现在是微软的终身教授了,有点牛的.我就简单的介绍下算法的核心原理,公式的推理可能有点多... 一 基本问题描述:空间平面的三维点与相机平面二维点的映射 假设空间平面

【算法系列学习】线段树vs树状数组 单点修改,区间查询 [kuangbin带你飞]专题七 线段树 A - 敌兵布阵

https://vjudge.net/contest/66989#problem/A 单点修改,区间查询 方法一:线段树 http://www.cnblogs.com/kuangbin/archive/2011/08/15/2139834.html 1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 #include<cmath> 6 #

算法导论学习-线段树(1)

1. 线段树简介: --------------- 线段树是建立在线段的基础上,每个结点都代表了一条线段[a,b].长度为1的线段称为元线段.非元线段都有两个子结点,左结点代表的线段为[a,(a + b) / 2],右结点代表的线段为[((a + b) / 2)+1,b].若非元线段的编号为 i,那么他的左孩子编号为 2*i,右孩子为 2*i+1.下图是一棵典型的线段树.,一般的,我们把根节点的编号设为1,那么下图很显然的,[1,5]的编号为2,[6,10]的编号为3,其他节点也以此类推. 2.

算法导论学习-线段树(2)

线段树(1)http://www.cnblogs.com/fu11211129/p/4230000.html 1. 线段树应用之动态点插与统计: -------------------------------- 线段树(1)中讲的应用是区段的插值与统计,我们在线段树结构体中接入cover之一域,cover等于0表示该节点所代表的区域并没有被完全覆盖,cover大于等于1表示该节点所代表区域已经被完全覆盖,用线段树(1)博客里面的图来说明一下:           如上图所示,我们最后统计的时候是

10.25算法训练——裸线段树

题目大意:对N(1<=N<=50000)个数进行连续进行M(1<=M<=200000)次询问:问1-N之间任意连续区间最大值和最小值之差. 之前学过线段树,学的是模版题,求解的问题是在一段区间内任意加减,然后再询问任意一段之区间的和. 这次的问题和之前学的模版题相同之处是:查询的是一段连续区间的信息. 不同之处在于:区间求和问题需要在线段树的每个结点记录其左儿子和右儿子所有结点之和.也就是说每个结点的信息是一个数. 所以之后的查询操作,也是不断去访问线段树的结点,将这些结点上的数加