39.1 数学推导

书上这么说:

39.2 看C++代码实现

----------------------------------------------tori.h------------------------------------------

tori.h

#ifndef TORI_H
#define TORI_H#include <hitable.h>class tori : public hitable
{public:tori() {}tori(vec3 cen, float ra, float rb, material *m) : center(cen), radius_a(ra), radius_b(rb), ma(m) {}virtual bool hit(const ray& r, float tmin, float tmax, hit_record& rec) const;vec3 center;float radius_a;float radius_b;material *ma;
};#endif // TORI_H

----------------------------------------------tori.cpp------------------------------------------

tori.cpp


#include "tori.h"
#include <iostream>
using namespace std;bool tori::hit(const ray& r, float t_min, float t_max, hit_record& rec) const {vec3 oc = r.origin() - center;float a4 = dot(r.direction(), r.direction()) * dot(r.direction(), r.direction());float a3 = 4*(dot(oc, r.direction())) * dot(r.direction(), r.direction());float a2 = 2*dot(r.direction(), r.direction()) * (dot(oc, oc) - (radius_a*radius_a+radius_b*radius_b))+ 2*(dot(oc, r.direction()))- 4*radius_a*radius_a*r.direction().z()*r.direction().z();float a1 = 4*dot(oc, r.direction())*(dot(oc, oc) - (radius_a*radius_a+radius_b*radius_b))- 8*radius_a*radius_a*oc.z()*r.direction().z();float a0 = (dot(oc, oc) - (radius_a*radius_a+radius_b*radius_b))                    - 4*radius_a*radius_a*(radius_b*radius_b-oc.z()*oc.z());float *roots = roots_quartic_equation(a4, a3, a2, a1, a0);float temp;if (roots[0] > 0.0001) {for (int i=1; i<int(roots[0]); i++) {for (int j=i+1; j<int(roots[0])+1; j++) {if (roots[i] > roots[j]) {temp = roots[i];roots[i] = roots[j];roots[j] = temp;}}}for (int k=1; k<int(roots[0])+1; k++) {if (roots[k] < t_max && roots[k] > t_min) {rec.t = roots[k];rec.p = r.point_at_parameter(rec.t);vec3 pc = rec.p - center;float nx = 4*pc.x()*pc.x()*pc.x() + 4*pc.x()*(pc.y()*pc.y()+pc.z()*pc.z()-(radius_a*radius_a+radius_b*radius_b));float ny = 4*pc.y()*pc.y()*pc.y() + 4*pc.y()*(pc.x()*pc.x()+pc.z()*pc.z()-(radius_a*radius_a+radius_b*radius_b));float nz = 4*pc.z()*pc.z()*pc.z() + 4*pc.z()*(pc.x()*pc.x()+pc.y()*pc.y()+radius_a*radius_a-radius_b*radius_b);rec.normal = unit_vector(vec3(nx, ny, nz));if(dot(r.direction(), rec.normal) > 0) {rec.normal = - rec.normal;}rec.mat_ptr = ma;rec.u = -1.0;rec.v = -1.0;delete [] roots;return true;}}}delete [] roots;return false;
}

----------------------------------------------main.cpp------------------------------------------

main.cpp

        hitable *list[2];list[0] = new sphere(vec3(0.0,-100,0), 100, new lambertian(vec3(0.8, 0.8, 0.0)));list[1] = new tori(vec3(0, 3.0, 0), 2.5, 0.5, new lambertian(vec3(1.0, 0.5, 0.5)));hitable *world = new hitable_list(list,2);vec3 lookfrom(0, 3, 5);vec3 lookat(0, 3, 0);float dist_to_focus = (lookfrom - lookat).length();float aperture = 0.0;camera cam(lookfrom, lookat, vec3(0,1,0), 80, float(nx)/float(ny), aperture, 0.7*dist_to_focus);

输出图片如下:

我只是想问问:这是什么鬼???

39.3 修改书上错误

查来查去,算来算去。发现是书上对一元四次方程的系数算错了。坑爹啊!!!

书上给的是这个:

实际应该是这个:

对应代码修改如下:

float a4 = dot(r.direction(), r.direction()) * dot(r.direction(),r.direction());

float a3 = 4*(dot(oc, r.direction())) *dot(r.direction(), r.direction());

float a2 = 2*dot(r.direction(), r.direction()) * (dot(oc, oc) -(radius_a*radius_a+radius_b*radius_b))

+ 4*(dot(oc,r.direction()))*(dot(oc, r.direction()))

+4*radius_a*radius_a*r.direction().z()*r.direction().z();

float a1 = 4*dot(oc, r.direction())*(dot(oc,oc) - (radius_a*radius_a+radius_b*radius_b))

+8*radius_a*radius_a*oc.z()*r.direction().z();

float a0 = (dot(oc, oc) - (radius_a*radius_a+radius_b*radius_b))*(dot(oc, oc) - (radius_a*radius_a+radius_b*radius_b))

-4*radius_a*radius_a*(radius_b*radius_b-oc.z()*oc.z());

修改后输出图片如下:

哦啦~第一张圆环图片应该正常了……

