这周的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. POJ #1015 - Jury Compromise - TODO: POJ website issue

    (poj.org issue. Not submitted yet) This is a 2D DP problem, very classic too. Since I'm just learnin ...

  2. 在使用Redis的客户端连接工具ServiceStack.Redis要注意的问题

    在使用Redis的客户端连接工具ServiceStack.Redis要注意的问题   Redis是一个非常NB的内存级的数据库,我们可以把很多”热数据“(即读写非常多的数据)放入其中来操作,这样就减少 ...

  3. 借助LVS+Keepalived通过DR模式实现负载均衡

    1.测试环境4台server,全部初始化一下,该关的关了 # vim /etc/hosts 192.168.1.101 lvs-master DIP 192.168.1.102 lvs-slave D ...

  4. 【转】 远程到服务器安装visualSVN server,出现Service 'VisualSVN Server' failed to start的解决方法

    在帮助远程到服务器上安装visualSVN server的时候,出现Service 'VisualSVN Server' failed to start. 解决方法(先不要关闭安装弹出的错误窗口): ...

  5. iphone dev 入门实例6:How To Use UIScrollView to Scroll and Zoom and Page

    http://www.raywenderlich.com/10518/how-to-use-uiscrollview-to-scroll-and-zoom-content Getting Starte ...

  6. easy dp

    1.将一堆正整数分为2组,要求2组的和相差最小. //File Name: nod1007.cpp //Author: long //Mail: 736726758@qq.com //Created ...

  7. Linux Deepin 2014安装Lenovo LJ2600D驱动

    双11老师给实验室抢了个Lenovo LJ2600D的USB接口打印机,并用旧的HP-1080MFP网络打印服务器连接上了.Windows下就不多说了,官方给的驱动就是针对它的,同学们都用得爽爆了,因 ...

  8. 标准电流信号为什么是4-20MA?(网络摘录)

    一来源: 4-20mA.DC(1-5V.DC)信号制是国际电工委员会(IEC):过程控制系统(是连接仪表.变送设备.控制设备.计算机采样设备)用模拟信号标准.我国从DDZ-Ⅲ型电动仪表开始采用这一国际 ...

  9. Java多线程之新类库中的构件PriorityBlockingQueue

    package concurrent2; import java.util.ArrayList; import java.util.List; import java.util.Queue; impo ...

  10. Decorator装饰模式

    动态地给一个对象增加一些额外的职责.就增加功能而言,Decorator模式比生成子类更为灵活. ——<设计模式>GoF 作用:在不影响其他对象的情况下,以动态.透明的方式给单个对象添加职责 ...