【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 ...
随机推荐
- Python基础教程【读书笔记】 - 2016/8/3
希望通过博客园持续的更新,分享和记录Python基础知识到高级应用的点点滴滴! 第十一波:第11章 文件和素材 本章更进一步,让程序能够接触更多的领域:文件和流.接下来介绍的函数和对象可以让你在程序 ...
- Redis性能测试工具benchmark简介
Redis自己提供了一个性能测试工具redis-benchmark.redis-benchmark可以模拟N个机器,同时发送M个请求. 用法:redis-benchmark [-h -h <ho ...
- MySQL计算时间差
MySQL计算两个日期的时间差函数:TIMESTAMPDIFF 语法: TIMESTAMPDIFF(interval, datetime_expr1, datetime_expr2) interval ...
- 常用JS
window.opener.location.reload(); 刷新上一个页面 window.opener=null;window.open('','_self');window.close(); ...
- iphone dev 入门实例4:CoreData入门
The iPhone Core Data Example Application The application developed in this chapter will take the for ...
- PL/SQL中查看列注释、列属性
- [物理学与PDEs]书中出现的符号及其意义汇总
1. 标量 $\ve_0$: $=8.85419\times 10^{-2}C^2/(N\cdot m^2)$ 真空中的介电常数 $\ve$: 介电常数 $\ve_r$: $=1+\chi_e$ 相对 ...
- 转 -android:程序无响应,你该如何定位问题?
如果MainThread长时间无响应,系统会提示“XXX无响应”,然后用户会关闭.那么,如何定位问题呢?无响应并不像Crash,它抓取不到异常日志,通常我们需要调试,才能定位问题.如何调试呢? 1.在 ...
- redmine后台运行命令
nohup ruby script/rails server webrick -e production & redmine 3 后台运行命令: nohup bundle exec rail ...
- gridview转成EXCEL文件保存(多页)
CompositeLink complink = new CompositeLink(new PrintingSystem()); PrintableComponentLink link = new ...