针孔相机,带旋转,移动等功能。

类声明:

#pragma once
#ifndef __PINHOLE_HEADER__
#define __PINHOLE_HEADER__ #include "camera.h" class Pinhole :public Camera {
public:
Pinhole();
~Pinhole();
Pinhole(const Pinhole& ph);
void set_view_distance(const ldouble a);
void set_zoom(const ldouble factor);
void set_angle(const ldouble deg);
Vector3 ray_direction(const Point3& p) const;
virtual Camera* clone() const;
virtual void render_scene(World& w);
Pinhole& operator=(const Pinhole& ph);
private:
ldouble d, zoom;
};
#endif

类实现:

#include "pch.h"
#include "pinhole.h"
#include "../utilities/world.h"
#include "../utilities/viewplane.h"
#include "../samplers/sampler.h"
#include "../tracers/tracer.h" Pinhole::Pinhole() :Camera(), d(1), zoom(1) {} Pinhole::Pinhole(const Pinhole& ph) : Camera(ph), d(ph.d), zoom(ph.zoom) {} Pinhole::~Pinhole() {} void Pinhole::set_view_distance(const ldouble a) {
d = a;
} void Pinhole::set_zoom(const ldouble factor) {
zoom = factor;
} void Pinhole::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);//绕z轴旋转
} Vector3 Pinhole::ray_direction(const Point3& p) const{
Vector3 dir = p.x * u + p.y * v - w / d;//书中这里是错误的
dir.normalize();
return dir;
} Camera* Pinhole::clone() const {
return new Pinhole(*this);
} void Pinhole::render_scene(World& w) {
ViewPlane vp(w.vp);
Ray ray;
integer depth = 0;
Point3 sp, pp;
w.open_window(vp.hres, vp.vres);
vp.s = 1 / (zoom * vp.s);
ray.o = eye;
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);
color += w.tracer_ptr->trace_ray(ray);
}
color /= vp.nsamples;
color *= exposure_time;
w.display_pixel(r, c, color);
}
} Pinhole& Pinhole::operator=(const Pinhole& ph) {
if (this == &ph)
return *this;
Camera::operator= (ph);
d = ph.d;
zoom = ph.zoom;
return *this;
}

需要修改的World类:

class World {
public:
World();
World(const World& wr);
~World();
void build();
void render();
...
void open_window(const integer hres, const integer vres);
void display_pixel(const integer row, const integer column, const RGBColor& color);
void set_camera(Camera* const cam_ptr);//新加
ViewPlane vp;
Tracer* tracer_ptr;
private:
std::stringstream ss;
std::vector<Geometrics*> objects;
RGBColor backgrd_color;
Camera* camera_ptr;//新加
};

  

实现代码修改:

void World::build() {
vp.set_hres(200);
vp.set_vres(100);
vp.set_sampler(new Hammersley());
vp.sampler->map_to_sphere();
tracer_ptr = new MultiSphere(this);
Geometrics* obj = new Sphere(0, 0.5);
obj->set_color(RGBColor(1, 0, 0));
add_object(obj);
obj = new Sphere(Point3(0, -100.5, 0), 100);
obj->set_color(RGBColor(0, 0, 1));
add_object(obj);
Pinhole* pinhole = new Pinhole();
pinhole->set_eye(Point3(0, 0, 1));
pinhole->set_lookat(Point3(0));
pinhole->set_view_distance(1.5);//视距测试
pinhole->set_angle(-45);//旋转测试
//pinhole->set_zoom(2.0);//缩放测试
pinhole->compute_uvw();
set_camera(pinhole);
} void World::render() {
camera_ptr->render_scene(*this);
}

  

测试效果图(左旋转45度图):