再来一张:

        hitable *list[2];list[0] = new tori(vec3(0, 3.4, 0), 3.2, 0.2, new lambertian(vec3(0.0, 1.0, 0.0)));list[1] = new tori(vec3(0, 4.9, 0), 1.3, 0.2, new lambertian(vec3(1.0, 0.0, 0.0)));hitable *world = new hitable_list(list,2);vec3 lookfrom(0, 3, 5);vec3 lookat(0, 3, 0);float dist_to_focus = (lookfrom - lookat).length();float aperture = 0.0;camera cam(lookfrom, lookat, vec3(0,1,0), 80, float(nx)/float(ny), aperture, 0.7*dist_to_focus);

输出图片如下:

等等……等等……中间那个白色夹杂着红色的圈是什么鬼???

问题三十九:怎么用ray tracing画圆环相关推荐

  1. 问题三十三:怎么用ray tracing画特殊长方体(box)

    33.1 怎么用ray tracing画特殊长方体 在光线追踪中被用到的一种常见形态是长方体盒子.这种基本物体被用于可见物体和包围盒,包围盒被用于加速复杂物体的相交测试. 吐槽:单词都认识,就是不知道 ...

  2. 问题二十九:测试ray tracing中camera几个主要参数

    camera(vec3 lookfrom, vec3 lookat, vec3vup, float vfov, float aspect, float aperture, float focus_di ...

  3. 问题五十:怎么用ray tracing画blobs

    这一节,画这个: 参考文献: Blinn, J.F., A generalization of algebraic surfacedrawing. ACM Trans. Graph. 1(3) , 2 ...

  4. 问题六十:怎么用ray tracing画回旋体(rotational sweeping / revolution)

    60.1 概述 回旋体,大概是长这个样子: 回旋体是指曲线(称为"基本曲线")围绕y轴转一圈得到的图形. (基本曲线是由多段b-spline曲线段连接而成) 这里先强调一下: 上图 ...

  5. NeHe OpenGL第三十九课:物理模拟

    NeHe OpenGL第三十九课:物理模拟 物理模拟简介: 还记得高中的物理吧,直线运动,自由落体运动,弹簧.在这一课里,我们将创造这一切.   物理模拟介绍 如果你很熟悉物理规律,并且想实现它,这篇 ...

  6. Python编程基础:第三十九节 面向对象编程Object Oriented Programming

    第三十九节 面向对象编程Object Oriented Programming 前言 实践 前言 到目前为止我们都是函数式编程,也即将每一个功能块写为一个函数.其实还有一种更常用的编程方式被称为面向对 ...

  7. javaweb学习总结(三十九)——数据库连接池

    javaweb学习总结(三十九)--数据库连接池 一.应用程序直接获取数据库连接的缺点 用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长.假设网站一天10 ...

  8. 三十九、Java集合中的HashSet和TreeSet

    @Author:Runsen @Date:2020/6/6 作者介绍:Runsen目前大三下学期,专业化学工程与工艺,大学沉迷日语,Python, Java和一系列数据分析软件.导致翘课严重,专业排名 ...

  9. WPF,Silverlight与XAML读书笔记第三十九 - 可视化效果之3D图形

    原文:WPF,Silverlight与XAML读书笔记第三十九 - 可视化效果之3D图形 说明:本系列基本上是<WPF揭秘>的读书笔记.在结构安排与文章内容上参照<WPF揭秘> ...

最新文章

  1. ARM 命名规则、架构
  2. JavaScript 的性能优化:加载和执行
  3. 思维模型篇:四大战略分析工具
  4. 【SQLSERVER】SQL SERVER 2008筛选表报错
  5. 机器视觉:光源专业词汇中英文详解
  6. html css字幕滚动代码,纯CSS实现滚动3D字幕
  7. 2. crontab 的使用
  8. 服务价格实惠的Andr​​oid游戏开发公司
  9. sam卡和sim卡区别_PSAM卡、SAM卡与SIM卡
  10. python算法 之 猜词游戏
  11. 状态模式——你若安好,便是晴天
  12. 西北工业大学遭到境外网络攻击,调查报告二发布
  13. 2019,我的工作寻找之路
  14. html制作简单框架网页 实现自己的音乐驿站 操作步骤及源文件下载 (播放功能限mp3文件)
  15. crmeb打通版开源微信公众号小程序商城框架源码
  16. Ember恶意软件数据集的使用教程
  17. 局域网socket传输视频流
  18. 关于特征值特征向量和矩阵分解的理解总结
  19. 光照模型-兰伯特光照模型
  20. 巴别塔圣经_承认巴别塔

热门文章

  1. Android如何使用WebView访问https的网站
  2. 循环变量到底应该使用int还是unsigned int?
  3. Iptables详解之iptables命令的参数
  4. SSMS 2005 连接 SQL SERVER 2008问题
  5. [转摘]使用异步方式调用同步方法
  6. Matlab之矩阵行列式、秩、迹的求解
  7. latex 设置pdf的页边距
  8. 【转】Linux zip解压/压缩并指定目录
  9. iOS下JS和原生交互,函数互调
  10. C++中的struct与class继承方式