【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 ...
随机推荐
- 【jmeter】搭建持续集成接口测试平台(Jenkins+Ant+Jmeter)
一.环境准备: 1.JDK:http://www.oracle.com/technetwork/java/javase/downloads/index.html 2.Jmeter:http://jme ...
- Python 函数的创建和调用
>>> movies =[ "the holy grail", 1975,"terry jones",91, ["graham ch ...
- gcc和ld 中的参数 --whole-archive 和 --no-whole-archive
首先 --whole-archive 和 --no-whole-archive 是ld专有的命令行参数,gcc 并不认识,要通gcc传递到 ld,需要在他们前面加 -Wl,字串. --whole-ar ...
- GCC 编译使用动态链接库和静态链接库
1 库的分类 根据链接时期的不同,库又有静态库和动态库之分. 静态库是在链接阶段被链接的(好像是废话,但事实就是这样),所以生成的可执行文件就不受库的影响了,即使库被删除了,程序依然可以成功运行. 有 ...
- JavaScript中Eval()函数的使用
Eval()常用的几种形式 1.我们预先不知道要执行什么语句,只有当条件和参数给时才知道执行什么语句,这时候eval就派上用场了. function output(a, b) { var tmpa, ...
- Javascript之UI线程与性能优化
在浏览器中,Javascript执行与UI更新是发生在同一个进程(浏览器UI线程)中的.UI线程的工作基于一个简单的队列系统,任务会被保存到队列中直到进程空闲时被提取出来执行.所以Javascript ...
- C#(类)
一.String类 string s = " abCDefgb ";int a = s.Length;//获取长度 Console.WriteLine(s.Length); Con ...
- English Notes
1. Thanks for stopping by.慢走不送. 2. I don't like to judge a book by it's cover.我不喜欢以貌取人. 3. Rush hour ...
- 什么是bower
Bower是一个客户端技术的软件包管理器,它可用于搜索.安装和卸载如JavaScript.HTML.CSS之类的网络资源.其他一些建立在Bower基础之上的开发工具,如YeoMan和Grunt,这个会 ...
- win10,软件, 发布者不受信任怎么办
这个方法比较管用:右键单击windows左下角,弹出右击菜单选择‘命令提示符(管理员)(A)’,然后用DOS命令安装程序.就可以了 PS:win10的cmd可以直接复制粘贴了.