问题三十五: 怎么用ray tracing画二次曲面(quadratic surfaces)(4)——双曲抛物面(马鞍面)
来源:互联网 发布:python 前端 编辑:程序博客网 时间:2024/06/07 21:51
35.4 双曲抛物面(马鞍面)
35.4.1 数学推导
双曲抛物面的方程如下:
35.4.2 看C++代码实现
---------------------------------------------quadratic_hyperbolic_paraboloid.h ------------------------------------
quadratic_hyperbolic_paraboloid.h
#ifndef QUADRATIC_HYPERBOLIC_PARABOLOID_H#define QUADRATIC_HYPERBOLIC_PARABOLOID_H#include <hitable.h>class quadratic_hyperbolic_paraboloid : public hitable{ public: quadratic_hyperbolic_paraboloid() {} quadratic_hyperbolic_paraboloid(vec3 cen, float p, float q, int hy, int wx, material *m) : center(cen), focus_directrix_p(p), focus_directrix_q(-q), height_half_y(hy), width_x(wx), ma(m) {}/*(x-xc)^2/2*p + (z-zc)^2/2*q = (y-yc)(p>0, q>0)*/ virtual bool hit(const ray& r, float tmin, float tmax, hit_record& rec) const; vec3 center; float focus_directrix_p; float focus_directrix_q; int height_half_y, width_x; material *ma;};#endif // QUADRATIC_HYPERBOLIC_PARABOLOID_H
-------------------------------------------quadratic_hyperbolic_paraboloid.cpp ----------------------------------
quadratic_hyperbolic_paraboloid.cpp
#include "quadratic_hyperbolic_paraboloid.h"#include <iostream>using namespace std;bool quadratic_hyperbolic_paraboloid::hit(const ray& r, float t_min, float t_max, hit_record& rec) const { float A = focus_directrix_q*r.direction().x()*r.direction().x() + focus_directrix_p*r.direction().z()*r.direction().z(); float B = 2*focus_directrix_q*r.direction().x()*(r.origin().x()-center.x()) + 2*focus_directrix_p*r.direction().z()*(r.origin().z()-center.z()) - 2*focus_directrix_p*focus_directrix_q*r.direction().y(); float C = focus_directrix_q*(r.origin().x()-center.x())*(r.origin().x()-center.x()) + focus_directrix_p*(r.origin().z()-center.z())*(r.origin().z()-center.z()) - 2*focus_directrix_p*focus_directrix_q*(r.origin().y()-center.y()); float temp, temp1, temp2; vec3 pc; if(A == 0) { if (B == 0) { return false; } else { temp = -C/B; if (temp < t_max && temp > t_min) { rec.t = temp; rec.p = r.point_at_parameter(rec.t); if ((((rec.p.y()-center.y()) > -height_half_y) && ((rec.p.y()-center.y()) < height_half_y)) && (((rec.p.x()-center.x()) > -width_x) && ((rec.p.x()-center.x()) < width_x)) ) { pc = rec.p - center; rec.normal = unit_vector(vec3(2*focus_directrix_q*pc.x(), -2*focus_directrix_p*focus_directrix_q, 2*focus_directrix_p*pc.z())); if (dot(rec.normal, r.direction()) > 0) { rec.normal = -rec.normal; } rec.mat_ptr = ma; return true; } else { return false; } } } } else { float discriminant = B*B - 4*A*C; if (discriminant >= 0) { temp1 = (-B - sqrt(discriminant)) / (2.0*A); temp2 = (-B + sqrt(discriminant)) / (2.0*A); if (temp1 > temp2) {//make sure that temp1 is smaller than temp2 temp = temp1; temp1 = temp2; temp2 = temp; } if (temp1 < t_max && temp1 > t_min) { rec.t = temp1; rec.p = r.point_at_parameter(rec.t); if ((((rec.p.y()-center.y()) > -height_half_y) && ((rec.p.y()-center.y()) < height_half_y)) && (((rec.p.x()-center.x()) > -width_x) && ((rec.p.x()-center.x()) < width_x)) ) { pc = rec.p - center; rec.normal = unit_vector(vec3(2*focus_directrix_q*pc.x(), -2*focus_directrix_p*focus_directrix_q, 2*focus_directrix_p*pc.z())); if (dot(rec.normal, r.direction()) > 0) { rec.normal = -rec.normal; } rec.mat_ptr = ma; return true; } else {// return false; } } if (temp2 < t_max && temp2 > t_min) { rec.t = temp2; rec.p = r.point_at_parameter(rec.t); if ((((rec.p.y()-center.y()) > -height_half_y) && ((rec.p.y()-center.y()) < height_half_y)) && (((rec.p.x()-center.x()) > -width_x) && ((rec.p.x()-center.x()) < width_x)) ) { pc = rec.p - center; rec.normal = unit_vector(vec3(2*focus_directrix_q*pc.x(), -2*focus_directrix_p*focus_directrix_q, 2*focus_directrix_p*pc.z())); if (dot(rec.normal, r.direction()) > 0) { rec.normal = -rec.normal; } rec.mat_ptr = ma; return true; } else {// return false; } } } return false; }}
----------------------------------------------main.cpp ------------------------------------------
main.cpp
hitable *list[2]; list[0] = new sphere(vec3(0.0,-100.5,-1), 100, new lambertian(vec3(0.8, 0.8, 0.0))); list[1] = new quadratic_hyperbolic_paraboloid(vec3(0, 1.5, 0), 0.5, 2, 1.5, 2, new lambertian(vec3(0.0, 0.1, 0.5))); hitable *world = new hitable_list(list,2); vec3 lookfrom(2,5,10); vec3 lookat(0,1,0); float dist_to_focus = (lookfrom - lookat).length(); float aperture = 0.0; camera cam(lookfrom, lookat, vec3(0,1,0), 20, float(nx)/float(ny), aperture, 0.7*dist_to_focus);
输出图片:
如果改成这样vec3 lookfrom(5,5,10);,图是这样的:
如果改成这样vec3 lookfrom(10,5,10);,图是这样的:
4 0
- 问题三十五: 怎么用ray tracing画二次曲面(quadratic surfaces)(4)——双曲抛物面(马鞍面)
- 问题三十五: 怎么用ray tracing画二次曲面(quadratic surfaces)(3)——椭球抛物面
- 问题三十五: 怎么用ray tracing画二次曲面(quadratic surfaces)(1)——椭球面
- 问题三十五: 怎么用ray tracing画二次曲面(quadratic surfaces)(5)——汇总
- 问题三十五: 怎么用ray tracing画二次曲面(quadratic surfaces)(2)——单页双曲面、双页双曲面、椭圆锥面、椭圆柱面
- 问题六十三:怎么用ray tracing画sphere sweeping图形(2)——teapot
- 问题五十四:怎么用ray tracing画参数方程表示的曲面(2)—— bezier surface
- 问题五十六:怎么用ray tracing画参数方程表示的曲面(3)—— b-spline surface
- 问题三十二:怎么用ray tracing画多边形(polygon, triangle)
- 问题三十三:怎么用ray tracing画特殊长方体(box)
- 问题三十四:怎么用ray tracing画任意长方体(generalized box)
- 问题四十一:怎么用ray tracing画任意圆柱面(generalized cylinder)
- 问题四十八:怎么用ray tracing画superhyperboloid(超级双曲面)
- 问题四十九:怎么用ray tracing画supertoroid(超级圆环)
- 问题五十三:怎么用ray tracing画参数方程表示的曲面(1)
- 问题六十:怎么用ray tracing画回旋体(rotational sweeping / revolution)
- 问题六十六:怎么用ray tracing画CSG(Constructive Solid Geometry 构造实体几何)图形
- 问题三十六:ray tracing中的Inverse Mapping(5)——圆锥面Inverse Mapping
- 《第一行代码》学习之旅--第一章
- 方法
- 数学归纳法证明任意两个正整数相等(伪命题)
- jdk1.7 环境配置
- Poj 2887 Big String(块状数组)
- 问题三十五: 怎么用ray tracing画二次曲面(quadratic surfaces)(4)——双曲抛物面(马鞍面)
- HDU-1698-Just A Hook (线段树区间修改,区间查询)
- Android微信支付开发
- 3D射线拾取算法揭秘
- NDK编程的一个坑—Arm平台下的类型转换
- leetcode oj java 143. Reorder List
- 四个月的蜕变之单例模式创建线程池和使用
- 《Head First设计模式》-工厂模式C++实现
- python 2-5 如何快速找到多个字典中的(key) viewkeys(集合)/reduce(lambda a,b:a&b,map(d.keys(),[d1,d2])