【CImg】三角形绘制算法实现
这周的CV基础练习是简单的图形绘制:比如说矩形、三角形和圆心什么的。会发现其实矩形和圆形的实现思路都很直白,矩形只需要确认两个对角坐标就可以了,圆心只需要确认圆心和半径,接着就是简单的遍历各个像素点判断。但是,三角形的绘制把数学渣的我难住了,然后去查了一下资料,受到了知乎某位大神的启发:
如下截图:

于是有了以下思路:
一.实心三角形绘制
①算出三条直线L1、L2、L3的直线方程,即K1、K2、K3(斜率)和B1、B2、B3(截距)的值
②设三个顶点为P1、P2、P3,某一个任意位置的像素点P,P1P2的直线为L1.
③要判断P点是否在L1的“+”一边,则把P、P3分别带入直线方程,算出Y-(KX+B)的值,同时大于0或者同时小于0,则P落在“+”,否则在“-”
④判断P点是否在三角形内,则需要判断P是否同时落在三条直线的“+”区域,所以要做三次判断
二. 三角形边框绘制
①求出三条直线方程
②求出三角形范围内的X轴最大最小值,Y轴最大最小值
③在minX~maxX, minY~maxY的范围内遍历,只要P点落在直线方程上,则可以判断为真,赋上指定的绘制颜色
code实现:
//一个三角形,需要依靠三个顶点来确立,同样还需要颜色以及空心与否等条件
void drawTri(CImg<unsigned char>& inputImage, vector<int>& position, vector<int>& color, bool solid ) {
unsigned int width = inputImage.width();
unsigned int height = inputImage.height();
unsigned int depth = inputImage.depth();
unsigned int spectrum = inputImage.spectrum(); ////算法优化,尽量地减少遍历范围
int minX = (position[] > position[] ? position[] : position[]) > position[] ? position[] : (position[] > position[] ? position[] : position[]);
int maxX = (position[] > position[] ? position[] : position[]) < position[] ? position[] : (position[] > position[] ? position[] : position[]);
int minY = (position[] > position[] ? position[] : position[]) > position[] ? position[] : (position[] > position[] ? position[] : position[]);
int maxY = (position[] > position[] ? position[] : position[]) < position[] ? position[] : (position[] > position[] ? position[] : position[]); //三条直线方程
double k1, b1, k2, b2, k3, b3;
k1 = (position[] - position[]) / (position[] - position[] + 0.0);
b1 = position[] - k1 * position[];
k2 = (position[] - position[]) / (position[] - position[] + 0.0);
b2 = position[] - k2 * position[];
k3 = (position[] - position[]) / (position[] - position[] + 0.0);
b3 = position[] - k3 * position[]; //遍历范围增大,防止边界无法检测 +2, 此处不需要担心超出边界,因为在最后赋值的时候会再判断一次
for (int x = minX - ; x <= maxX + ; x ++) {
for (int y = minY - ; y <= maxY + ; y ++) {
if (y >= && y < height && x >= && x < width) {
//按照三角形绘制算法,我们需要判断某一点落在正确的一边就需要依赖三角形中的第三个点
//P1P2形成直线L1,判断(X, Y)是否落在正确的一边,就把P3和该点一起带入直线方程,同时大于0,或者同时小于0则为真(即有效)
//判断某一点是否对于三条直线方程都符合条件(都为真,则该点落在三角形内)
int ans1 = static_cast<int>(position[] - (position[] * k1 + b1));
int ans2 = static_cast<int>(y - (x * k1 + b1));
int ans3 = static_cast<int>(position[] - (position[] * k2 + b2));
int ans4 = static_cast<int>(y - (x * k2 + b2));
int ans5 = static_cast<int>(position[] - (position[] * k3 + b3));
int ans6 = static_cast<int>(y - (x * k3 + b3));
bool line1 = false, line2 = false, line3 = false;
if ((ans1 > && ans2 >= -) || (ans1 < && ans2 <= ))line1 = true;
if ((ans3 > && ans4 >= -) || (ans3 < && ans4 <= ))line2 = true;
if ((ans5 > && ans6 >= -) || (ans5 < && ans6 <= ))line3 = true;
if (line1 && line2 && line3) {
for (int z = ; z < spectrum; z ++){
if (solid) {
inputImage.atXYZC(x, y, , z) = static_cast<unsigned char>(color[z]);
}
else {
if (ans2 == || ans4 == ||ans6 == ) {
inputImage.atXYZC(x, y, , z) = static_cast<unsigned char>(color[z]);
}
}
}
} }
}
}
};
drawTri
效果如下图:
(填充)

(非填充)