Pinhole类声明和实现的更多相关文章

  1. EC笔记,第二部分:7.为多态基类声明虚析构函数

    7.为多态基类声明虚析构函数 1.为多态基类声明虚析构函数 code1: class A{ public: int* a; A():a(new int(5)) {} ~A(){ delete a; } ...

  2. C++ 中的模板类声明头文件和实现文件分离后,如何能实现正常编译?

    C++ 中的模板类声明头文件和实现文件分离后,如何能实现正常编译? 这个feature叫做Export Template,即外名模板,它的作用在于使得模板代码可依照C/C++语言习惯,将模板声明和实现 ...

  3. [Effective C++ --007]为多态基类声明virtual析构函数

    引言: 我们都知道类的一个很明显的特性是多态,比如我们声明一个水果的基类: class Fruit { public: Fruit() {}; ~Fruit(){}; } 那么我们根据这个Fruit基 ...

  4. c++,基类声明的指针变量和引用类型变量可以指向派 生类的对象

    基类声明的指针变量和引用类型变量可以指向派生类的对象,而反过来派生类的指针却不能指向基类变量. 这与基类和派生类之间,被允许的赋值方向是相反的. 但是从逻辑上很容易推敲其合理性.

  5. error C2248: “CObject::operator =”: 不可访问 private 员(于“CObject”类声明)

    MFC如果编码错误: 演出:error C2248: "CObject::operator =": 不可访问 private 员(于"CObject"类声明) ...

  6. 类声明、类作用域、前向声明、this指针、嵌套类、PIMPL 技法 等

    一.类声明 //类是一种用户自定义类型,声明形式: class 类名称 {    public:              公有成员(外部接口)    private:              私有 ...

  7. C++模板类内友元(友元函数,友元类)声明的三种情况

    根据<C++ Primer>第三版16.4节的叙述,C++类模板友元分为以下几种情况 1.非模板友元类或友元函数. 书上给了一个例子: class Foo{     void bar(); ...

  8. Thinhole类声明和实现

    Thinhole类说白了就是在眼睛处,放一个放大镜.就像我们平时用放大镜观察物体一样.这样实现的效果的是,周围会模糊.原理书上都说的很清楚了,我把算法截图下来了.这个应用我猜测是在竞技游戏比如csgo ...

  9. 07——为多态基类声明为virtual析构函数

    当基类确定被继承的时候,析构函数声明为virtual是必须的 当返回的派生类的指针或引用的时候,调用析构函数容易发生内存泄漏 当基类作为抽象类使用,声明pure virtual析构函数 析构函数的顺序 ...

随机推荐

  1. 一文看懂 ZooKeeper ,面试再也不用背八股(文末送PDF)

    ZooKeeper知识点总结 一.ZooKeeper 的工作机制 二.ZooKeeper 中的 ZAB 协议 三.数据模型与监听器 四.ZooKeeper 的选举机制和流程 本文将以如下内容为主线讲解 ...

  2. 使用ROOT用户运行Jenkins

    !本教程仅适用于以YUM.APT等包管理器安装的Jenkins. 使用ROOT用户运行Jenkins,以保证Jenkins以最高权限执行任务. 注:会存在安全风险! 1.找到Jenkins启动脚本 通 ...

  3. .net6.0 中一个接口多个实现的服务注册与注入

    1.现有一个数据库操作接口 如下   它有两个数据操作实现 Sqlserver 和MySql的数据库操作实现类 现在我们需要 将这个两个类 注册到MVC中 注意这里注册的服务类型都是 IDataBas ...

  4. ASP.NET MVC 处理管线模型

    MVC管道整体处理模型 1.在ASP.NET MVC处理管线中的第一站就是路由模块.当请求到达路由模块后,MVC框架就会根据Route Table中配置的路由模板来匹配当前请求以获得对应的contro ...

  5. STM32 CubeMx使用教程

    一.STM32CubeMX 简介 STM32CubeMX 是 ST 意法半导体近几年来大力推荐的STM32 芯片图形化配置工具,目的就是为了方便开发者, 允许用户使用图形化向导生成C 初始化代码,可以 ...

  6. 直观比较 popcount 的效率差异

    问题 求 \(\sum\limits_{i=1}^{3\times 10^8} popcount(i)\) . 仅考虑在暴力做法下的效率. 枚举位 __builtin_popcount #includ ...

  7. java通过socket实现https get 请求网页

    1. 首先要初始化ssl context SSLContext context = SSLContext.getDefault(); socket = (SSLSocket) context.getS ...

  8. Maven POM文件介绍

    1. POM文件是什么 1.1 Super POM 1.2 Minimal POM 1.3 Effective POM 3. 项目继承 和 项目聚合 2.1 Project Inheritance 项 ...

  9. BUUCTF-BJDCTF2020]just_a_rar

    BJDCTF2020]just_a_rar 压缩包提示是四位数密码 爆破得知压缩包密码 16进制查看解压的图片后发现flag flag{Wadf_123}

  10. sql-DDL-操作数据库与表

    1. 操作数据库:CRUD oracle应该是没有操作数据库的SQL oracl创建数据库通过数据库提供的工具来新建数据库 windows版oracle新建数据库 C(Create):创建 creat ...