• Fishhole类定义和实现


    当眼睛处于水中,产生类似的鱼眼视角,fov永远是psi_max的2倍。具体算法参考书籍。

    类声明:

    #pragma once
    #ifndef __FISHHOLE_HEADER__
    #define __FISHHOLE_HEADER__
    
    #include "camera.h"
    
    class Fishhole :public Camera {
    public:
    	Fishhole();
    	~Fishhole();
    	Fishhole(const Fishhole& fh);
    	void set_fov(const ldouble fov);
    	void set_angle(const ldouble deg);
    	Vector3 ray_direction(const Point3& pp, const integer hres, const integer vres, const ldouble s, ldouble& r_squared) const;
    	virtual Camera* clone() const;
    	virtual void render_scene(World& w);
    	Fishhole& operator=(const Fishhole& fh);
    private:
    	ldouble psi_max;//fov/2
    };
    #endif
    

      

    类实现:

    #include "pch.h"
    #include "fishhole.h"
    #include "../utilities/world.h"
    #include "../utilities/viewplane.h"
    #include "../samplers/sampler.h"
    #include "../tracers/tracer.h"
    
    Fishhole::Fishhole() :Camera(), psi_max(180) {}
    
    Fishhole::~Fishhole() {}
    
    Fishhole::Fishhole(const Fishhole& fh) : Camera(fh), psi_max(fh.psi_max) {}
    
    void Fishhole::set_fov(const ldouble fov) {
    	psi_max = fov / 2;
    }
    
    void Fishhole::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 Fishhole::ray_direction(const Point3& pp, const integer hres, const integer vres, const ldouble s, ldouble& r_squared) const {
    	Point3 pn(2.0 / (s * hres) * pp.x, 2.0 / (s * vres) * pp.y, 0);
    	r_squared = pn.x * pn.x + pn.y * pn.y;
    	Vector3 dir;
    	if (r_squared <= 1.0) {
    		ldouble r = std::sqrt(r_squared);
    		ldouble psi = r * radian(psi_max);
    		ldouble sin_psi = std::sin(psi), cos_psi = std::cos(psi), sin_alpha = pn.y / r, cos_alpha = pn.x / r;
    		dir = sin_psi * cos_alpha * u + sin_psi * sin_alpha * v - cos_psi * w;
    	}
    	return dir;
    }
    
    Camera* Fishhole::clone() const {
    	return new Fishhole(*this);
    }
    
    void Fishhole::render_scene(World& w) {
    	Ray ray;
    	ViewPlane vp(w.vp);
    	integer depth = 0;
    	Point3 sp, pp;
    	ldouble r_squared;
    	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, r_squared);
    				if (r_squared <= 1.0)
    					color += w.tracer_ptr->trace_ray(ray);
    			}
    			color /= vp.nsamples;
    			color *= exposure_time;
    			w.display_pixel(r, c, color);
    		}
    }
    
    Fishhole& Fishhole::operator=(const Fishhole& fh) {
    	if (this == &fh)
    		return *this;
    	Camera::operator=(fh);
    	psi_max = fh.psi_max;
    	return *this;
    }

    测试效果图(fov是180度):

  • 相关阅读:
    spring aop简单理解
    动态代理
    静态代理
    spring的i o c简单回顾
    java注解的概念理解
    Eclipse中配置Tomcat
    java中Optional和Stream流的部分操作
    java中的stream的Map收集器操作
    java中的二进制运算简单理解
    Class.forName和ClassLoader.loadClass区别(转)
  • 原文地址:https://www.cnblogs.com/dalgleish/p/12651150.html
Copyright © 2020-2023  润新知