此类是一个全景摄像机视角,书上介绍了详细原理。直接给实现代码。

类声明:

#pragma once
#ifndef __SPHERICAL_HEADER__
#define __SPHERICAL_HEADER__ #include "camera.h" class Spherical :public Camera {
public:
Spherical();
~Spherical();
Spherical(const Spherical& sp);
void set_fov(const ldouble hfov, const ldouble vfov);
void set_angle(const ldouble deg);
Vector3 ray_direction(const Point3& pp, const integer hres, const integer vres, const ldouble s) const;
virtual Camera* clone() const;
virtual void render_scene(World& w);
Spherical& operator=(const Spherical& sp);
private:
ldouble lambda_max, psi_max;
};
#endif

类实现:

#include "pch.h"
#include "spherical.h"
#include "../utilities/world.h"
#include "../utilities/viewplane.h"
#include "../samplers/sampler.h"
#include "../tracers/tracer.h" Spherical::Spherical() :Camera(), lambda_max(180), psi_max(180) {} Spherical::~Spherical() {} Spherical::Spherical(const Spherical& sp) : Camera(sp), lambda_max(sp.lambda_max), psi_max(sp.psi_max) {} void Spherical::set_fov(const ldouble hfov, const ldouble vfov) {
lambda_max = hfov / 2;
psi_max = vfov / 2;
} void Spherical::set_angle(const ldouble deg) {
ldouble rad = radian(deg);
up = Point3(std::cos(rad) * up.x - std::sin(rad) * up.y,
std::sin(rad) * up.x + std::cos(rad) * up.y, up.z);
} Vector3 Spherical::ray_direction(const Point3& pp, const integer hres, const integer vres, const ldouble s) const {
Point3 pn(2.0 / (s * hres) * pp.x, 2.0 / (s * vres) * pp.y, 0);
ldouble lambda = pn.x * radian(lambda_max),
psi = pn.y * radian(psi_max);
ldouble phi = M_PI - lambda,
theta = 0.5 * M_PI - psi;
ldouble sin_phi = std::sin(phi), cos_phi = std::cos(phi), sin_theta = std::sin(theta), cos_theta = std::cos(theta);
Vector3 dir = sin_theta * sin_phi * u + cos_theta * v + sin_theta * cos_phi * w;
return dir;
} Camera* Spherical::clone() const {
return new Spherical(*this);
} void Spherical::render_scene(World& w) {
Ray ray;
ViewPlane vp(w.vp);
integer depth = 0;
Point3 sp, pp;
w.open_window(vp.hres, vp.vres);
ray.o = eye;
vp.s = 1 / vp.s;
for (integer r = vp.vres - 1; r >= 0; r--)//render from left-corner to right-corner
for (integer c = 0; c < vp.hres; c++) {
RGBColor color;
for (integer p = 0; p < vp.nsamples; p++) {
sp = vp.sampler->sample_unit_square();
pp.x = (c - 0.5 * vp.hres + sp.x) * vp.s;
pp.y = (r - 0.5 * vp.vres + sp.y) * vp.s;
ray.d = ray_direction(pp, vp.hres, vp.vres, vp.s);
color += w.tracer_ptr->trace_ray(ray);
}
color /= vp.nsamples;
color *= exposure_time;
w.display_pixel(r, c, color);
}
} Spherical& Spherical::operator=(const Spherical& sp) {
if (this == &sp)
return*this;
Camera::operator=(sp);
lambda_max = sp.lambda_max;
psi_max = sp.psi_max;
return *this;
}

测试效果图(等之后加了材质后,再看看效果):

