Genesis 多边形闭轮廓填充算法
通过逐行扫描,计算得出直线与多边形相交点进行求解
原理图形如下所示:


相关函数:
/// <summary>
/// 求点P到线段L距离
/// </summary>
/// <param name="p"></param>
/// <param name="l"></param>
/// <param name="return_p"></param>
/// <param name="is_calc_width"></param>
/// <returns></returns>
public double p2l_di(gP p, gL l, gPoint return_p, bool is_calc_width = false)
{
double b, s, a_side, b_side, c_side;
a_side = p2p_di(p.p, l.ps);
if (a_side < eps) return ;
b_side = p2p_di(p.p, l.pe);
if (b_side < eps) return ;
c_side = p2p_di(l.ps, l.pe);
if (b_side < eps) return a_side; //' 钝角或直角三角形
if (a_side * a_side >= b_side * b_side + c_side * c_side)
{
return_p = l.pe;
if (is_calc_width)
return b_side - p.width * 0.0005 - l.width * 0.0005;
else
return b_side;
} if (b_side * b_side >= a_side * a_side + c_side * c_side)
{
return_p = l.ps;
if (is_calc_width)
return a_side - p.width * 0.0005 - l.width * 0.0005;
else
return a_side;
} // 锐角三角形
return_p = p2l_toP(p.p, l);
b = (a_side + b_side + c_side) * 0.5;
s = Math.Sqrt(b * (b - a_side) * (b - b_side) * (b - c_side));
if (is_calc_width)
return s * / c_side - p.width * 0.0005 - l.width * 0.0005;
else
return s * / c_side;
}
/// <summary>
/// 求点P到线L垂足P
/// </summary>
/// <param name="p"></param>
/// <param name="l"></param>
/// <returns></returns>
public gPoint p2l_toP(gPoint p, gL l)
{
gPoint tempP;
if (Math.Abs(l.ps.x - l.pe.x) < eps)//垂直
{
tempP.x = (l.ps.x + l.pe.x) * 0.5;
tempP.y = p.y;
}
else if (Math.Abs(l.ps.y - l.pe.y) < eps) //水平
{
tempP.x = p.x;
tempP.y = (l.ps.y + l.pe.y) * 0.5;
}
else
{
double k = (l.pe.y - l.ps.y) / (l.pe.x - l.ps.x);
tempP.x = (p.y - l.ps.y + k * l.ps.x + p.x * k) * (k + * k);
tempP.y = p.y - (tempP.x - p.x) / k;
}
return tempP;
}
/// <summary>
/// 求线段与线段交点
/// </summary>
/// <param name="l1ps"></param>
/// <param name="l1pe"></param>
/// <param name="l2ps"></param>
/// <param name="l2pe"></param>
/// <param name="isIntersect"></param>
/// <returns></returns>
public gPoint l2l_Intersect(gPoint l1ps, gPoint l1pe, gPoint l2ps, gPoint l2pe, ref bool isIntersect)
{
gL L1 = new gL(l1ps, l1pe, );
gL L2 = new gL(l2ps, l2pe, );
gPoint tempP = new gPoint();
double ABC, ABD, CDA, CDB, T;
//面积符号相同则两点在线段同侧,不相交 (对点在线段上的情况,本例当作不相交处理)
ABC = (L1.ps.x - L2.ps.x) * (L1.pe.y - L2.ps.y) - (L1.ps.y - L2.ps.y) * (L1.pe.x - L2.ps.x);
ABD = (L1.ps.x - L2.pe.x) * (L1.pe.y - L2.pe.y) - (L1.ps.y - L2.pe.y) * (L1.pe.x - L2.pe.x);
CDA = (L2.ps.x - L1.ps.x) * (L2.pe.y - L1.ps.y) - (L2.ps.y - L1.ps.y) * (L2.pe.x - L1.ps.x); // 三角形cda 面积的2倍 // 注意: 这里有一个小优化.不需要再用公式计算面积,而是通过已知的三个面积加减得出.
CDB = CDA + ABC - ABD; // 三角形cdb 面积的2倍
isIntersect = (CDA * CDB <= ) && (ABC * ABD <= );
//计算交点
T = CDA / (ABD - ABC);
tempP.x = L1.ps.x + T * (L1.pe.x - L1.ps.x);
tempP.y = L1.ps.y + T * (L1.pe.y - L1.ps.y);
return tempP;
}
Genesis实现后图示:


相关链接:http://www.cnblogs.com/zjutlitao/p/4117223.html
Genesis 多边形闭轮廓填充算法的更多相关文章
- OpenCV探索之路(十一):轮廓查找和多边形包围轮廓
Canny一类的边缘检测算法可以根据像素之间的差异,检测出轮廓边界的像素,但它没有将轮廓作为一个整体.所以要将轮廓提起出来,就必须将这些边缘像素组装成轮廓. OpenCV中有一个很强大的函数,它可以从 ...
- OpenCV计算机视觉学习(8)——图像轮廓处理(轮廓绘制,轮廓检索,轮廓填充,轮廓近似)
如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 1, ...
- OpenCV空洞填充算法
讨论帖: http://bbs.csdn.net/topics/391542633 在Matlab下,使用imfill可以很容易的完成孔洞填充操作,感觉这是一个极为常用的方法,然而不知道为什么Op ...
- CGA填充算法之种子填充算法
CGA填充算法之种子填充算法 平面区域填充算法是计算机图形学领域的一个很重要的算法,区域填充即给出一个区域的边界 (也可以是没有边界,只是给出指定颜色),要求将边界范围内的所有象素单元都修改成指定的颜 ...
- JAVA实现种子填充算法
种子填充算法原理在网上很多地方都能找到,这篇是继上篇扫描线算法后另一种填充算法,直接上实现代码啦0.0 我的实现只是实现了种子填充算法,但是运行效率不快,如果大佬有改进方法,欢迎和我交流,谢谢! 最后 ...
- 种子填充算法描述及C++代码实现
项目需要看了种子填充算法,改进了算法主要去除面积小的部分.种子填充算法分为两种,简单的和基于扫描线的方法,简单的算法如下描述(笔者针对的是二值图像): (1)从上到下,从左到有,依次扫描每个像素: ( ...
- 图像处理之泛洪填充算法(Flood Fill Algorithm)
泛洪填充算法(Flood Fill Algorithm) 泛洪填充算法又称洪水填充算法是在很多图形绘制软件中常用的填充算法,最熟悉不过就是 windows paint的油漆桶功能.算法的原理很简单,就 ...
- 漫水填充算法 - cvFloodFill() 实现
前言 漫水填充算法是用来标记一片区域的:设置一个种子点,然后种子点附近的相似点都被填充同一种颜色. 该算法应用性很广,比如目标识别,photoshop 的魔术棒功能等等,是填充类算法中应用最为广泛的一 ...
- Open gl 的不规则图形的4联通种子递归填充和扫描线种子递归填充算法实现
实验题目:不规则区域的填充算法 实验目的:验证不规则区域的填充算法 实验内容:利用VC与OpenGL,实现不规则区域的填充算法. 1.必做:实现简单递归的不规则区域填充算法. 2.选做:针对简单递归算 ...
随机推荐
- 【技术累积】【点】【java】【22】UUID
基础概念&使用 UUID是Universally Unique Identifier的缩写,它是在一定的范围内(从特定的名字空间到全球)唯一的机器生成的标识符. 说白了就是个唯一键,只不过到处 ...
- 【转载】Linux 通过mount -o loop 配置本地.iso镜像为yum源(yum仓库)
原文地址:https://www.jb51.net/os/RedHat/2682_all.html 如果拷贝到本地,可以使用mount mount fileName mountPoint -o loo ...
- windows上关闭Nagle算法
下面的设置可以调整或禁用 nagel 算法.禁用 nagel 算法以后, 允许很小的包没有延迟立即发送.建议对某些游戏关闭 nagel 算法, 这样做对文件传输/吞吐量有负面影响.默认状态( 开启na ...
- yum插件
参考文章: http://www.linuxfly.org/post/297/ [root@dnstest07.tbc /home/ahao.mah] #rpm -qa |grep yum yum-p ...
- 基本数据类型:布尔型(bool)和空值None
一.布尔型(bool) 布尔类型很简单,就两个值 ,一个True(真),一个False(假), 主要用记逻辑判断: 一件事情成立就是True,不成立就是False,也可以将bool值归类为数字, 是因 ...
- C#学习笔记_14_接口&命名空间
14_接口&命名空间 接口 一系列规范 语法: 如果一个类的后面既有父类也有接口,那么一定是父类在前,接口靠后 一个类可以实现多个接口 规范:接口命名以大写字母 I 开头 接口中可以包含接口方 ...
- 【codeforces 510D】Fox And Jumping
[题目链接]:http://codeforces.com/contest/510/problem/D [题意] 你可以买n种卡片; 每种卡片的花费对应c[i]; 当你拥有了第i种卡片之后; 你可以在任 ...
- Java POI Excel 导入导出
这个东西很容易懂,不是特别难,难就难在一些复杂的计算和Excel格式的调整上. 近期写了一个小列子,放上来便于以后使用. POI.jar下载地址:http://mirror.bit.edu.cn/ap ...
- (43). Spring Boot动态数据源(多数据源自动切换)【从零开始学Spring Boot】
在上一篇我们介绍了多数据源,但是我们会发现在实际中我们很少直接获取数据源对象进行操作,我们常用的是jdbcTemplate或者是jpa进行操作数据库.那么这一节我们将要介绍怎么进行多数据源动态切换.添 ...
- 关于单CPU,多CPU上的原子操作
所谓原子操作,就是"不可中断的一个或一系列操作" . 硬件级的原子操作:在单处理器系统(UniProcessor)中,能够在单条指令中完成的操作都可以认为是" 原子操作& ...