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

类声明:

#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. HMS Core AR Engine 2D图片/3D物体跟踪技术 助力打造更智能AR交互体验

    AR技术已经被广泛应用于营销.教育.游戏.展览等场景.通过2D图像跟踪技术和3D物体跟踪技术,用户只需使用一台手机进行拍摄,即可实现海报.卡牌等平面物体以及文物.手办等立体物体的AR效果.尽管近年来2 ...

  2. 负载均衡之keepalived

    DR实验存在的隐患 DR可能会挂,单点故障 RS可能会挂 解决方案: 解决单点故障 主备:准备多个DR备用机,做好配置,主机挂掉备用机顶上 主主 解决RS会挂的问题 给RS发送请求,如果收到200 o ...

  3. 【Azure 存储服务】Java Azure Storage SDK V12使用Endpoint连接Blob Service遇见 The Azure Storage endpoint url is malformed

    问题描述 使用Azure Storage Account的共享访问签名(Share Access Signature) 生成的终结点,连接时遇见  The Azure Storage endpoint ...

  4. String、StringBuilder、StringBuffer——JavaSE基础

    String.StringBuilder.StringBuffer String不可变 StringBuilder与StringBuffer均可变 StringBuilder线程不安全,效率高,常用 ...

  5. 【SpringSecurity系列1】基于SpringSecurity实现前后端分离无状态Rest API的权限控制

    源码传送门: https://github.com/ningzuoxin/zxning-springsecurity-demos/tree/master/01-springsecurity-state ...

  6. 线程安全性-原子性之Atomic包

    先了解什么是线程安全性:当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些进程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称为这个类是线程 ...

  7. camunda如何调用HTTP REST(Service Task)服务节点

    ​ Camunda中的Service Task(服务任务)用于调用服务.在Camunda中,可以通过调用本地Java代码.外部工作项.web服务形式实现的逻辑来完成的. 本文重点描述如何使用web服务 ...

  8. 【Spring】AOP实现原理(二):Advisor获取

    @EnableAspectJAutoProxy @EnableAspectJAutoProxy注解可以用来开启AOP,那么就从@EnableAspectJAutoProxy入手学习一下Spring A ...

  9. 26.MySQL数据库基础

    MySQL数据库基础 目录 MySQL数据库基础 数据库的概念 数据 表 数据库 数据库的管理系(DBMS) 数据库系统 访问数据库的流程 数据库系统发展史 当今主流数据库介绍 关系数据库 关系数据库 ...

  10. 基于SqlSugar的开发框架循序渐进介绍(9)-- 结合Winform控件实现字段的权限控制

    字段的权限控制,一般就是控制对应角色人员对某个业务对象的一些敏感字段的可访问性:包括可见.可编辑性等处理.本篇随笔结合基于SqlSugar的开发框架进行的字段控制管理介绍. 在设计字段权限的时候,我们 ...