这周的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】三角形绘制算法实现的更多相关文章

  1. pcl曲面重建模块-贪婪三角形投影算法实例

    贪婪三角形投影算法 在pcl-1.8测试 #include <pcl/point_types.h> #include <pcl/io/pcd_io.h> #include &l ...

  2. [算法]检测空间三角形相交算法(Devillers & Guigue算法)

    #pragma once //GYDevillersTriangle.h /* 快速检测空间三角形相交算法的代码实现(Devillers & Guigue算法) 博客原地址:http://bl ...

  3. CSS 利用border三角形绘制方法

    CSS 三角形绘制方法,这里面的transparent比较重要,有和没有影响很大: 原理:这个div是由4个三角形组成,每个三角对应一个border,隐藏其它3个border,就可以得到一个三角形. ...

  4. OpenglEs之三角形绘制

    在前面我们已经在NDK层搭建好了EGL环境,也介绍了一些着色器相关的理论知识,那么这次我们就使用已经搭配的EGL绘制一个三角形吧. 在Opengl ES的世界中,无论多复杂的形状都是由点.线或三角形组 ...

  5. 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,   ...

  6. 探索颜色渐变绘制算法(基于Processing语言) 第一部分

    突然间意识到连续变化的颜色在程序中是如何实现的这一问题.没错,就想有事找事,我会分好几部分慢慢探寻,其实笔者也不会,咱一起研究.ok,我们开始! 第一部分 初始部分就从官方案例来入手学习.官方给了三个 ...

  7. css三角形绘制

    三角形演变: 1.将一个块元素的宽.高都设置为0,再设置边框样式,得如下效果图(绿色部分): 样式: {;;border: 35px solid #7de87d;} 通过此样式得到的是一个正方形. 2 ...

  8. 3D引擎为什么使用三角形绘制曲面

    这个问题是我第一次接触3D开发就有的疑问,最近在看<游戏引擎架构>(Game Engine Architecture),在书中找到了答案. 三角网格(Triangle Mesh),游戏开发 ...

  9. Openlayers3中实现台风风圈绘制算法

    概述: 台风的风圈的NE.NW.SW.SE四个方位的影响范围是不一致,本文介绍一种简单的风圈的绘制方法,并在OL3中展示. 实现效果: 实现代码: 1.数据格式 var Configs = { CIR ...

随机推荐

  1. sqlite 下载的 ZIP 包的区别

    https://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki sqlite-netFx20-binary-bundle- ...

  2. SPOJ #5 The Next Palindrome

    "not more than 1000000 digits" means an efficient in-place solution is needed. My first so ...

  3. linux下查看进程运行的时间

    原文链接:http://www.centoscn.com/CentOS/2014/0403/2724.html 可通过ps 来查看,通过参数 -o 来查看 例: ps -eo pid,tty,user ...

  4. iwpriv

    AuthMode             {OPEN,SHARED,WEPAUTO,WPAPSK,WPA2PSK,WPANONE} ::Set Authentication Mode EncrypTy ...

  5. DatagridView 最后编辑状态数据无法自动提交的问题

    DataGridView1.CurrentCell = null 从一个帖子上看的,绝招! http://bbs.csdn.net/topics/120020614

  6. css3旋转小三角

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. PHP 正则表达式常用函数使用小结

    在PHP中有两套正则表达式函数库.一套是由PCRE(Perl Compatible Regular Expression)库提供的.PCRE库使用和Perl相同的语法规则实现了正则表达式的模式匹配,其 ...

  8. 在UIViewController中获得Container View里的embed viewController的引用

    When you want to use a controller you use the UIStoryboard method instantiateViewControllerWithIdent ...

  9. OAF_OAF Debug And Log调试和记录工具的详解(案例)

    2014-06-16 Created By BaoXinjian

  10. c# 函数及out传值

    使用 out传值的时候仅仅是将变量名(箱子)拿过来,并不会管之前是什么值函数体结束之前必须对该out的参数进行赋值,否则报错(不好意思还回去)out传值,可以进行多个值的传回 public void ...