Spherical类定义和实现的更多相关文章

  1. Python笔记——类定义

    Python笔记——类定义 一.类定义: class <类名>: <语句> 类实例化后,可以使用其属性,实际上,创建一个类之后,可以通过类名访问其属性 如果直接使用类名修改其属 ...

  2. 几种常用的JS类定义方法

    几种常用的JS类定义方法   // 方法1 对象直接量var obj1 = {    v1 : "",    get_v1 : function() {        return ...

  3. Js 类定义的几种方式

    提起面向对象我们就能想到类,对象,封装,继承,多态.在<javaScript高级程序设计>(人民邮电出版社,曹力.张欣译.英文名字是:Professional JavaScript for ...

  4. 为什么C++类定义中,数据成员不能被指定为自身类型,但可以是指向自身类型的指针或引用?为什么在类体内可以定义将静态成员声明为其所属类的类型呢 ?

    static的成员变量,不是存储在Bar实例之中的,因而不会有递归定义的问题. 类声明: class Screen: //Screen类的声明 1 类定义: class Screen{ //Scree ...

  5. C++学了这么多年,你也许不知道为什么类定义要放在.h文件,类实现放在cpp文件。它们如何关联?

    原文  http://blog.csdn.net/ithzhang/article/details/8119286 主题 C++  C++学了这么多年你知道为什么定义类时,类的定义放在.h文件中,而类 ...

  6. YTU 2602: 熟悉题型——类设计( 矩形类定义【C++】)

    2602: 熟悉题型--类设计( 矩形类定义[C++]) 时间限制: 1 Sec  内存限制: 128 MB 提交: 183  解决: 119 题目描述 定义一个矩形类,数据成员包括左下角和右上角坐标 ...

  7. Objective-c 类接口 (@interface) (类定义)

    在Objective-c中如何定义一个类呢?我们可以使用下面的格式进行表示: @interface 类名:父类名{ 变量定义; } 方法定义: @end; 下面给出一个实例: @interface P ...

  8. 只能从脚本中调用在类定义上有[ScriptService]属性的Web服务问题的解决方案

    ajax调用webservice中的接口时, 会出现[只能从脚本中调用在类定义上有[ScriptService]属性的...]的异常. 这是因为, 在.net3.5中, 访问web服务, 要对web服 ...

  9. 开涛spring3(12.4) - 零配置 之 12.4 基于Java类定义Bean配置元数据

    12.4  基于Java类定义Bean配置元数据 12.4.1  概述 基于Java类定义Bean配置元数据,其实就是通过Java类定义Spring配置元数据,且直接消除XML配置文件. 基于Java ...

随机推荐

  1. MMDeploy安装笔记

    MMDeploy的TensorRT教程 Step1: 创建虚拟环境并且安装MMDetection conda create -n openmmlab python=3.7 -y conda activ ...

  2. 关于『进击的Markdown』:第二弹

    关于『进击的Markdown』:第二弹 建议缩放90%食用 众里寻他千百度,蓦然回首,Markdown却在灯火灿烂处 MarkdownYYDS! 各位早上好!  我果然鸽稿了  Markdown 语法 ...

  3. Tomcat启动失败:java.lang.NoSuchMethodError: org.apache.tomcat.util.res.StringManager.getManager(Ljava/lang/Class;)Lorg/apache/tomcat/util/res/StringManager

    项目开发中发现服务器上Tomcat启动失败 开始定位 第一步:打开tomcat日志catalina.log: 2017-07-25 17:02:43,799 [Catalina-startStop-1 ...

  4. 用Arduino显示颜色序列(u8g2,OLED)

    目录 用Arduino显示颜色序列(u8g2,OLED) 用Arduino显示颜色序列(u8g2,OLED) 提前祝大家新年快乐! 主控:Arduino Mega 2560 硬件:126×64 OLE ...

  5. wsl2环境搭建

    序言 我电脑配置不高,开虚拟机跑linux总觉得太卡.最近才了解到windows早就上了wsl2--一款较为轻量的虚拟机软件.所以本篇博客偏笔记向,存粹记录以便多次使用. 环境 宿主机windows1 ...

  6. LoRa模块无线收发通信技术详解

    LoRa是一种LPWAN通信技术,它基于扩频技术而广泛应用于超长距离的无线传输场景中.现在,LoRa主要在全世界433.868.915MHz等自由频带工作.其最大特征是灵敏度高,传输距离长,工作功耗低 ...

  7. 数字化转型之数字资产知识库(springboot+es+vue+neo4j)

    前言 在数字化高度普及的时代,企事业机关单位在日常工作中会产生大量的文档,例如医院制度汇编,企业知识共享库等.针对这些文档性的东西,手工纸质化去管理是非常消耗工作量的,并且纸质化查阅难,易损耗,所以电 ...

  8. BUUCTF-snake

    snake 这是我最想吐槽的一个题目,搞这个蛇在这里.我看的这个图就头皮发麻. 最不愿意做的题,建议以后出题能不能搞个正常的啊. 16进制打开发现压缩包,binwalk提取,得到三个文件 key中是b ...

  9. js 表面学习 - 认识结构2

    单行注释以 // 开头. 多行注释以 /* 开头,以 */ 结尾. 任何位于 /* 和 */ 之间的文本都会被 JavaScript 忽略. JavaScript 数据类型 JavaScript 变量 ...

  10. linux中CentOS配置文件编辑错误撤回

    未编辑状态下 U键 撤销 DD 快速删除