【CImg】三角形绘制算法实现的更多相关文章
- pcl曲面重建模块-贪婪三角形投影算法实例
贪婪三角形投影算法 在pcl-1.8测试 #include <pcl/point_types.h> #include <pcl/io/pcd_io.h> #include &l ...
- [算法]检测空间三角形相交算法(Devillers & Guigue算法)
#pragma once //GYDevillersTriangle.h /* 快速检测空间三角形相交算法的代码实现(Devillers & Guigue算法) 博客原地址:http://bl ...
- CSS 利用border三角形绘制方法
CSS 三角形绘制方法,这里面的transparent比较重要,有和没有影响很大: 原理:这个div是由4个三角形组成,每个三角对应一个border,隐藏其它3个border,就可以得到一个三角形. ...
- OpenglEs之三角形绘制
在前面我们已经在NDK层搭建好了EGL环境,也介绍了一些着色器相关的理论知识,那么这次我们就使用已经搭配的EGL绘制一个三角形吧. 在Opengl ES的世界中,无论多复杂的形状都是由点.线或三角形组 ...
- OpenGL ES 3.0 点,线,三角形绘制形式总结
OpenGL ES 3.0 顶点 -1, 1, 0, -0.5f, 0, 0, 0, -1, 0, -1, 0, 0, 0.5f, 0, 0, 1, -1, ...
- 探索颜色渐变绘制算法(基于Processing语言) 第一部分
突然间意识到连续变化的颜色在程序中是如何实现的这一问题.没错,就想有事找事,我会分好几部分慢慢探寻,其实笔者也不会,咱一起研究.ok,我们开始! 第一部分 初始部分就从官方案例来入手学习.官方给了三个 ...
- css三角形绘制
三角形演变: 1.将一个块元素的宽.高都设置为0,再设置边框样式,得如下效果图(绿色部分): 样式: {;;border: 35px solid #7de87d;} 通过此样式得到的是一个正方形. 2 ...
- 3D引擎为什么使用三角形绘制曲面
这个问题是我第一次接触3D开发就有的疑问,最近在看<游戏引擎架构>(Game Engine Architecture),在书中找到了答案. 三角网格(Triangle Mesh),游戏开发 ...
- Openlayers3中实现台风风圈绘制算法
概述: 台风的风圈的NE.NW.SW.SE四个方位的影响范围是不一致,本文介绍一种简单的风圈的绘制方法,并在OL3中展示. 实现效果: 实现代码: 1.数据格式 var Configs = { CIR ...
随机推荐
- js之引用类型
一.摘要: <javascript高级程序设计第三版>一书中单独有一章对js的引用类型(Object.Array.RegExp.Function:基本包装类型:Boolean.Number ...
- CentOS6.8安装Redis3.2.5
1.下载Redis3.2.5安装包 wget http://download.redis.io/releases/redis-3.2.5.tar.gz 2.解压.编译.安装redi ...
- TCP中需要了解的东西
1.TCP是一个流协议. TCP跟UDP不一样的是,TCP发送过去的东西是stream,也就是说第一次发送的跟第二次发送的数据包可能会粘在一起,即所谓的粘包问题 http://blog.csdn.ne ...
- SQLServer数据库字典维护方法
启用SQLServer启用管理器,以2008为例 1.设置表信息描述 选中要设置的表,右键点击“属性” . 选择扩展属性 填写要求: 名称:MS_Description 值: 模块名称-表名称 修改语 ...
- [工具开发] Perl 爬虫脚本--从美国国家漏洞数据库抓取实时信息
一.简介 美国国家漏洞数据库收集了操作系统,应用软件的大量漏洞信息,当有新的漏洞出现时,它也会及时发布出来. 由于信息量巨大,用户每次都需要到它的网站进行搜索,比较麻烦.如果能有个工具,每天自动分析它 ...
- Tomcat服务器搭建
一.JDK环境搭建 二.tomcat下载安装 三.tomcat服务启动 cmd> net start tomcat8 四.查看tomcat服务器启动情况: http://localhost:8 ...
- TMS320C54x系列DSP的CPU与外设——第3章 存储器
第3章 存储器 本章介绍了TMS320C54x DSP存储器的构成和操作.一般来说,C54x器件共有192K 16位字的存储窨,这个空间分成3个专用的部分:64K字程序.64K字数据和64K字I/O ...
- 黄聪:走进wordpress 详细说说template-loader.php
再看template-laoder.php,这个文件总共只有45行.它的作用是基于访问的URL装载正确的模板. 文件第六行,也是第一条语句,如下: if ( defined('WP_USE_THEME ...
- 简单的缓存代理HTTP服务器
http, 演示客户与服务器套接字. http只支持GET操作及硬编码的MIME类型的一小部分(MIME类型是多媒体内容的类型描述符).代理HTTP服务器是单线程的,该线程中每一个请求依次被处 ...
- VC++、MFC、COM和ATL的区别
今天看到的,感觉不错.转载了 一.什么是MFC 微软基础类(Microsoft Foundation Classes),实际上是微软提供的,用于在C++环境下编写应用程序的一个框架和引擎,VC++是W ...