![](https://img-blog.csdnimg.cn/20201014180756927.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
C++
文章平均质量分 66
图形跟班
we've got to find what we love.
展开
-
问题六十四:怎么用C++实现二叉查找树(binary search tree)及其相关操作
64.0 概述什么是二叉查找树(binary search tree)?二叉查找树(binary search tree)又叫二叉排序树(binary ordered tree)。对于任意二叉查找树,要么是一棵空树,要么具有如下性质:若它的左子树不为空,则左子树上所有结点的值都小于它的根结点的值;若它的右子树不为空,则右子树上所有结点的值都大于它的根结点的值;它的左、右子树原创 2017-02-04 19:22:23 · 499 阅读 · 0 评论 -
问题六十五:二叉查找树的一个应用实例——求解一元十次方程时单实根区间的划分
65.1 概述回忆一下:“问题五十九:怎么求一元六次方程在区间内的所有不相等的实根”和“问题六十二:怎么求一元十次方程在区间内的所有不相等的实根”中求一元六次方程和一元十次方程的实根时,我们需要将求根区间划分成若干个单根子区间,然后再用牛顿迭代法求出方程在子区间的该单实根。关于“划分单根子区间”,我们之前的做法是:1,若子区间内实根的个数大于1,则将区间二分(将区间的右端值移至区间原创 2017-02-04 19:53:49 · 845 阅读 · 0 评论 -
问题六十六:怎么用ray tracing画CSG(Constructive Solid Geometry 构造实体几何)图形
66.1 概述什么是CSG图形? 若干简单图形通过集合运算后得到的复杂图形,被称为“CSG图形”。其中“简单图形”,包括:sphere, box, cylinder, and so on.其中“集合运算”,包括:并集、交集、相减(差集) 示意图如下:(CSG图形可以用二叉树表示)蓝色框标注的是“简单图形”:两个box、一个cylinder红色框标注的原创 2017-02-04 20:05:02 · 6387 阅读 · 0 评论 -
问题二:用C++输出第一张图片
将书上对应的代码抄写了一遍。#include <iostream>#include <fstream>using namespace std;int main(){ int nx = 200; int ny = 100; ofstream outfile( "mytest.txt", ios_base::out); outfile << "P3\n" << nx <原创 2017-01-13 22:56:52 · 16586 阅读 · 6 评论 -
问题三:类的头文件和实现文件分别写什么(用向量表示RGB输出“第一张图片”)
书上接下来是介绍一个表示向量的类(vec3)。所以,我要先创建一个新的类vec3。创建该类之后,生成两个文件:vec3.cpp和vec3.h。像之前一样,还是将书上的代码原封不动地抄写下来,如下:#ifndefVEC3_H#defineVEC3_H #include#include#include usingnamespace std; class vec3{ pu原创 2017-01-13 23:02:13 · 1736 阅读 · 0 评论 -
问题四:C++中inline是干嘛用的
iInline:若一个函数被指定为inline函数,则它将在程序中每个调用点上被内联地展开。一般来说,内联函数不会引入任何函数调用。所以可以提高执行效率。注意,函数home() 、get() 、height()和width()的定义是在类体内提供的。这些函数被称为“在类定义中定义的内联(inline)函数”。这些函数被自动作为inline函数处理。我们也可以通过在成员函数的返回类型前显式地原创 2017-01-13 23:14:27 · 2327 阅读 · 0 评论 -
问题五:C++中const是干嘛用的
还是先问度娘:http://www.cnblogs.com/lichkingct/archive/2009/04/21/1440848.html此处不单独谈及const修饰变量或指针的情况,独谈和函数相关的情况。 5.1 const修饰函数。表明该函数不修改类对象(不改变对象的非const成员变量. 也不能调用类中任何非const成员函数)。格式:关键字const被放在成员函数原创 2017-01-13 23:18:11 · 908 阅读 · 0 评论 -
问题六:C++中&是干嘛用的(引用类型)
6.1 指向独立对象的引用类型参考C++ Primer (3rd)的3.6章节通过引用我们可以间接地操纵对象,使用方式类似于指针。但是不需要指针的语法。 引用类型由类型标识符和一个取地址操作符来定义。 1. 引用必须被初始化,不允许空引用。int &refVal = ival; int &refVal2;// 错误引用必须被初始化为指向一个对象 2. 引原创 2017-01-13 23:25:08 · 883 阅读 · 0 评论 -
问题七:operator+=()是什么鬼函数?(重载操作符)
重载的操作符在类体中被声明声明,方式同普通成员函数一样,只不过它的名字包含关键字operator,以及紧随其后的一个预定义操作符(该操作符必须来自C++预定义操作符的一个子集见表15.1)。为什么要进行操作符重载??????关于操作符重载要遵循这么多原则(此处不解释),那么为什么还要进行操作符重载呢?为什么我不是写一个add()函数,代替operator +()呢??个人感觉C++中之所以原创 2017-01-13 23:32:55 · 3266 阅读 · 0 评论 -
问题八:C++中this是干嘛用的
参考C++ Primer (3rd)的13.4章节 每个类成员函数都含有一个指向被调用对象的指针,这个指针被称为this。所以: this表示被调用对象的指针; *this表示被调用对象本身; inline void Screen::home(){ this->_cursor = 0;}此处this表示被调用对象的指针原创 2017-01-13 23:35:14 · 1848 阅读 · 0 评论 -
问题九:C++中::是干嘛用的(域解析操作符)
一两行以上的成员函数最好被定义在类体之外。这要求一个特殊的声明语化来标识一个函数是一个类的成员:成员函数名必须被它的类名限定修饰(qualified)。也就是告诉编译器,这个成员函数在我这类的类域内,直到该成员函数结束。(by the way, 类体就定义了一个类域,类体外通过::扩充类域吧)比如:class vec3 {public: inline vec3& oper原创 2017-01-13 23:37:36 · 5351 阅读 · 0 评论 -
问题十:【总结】解决了问题四~问题九,vec3这个类的代码应该都能看懂了
类体内: inline floatx()const { return e[0]; }类体内定义成员函数x()。const:表示该函数不修改类对象。inline:表示该函数在程序中每个调用点上被内联地展开。 inlineconst vec3&operator+()const{ return *this; }类体内定义成原创 2017-01-13 23:41:15 · 2335 阅读 · 0 评论 -
问题十一:用条件编译(#if…#endif)避免 main函数中测试代码在测试完成后就删除
#define testNumber 3/*1: output the first image2: test "int &ri,int& ri,int*&pri"3: output the first image by using vector.*/ #if testNumber == 1 /*1: output the first image*///完整的测试代码原创 2017-01-13 23:48:10 · 1673 阅读 · 0 评论 -
问题十三:怎么用ray tracing画个球
当然这个球是画在之前的背景图上。通过画第一张图,已经直到画图有两个步骤:其一,确定位置(范围、大小);其二,设置颜色。画球也不例外。第一步:确定球的位置。球上每个像素点的位置即为光线与球的交点,所有这些交点就组成了球。所以,问题转化为找光线和球的交点。第二步:设置球的颜色。即设置光线和球交点的颜色。 (图都是一个像素点一个像素点画出来的,一个光线代表着一个像素点。此处和球有原创 2017-01-14 00:05:33 · 1970 阅读 · 0 评论 -
问题十五:C++中抽象类,虚函数是什么鬼?怎么测试
该篇内容提要:1,理论解释,来自网上;2,测试两个子类对父类虚函数的实现。 15.1 抽象类、虚函数是什么鬼?http://www.cnblogs.com/dongsheng/p/3343939.html一、纯虚函数定义. 纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加“原创 2017-01-14 00:12:10 · 1936 阅读 · 0 评论 -
问题十六:使用初始化列表的构造函数和使用函数体的构造函数有什么区别?
先看一段代码:class sphere: public hitable{ public: sphere() {} sphere(vec3 cen, float r) : center(cen), radius(r) {}//这是什么鬼??? virtual bool hit(constray& r, float tmin, fl原创 2017-01-14 00:14:54 · 810 阅读 · 0 评论 -
问题十二:怎么用ray tracing画第一张图
ray 类:(位于ray.h中。ray.cpp为空)#ifndef RAY_H#define RAY_H#include "vec3.h"class ray{ public: ray() {} ray(const vec3& a, const vec3& b) { A = a; B = b; } vec3 orgin() con原创 2017-01-13 23:49:43 · 2543 阅读 · 2 评论 -
问题六十七:ray tracing学习总结(2016.11.13, 2017.02.05)
从2016.11.13开始接触ray tracing到今天2017.02.05,差不多80天的时间。截至当前,学习ray tracing的过程,也是我重新找回自己或者说是“find what I love”的过程。不再浮躁,不再急功近利,不再认为“人活着就是为了赚钱”。我现在的观点是:对个人而言,活着的意义就是“find what we love”。找到爱的人,快乐生活;找到爱的事,快乐工作。原创 2017-02-05 18:02:09 · 1772 阅读 · 2 评论 -
问题十四:怎么可视化球的法向量
书上的原话是:visualize the normals with a color map,但是代码实现的是光线撞上球,然后色彩表(RGB)可视化“撞点”的法向量。开章第一句是“First, let’s get ourselves a surface normal so we can shade.”。这句话是看懂了“获取法向量是为了shade”,但是不知道具体是讲的是啥。为什么要可视化?为原创 2017-01-14 00:08:27 · 3550 阅读 · 5 评论 -
问题十八:怎么对ray tracing图形进行消锯齿
先将上一章节的图放大8倍,看看局部:边界的锯齿很清晰很明显很刺眼啊,有木有?我们现在要做的就是使得这些锯齿不那么清晰不那么明显不那么刺眼。简单地说,使边界模糊。之前的图是每个像素点设置一个颜色值,相当于将像素中心位置的颜色设置给了整个像素。所以,如果两个像素点中心位置的颜色值相差比较大时,这两个像素点就会产生清晰的边界。那么问题来了,怎么使得两个像素点的边界模糊呢?书上的做法是原创 2017-01-14 19:21:33 · 1554 阅读 · 2 评论 -
问题十九:怎么模拟ray tracing中漫射材料球体的颜色(diffuse materials)
前面画一个球时,球体的颜色设置为红色;前面画多个球时,球体的颜色设置为球在该点的单位法向量的色彩表映射值;现在画多个漫射材料的球,球体的颜色设置为背景颜色的系数倍。(姑且表述为“背景颜色”吧,将在“问题二十一”中确切说明) 漫射材料不发光,只吸收和反射环境的光(反射光的方向是随机的),所以将漫射材料的球体的颜色设置为背景颜色乘以某系数是合理的。系数怎么确定呢?光线每被反射一次*1/原创 2017-01-14 19:30:29 · 1937 阅读 · 0 评论 -
问题二十:C++全局debug “ray tracing图形”实例
紧接上文,漫射材料的球体颜色是不是太黑了呢?为什么会这么黑?接下来要debug啦!!! 第一步:取消“消锯齿”首先想到的是:应该减少光线条数。所以,将“消锯齿”的哪个ns系数设置为1先,原本的系数是100。简单算一下200*100的图片是2万个像素点,为了消锯齿,每个像素点采样100次然后求平均值,也就是一共采样200万次(by the way, 最后一次还真尝试打出了200万条l原创 2017-01-14 19:38:33 · 1593 阅读 · 8 评论 -
问题二十一:怎么模拟ray tracing图形中不同材料的颜色(diffuse and metal)
在漫射材料章节,我们将多个球都模拟成漫射材料的颜色。那么问题来了,我们能不能将不同的球模拟成不同材料的颜色呢?可以哈!我们这一章节就干这事。 21.1总结一下设置颜色的几种方法我们还是先回忆一下:ray tracing画图时,我们用过的设置颜色的方法: 1,第一张图(背景):vec3 unit_direction = unit_vector(r.directio原创 2017-01-14 20:11:21 · 2169 阅读 · 1 评论 -
问题二十二:C++中怎么添加log开关
说这问题的原因有二。其一,这两天在条程序时,如果在每条光线都会跑到的函数添加log,log的总量非常多(200*100的图片,每个像素点采样100次的话,一共就是1百万次采样,如果每次采样打一条log,就是1百万条。有一次在调试一张图片时,生成的log文件超过100Mkb)。其二,以前在公司时,和同事们一起解问题时,经常碰到说“帮忙开一下某个模块的log,然后帮忙抓一份完整的log”。原创 2017-01-14 20:29:08 · 1833 阅读 · 0 评论 -
问题二十三:C++中debug简单的运行死机问题
其实,“模拟不同材料颜色”章节中,刚添加完相关code之后,运行出现过死机。 将采样次数尽可能降低,简化过程,方便分析问题。在main()函数添几条log,为了判断死在main()中什么位置Log的最后位置是main()--2处,main()--3的log没有出来,说明死在了color()函数中。所以在color()函数中添加如下log。原创 2017-01-14 20:35:14 · 1624 阅读 · 0 评论 -
问题二十四:怎么模拟ray tracing图形中介质材料的颜色(dielectric)
这里的“介质”是指光可以通过的物质。比如,水,玻璃等。也就是我们常说的具有一定透明度的物质。24.1 预备知识24.1.1 反射和折射光线的方向向量 反射光线的方向向量: 漫反射:n + p。其中n为单位法向量,p为“起点在原点,长度小于1,方向随机”的随机向量。 镜面反射:v - 2*dot(v,n)*n。其中n为单位法向量,v原创 2017-01-14 20:49:59 · 2408 阅读 · 4 评论 -
问题二十五:为什么有时候XnView无法显示PPM图片?
25.1 当前问题分析之前在“问题二”中说明过,有截图如下:文件显示不出来,原因肯定是文件格式不对。所有的文件都应包含如下文件头,该文件头的格式如下:P3200 100255没见显示不出来,可能的原因:1,RGB值个数未到200*100个2,RGB值个数刚好200*100个,但某个R值、G值或者B值缺失(也就是RGB值出现残疾)3,RGB值不在[原创 2017-01-14 21:02:05 · 1407 阅读 · 0 评论 -
问题二十六:C++全局变量的使用实例
想知道程序多少次来到某个位置。可以这么做:第一步:在当前文件的开头定义一个全局变量counter初始化为0(注意,是全局变脸,不是局部变量,所以不要定义在某函数内部);第二步:在目标位置使用全局变量来计数, counter ++第三步:在主函数(主函数和之前的全局变量不在同一个文件)所在文件的开头extern之前定义的全局变量;第四步:在主函数快结束的地方将全局变量打印出来即可原创 2017-01-14 21:08:36 · 2538 阅读 · 0 评论 -
问题十七:怎么用ray tracing画多个球?
回忆一下,一个球是怎么画的呢?第一步:光线撞上球。找“撞点”第二步:将“撞点”的像素位置设置为球的颜色。之前采用过两种方式设置颜色:1,简单粗暴,将整个球的颜色设置为红色(return vec3(1, 0, 0));2,将球面上每个像素位置的颜色设置为球在该点的单位法向量的色彩表映射值(每个点的法向量都不一样,所以,每个点的颜色被设置得不一样)。 所以,那么,现在怎么画多个球呢?一原创 2017-01-14 19:11:21 · 1636 阅读 · 2 评论 -
问题二十七:ray traing中的positionable camera
27.1 引入张角theta和宽高比值aspect 回忆一下,“问题十二”中有介绍这么一张图。当时是这么说的:已知Z=-1平面上四点的坐标,我们可以求出下面三个值。 vec3 lower_left_corner(-2.0, -1.0, -1.0); vec3 horizontal(4.0, 0.0, 0.0); vec3 ve原创 2017-01-15 11:51:05 · 1278 阅读 · 2 评论 -
问题二十八:ray tracing中的散焦模糊(defocus blur)
“散焦模糊”在摄影上又称“景深”。在现实的相机中,我们需要做“散焦模糊”的原因是:我们需要一个更大的孔来收集光线增加图片的亮度(而不是“针孔”)。我们称“更大的孔”为“光圈”。For a real camera, if you need more light,you make the aperture bigger, and will get more defocus blur.For原创 2017-01-15 11:59:12 · 6859 阅读 · 1 评论 -
问题二十九:测试ray tracing中camera几个主要参数
camera(vec3 lookfrom, vec3 lookat, vec3vup, float vfov, float aspect, float aperture, float focus_dist)我们相机当前的构造函数的参数有这么七个:vec3 lookfrom:相机的位置vec3 lookat:目标物体的位置vec3 vup:相机的倾斜方向(一般设置为(0,1,0))原创 2017-01-15 12:08:16 · 1438 阅读 · 2 评论 -
问题三十:《Ray Tracing In One Weekend》封面图形生成
30.1 封面图片先完成封面图片。Code如下:----------------------------------------------main.cpp------------------------------------------main.cpp hitable *random_scene() { int n = 500; hit原创 2017-01-15 12:32:22 · 3456 阅读 · 3 评论 -
问题三十一:ray tracing中Convex Quadrilateral Inverse Mapping
从这一章节开始,主要是学习《An Introduction to Ray Tracing》光线和多边形相交问题的求解:1,光线和多边形所在的平面相交,求出交点;2,判断交点是否在多边形内;3,交点在多边形的什么位置(相对于多边形的边)。 前面两步分别在“2.3.1 Ray/Plane Intersection”和“2.3.2 PolygonIntersectio原创 2017-01-15 12:40:25 · 981 阅读 · 0 评论 -
问题三十二:怎么用ray tracing画多边形(polygon, triangle)
画多边形主要分为两步:1,光线和多边形所在的平面相交,求得交点;2,判断交点是否在多边形内; 32.1 光线和多边形所在的平面相交分别定义光线、多边形和多边形所在平面。光线和平面的方程如下:(注意:用到法向量的地方一般都将其标准化。尽管有时候没有必要,但是在某些公式或算法中只能使用标准法向量(而不是法向量)。所以,为了避免特别记忆,统一都进行标准化。) 光线方程:原创 2017-01-15 12:57:03 · 1887 阅读 · 1 评论 -
问题三十三:怎么用ray tracing画特殊长方体(box)
33.1 怎么用ray tracing画特殊长方体在光线追踪中被用到的一种常见形态是长方体盒子。这种基本物体被用于可见物体和包围盒,包围盒被用于加速复杂物体的相交测试。吐槽:单词都认识,就是不知道讲的是什么。“包围盒”是什么鬼?不懂!不过感觉好像很厉害的样子。表面法向量和坐标轴平行的长方体是最简单的形式之一。 我们先就画“表面法向量和坐标轴平行”的长原创 2017-01-15 13:23:06 · 1856 阅读 · 0 评论 -
问题三十四:怎么用ray tracing画任意长方体(generalized box)
34.1 思路分析这个内容书上没有,但是觉得实际应用中的长方体的位置应该是任意的(表面法向量不一定平行坐标轴)。怎么画?1,光线撞击到长方体2,撞击点到光线起点的距离3,撞击点的法向量 怎么确定空间中任意个长方体? 对于前下边的方向向量u(Xu, Yu, Zu)不平行于ZOX平面(即Yu不等于零)的情况:以下六个参数可以确定唯一的空间长方体。原创 2017-01-15 13:35:46 · 1079 阅读 · 4 评论 -
问题三十五: 怎么用ray tracing画二次曲面(quadratic surfaces)(1)——椭球面
二次曲面包括:球面、椭圆球面、单页双曲面、双页双曲面、椭圆锥面、椭圆柱面、椭圆抛物面、双曲抛物面等等。注意到:只有球面和椭球面是封闭面,其他的都是开放面。二次曲面是有方程的(我们已经学过的多边形、长方体等是没有方程的),所以其画法应该要比多边形和长方体要简单。思路是这样的:1,联立曲面方程和光线方程。判断光线是否撞击曲面;求得撞击点到光线起点的距离t;2,将t代入光线方原创 2017-01-15 14:22:30 · 1147 阅读 · 4 评论 -
问题三十五: 怎么用ray tracing画二次曲面(quadratic surfaces)(2)——单页双曲面、双页双曲面、椭圆锥面、椭圆柱面
35.2.1 数学推导单页双曲面、双页双曲面、椭圆锥面、椭圆柱面。这四个二次曲面方程共同形式:但是,注意到,这些曲面都是开放曲面。在画图时,需要限制曲面的范围(以免曲面覆盖整个画面)。我们在这里是限制曲面在y轴方向距离中心点的长度为height_y(引入该参数)。所以,我们可以在根据实根t求得交点坐标后,对交点坐标作如下判断:((re原创 2017-01-15 14:41:03 · 2879 阅读 · 2 评论 -
问题三十五: 怎么用ray tracing画二次曲面(quadratic surfaces)(3)——椭球抛物面
35.3 椭球抛物面35.3.1 数学推导椭球抛物面的方程如下:所以,其一:我们需要对两个实根进行排序(先处理小的) 另外,由于,是开放曲面,也就是,光线有可能撞击到曲面的正反两面,所以,对于撞击点处的标准化之后的法向量,我们需要做如下判断: if (dot(rec.normal,r.directio原创 2017-01-15 15:00:24 · 786 阅读 · 0 评论