问题二十五:为什么有时候XnView无法显示PPM图片?
来源:互联网 发布:mac 安装apache 编辑:程序博客网 时间:2024/06/06 07:18
25.1 当前问题分析
之前在“问题二”中说明过,有截图如下:
文件显示不出来,原因肯定是文件格式不对。
所有的文件都应包含如下文件头,该文件头的格式如下:
P3
200 100
255
没见显示不出来,可能的原因:
1,RGB值个数未到200*100个
2,RGB值个数刚好200*100个,但某个R值、G值或者B值缺失(也就是RGB值出现残疾)
3,RGB值不在[0,255]之间,可能是因为值溢出而出现负数。
25.2 在学习“问题四十六(superellipsoid)”时,添加本章节如下内容:
当像素点的值溢出时,其值输出为:
-2147483648 -2147483648 -2147483648
若某个变量x的值出现溢出,则该值在程序中表示为“nan(Not a Number)”,怎么判断x的值是否溢出呢?
If (x != x) {
//表示x值溢出,即为nan
}
或者:
If(isnan(x)) {
//表示x值溢出,即为nan
}
这条语句经常用于设置断点,在x值溢出时拦截程序,从而可以查看断点处程序的状态。
接下来我们在程序中反推是什么原因导致像素点的值出现溢出的:
main():
col += color(r, world, 0);
color():
return (1.0-t)*vec3(1.0,1.0, 1.0) + t*vec3(0.5, 0.7, 1.0);//white, light blue
float t = 0.5*(unit_direction.y()+ 1.0);
vec3 unit_direction = unit_vector(r.direction());
传入color()函数的光线有两种情况:其一,原始光线;其二,反射/折射光线
对于第一种情况:一般不会出错。对应main()函数中的如下代码:
float u = float(i + random)/ float(nx);
float v = float(j + random)/ float(ny);
ray r = cam.get_ray(u, v);
对于第二种情况:
color():
return attenuation*color(scattered, world,depth+1);
if (depth < 50 && rec.mat_ptr->scatter(r, rec, attenuation, scattered)) {
反射/折射光线是在对应的材料类的scatter()成员方法返回来的。下面我们分别看看
lambertian::scatter():
scattered =ray(rec.p, target-rec.p);
vec3 target =rec.p + rec.normal +random_in_unit_sphere();
metal::scatter():
scattered = ray(rec.p, reflected + fuzz*random_in_unit_sphere());
vec3 reflected= reflect(unit_vector(r_in.direction()), rec.normal);
dielectric::scatter():既有反射,也有折射:
反射:
scattered = ray(rec.p, reflected);
vec3 reflected= reflect(r_in.direction(), rec.normal);
折射:
scattered = ray(rec.p, refracted);
if (refract(r_in.direction(),outward_normal, ni_over_nt, refracted)) {
bool refract(const vec3& v, constvec3& n, floatni_over_nt, vec3& refracted) {
float dt = dot(uv, n);
refracted = ni_over_nt*(uv - n*dt) - n*sqrt(discriminat);
if(refract(r_in.direction(), outward_normal,ni_over_nt, refracted)) {
outward_normal = rec.normal;
如上,不管是什么材料,最终导致像素点的值溢出的是撞击点处的法向量normal的值。
这里以superellipsoid类为例,到其对应的hit()函数中看看normal的值的来源:
superellipsoid::hit():
rec.normal =unit_vector(vec3(nx,ny,nz));
nx = (p_e2/p_e1) * (pow((pow(fabs(pc.x()/intercept_x),(2/p_e2)) +
pow(fabs(pc.z()/intercept_z), (2/p_e2))), (p_e2/p_e1-1))) *
(2/p_e2)*(pow(fabs(pc.x()/intercept_x),(2/p_e2-1)))/intercept_x;
ny = (2/p_e1)*(pow(fabs(pc.y()/intercept_y),
(2/p_e1-1)))/intercept_y;
nz = (p_e2/p_e1) * (pow((pow(fabs(pc.x()/intercept_x),(2/p_e2)) +
pow(fabs(pc.z()/intercept_z), (2/p_e2))), (p_e2/p_e1-1))) *
(2/p_e2)*(pow(fabs(pc.z()/intercept_z),(2/p_e2-1)))/intercept_z;
从这里可以看到,可能导致nx,ny,nz值溢出的是pow()函数计算的值超出数据类型的范围(1,当指数为小数时,底数为负;2,底数为0;3,底数绝对值大于1,指数很大,然后求幂后超出数据类型能够表示的最大值)
25.3 单独分析pow()函数
从C++ Reference官网获知:
If the base is finite negative and the exponent is finite but not an integer value, it causes a domain error. 潜在错误一:底数为负时,指数为小数
If both base and exponent are zero, it may also cause a domain error on certain implementations.
If base is zero and exponent is negative, it may cause a domain error or a poleerror (or none, depending onthe library implementation). 潜在错误二:底数为0
The function may also cause a range error if the result is too great or toosmall to be represented by a value of the return type. 潜在错误三:计算结果超出数据类型范围
应对这三个潜在错误的措施:
1,单独考虑底数为负的情况,比如:
if (pc.x() < 0) {d_a1 = -intercept_x;} if (pc.y() < 0) {d_a2 = -intercept_y;} if (pc.z() < 0) {d_a3 = -intercept_z;}
2,单独考虑底数为0的情况,比如:
if (pc.x() == 0) { nx = 0; } else { nx = double(p_r)*pow(double(fabs(pc.x()/d_a1)), double(p_r-1))/double(d_a1); } if (pc.y() == 0) { ny = 0; } else { ny = double(p_s)*pow(double(fabs(pc.y()/d_a2)), double(p_s-1))/double(d_a2); } if (pc.z() == 0) { } else { nz = double(p_t)*pow(double(fabs(pc.z()/d_a3)), double(p_t-1))/double(d_a3); }
3,将数据类型换成double类型,比如(同上)(double类型都溢出了,直接输出报错吧!数值太大了,亲)
- 问题二十五:为什么有时候XnView无法显示PPM图片?
- SDWebImage下载图片有时候无法成功显示出来
- 用xnview批处理图片
- jfreechart图片无法显示问题
- XnView:图片管理的工具
- 用Glide加载图片到Recyclerview中有时候只显示占位图的问题
- JSP img元素无法显示本地图片的问题(二)_根源:spring访问静态资源
- 求助高手:为什么html上背景图片会有时候会显示,有时候不显示?
- 在 Outlook 中,为什么附件有时候显示在邮件正文中,有时候显示在标题中?
- Qt Gif图片无法显示问题(WINDOWS)
- office2007 word 图片无法显示问题
- 解决wiki图片无法显示问题
- office2007 word 图片无法显示问题
- Ie浏览器无法显示png图片问题
- 个别图片IE中无法显示问题
- 解决IE8无法显示本地图片问题
- Qt Gif图片无法显示问题(WINDOWS)
- php for linux 图片无法显示问题
- 感觉自己在做梦1.14
- ArrayList源码分析
- sklearn——朴素贝叶斯分文本分类2
- Linux下Setuid命令!
- 直接插入法排序
- 问题二十五:为什么有时候XnView无法显示PPM图片?
- 图论(三)图的遍历
- 【BS学习】——AJAX基础
- UML之用例图
- Gym - 101102B B. The Little Match Girl 贪心、数论、分步
- Linux--linux tail 命令详解
- 安装python-mysql出现的问题以及解决方法
- shell 编程
- 平面设计大神养成记之PS篇——编辑菜单栏