日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

问题三十五: 怎么用ray tracing画二次曲面(quadratic surfaces)(2)——单页双曲面、双页双曲面、椭圆锥面、椭圆柱面

發(fā)布時(shí)間:2024/1/18 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 问题三十五: 怎么用ray tracing画二次曲面(quadratic surfaces)(2)——单页双曲面、双页双曲面、椭圆锥面、椭圆柱面 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

35.2.1 數(shù)學(xué)推導(dǎo)

單頁(yè)雙曲面、雙頁(yè)雙曲面、橢圓錐面、橢圓柱面。

這四個(gè)二次曲面方程共同形式:





但是,注意到,這些曲面都是開(kāi)放曲面。在畫(huà)圖時(shí),需要限制曲面的范圍(以免曲面覆蓋整個(gè)畫(huà)面)。

我們?cè)谶@里是限制曲面在y軸方向距離中心點(diǎn)的長(zhǎng)度為height_y(引入該參數(shù))。

所以,我們可以在根據(jù)實(shí)根t求得交點(diǎn)坐標(biāo)后,對(duì)交點(diǎn)坐標(biāo)作如下判斷:

((rec.p.y()-center.y()) >-height_half_y) && ((rec.p.y()-center.y()) < height_half_y)

?

這里,要特別注意

之前,球面的處理方式是:


所以,其一:我們需要對(duì)兩個(gè)實(shí)根進(jìn)行排序(先處理小的)

?

另外,由于,是開(kāi)放曲面,也就是,光線有可能撞擊到曲面的正反兩面,所以,對(duì)于撞擊點(diǎn)處的標(biāo)準(zhǔn)化之后的法向量,我們需要做如下判斷:

??????????????????????? if (dot(rec.normal,r.direction()) > 0) {

??????????????????????????? rec.normal =-rec.normal;

??????????????????????? }//(法向量決定著反射光線和折射光線)

?

還有,由于我們引入了height_y參數(shù)來(lái)限制曲面的高度,但是,我們要注意到:小實(shí)根對(duì)應(yīng)的交點(diǎn)超出高度范圍時(shí)(之前的一貫做法:小根不在t_mint_max范圍,就直接return false),大實(shí)根是有可能在高度范圍的(而且,如果在范圍的話,光線撞擊的曲面的內(nèi)表面,這時(shí)的法向量是需要反向的)。


35.2.2 看C++代碼實(shí)現(xiàn)

----------------------------------------------quadratic.h ------------------------------------------

quadratic.h

?

#ifndef QUADRATIC_H #define QUADRATIC_H#include <hitable.h> #include "material.h" #include "log.h"class quadratic : public hitable {public:quadratic() {}quadratic(vec3 cen, float a, float b, float c, int s1, int s2, int hy, material *m) : center(cen), intercept_x(a), intercept_y(b), intercept_z(c), sign1(s1), sign2(s2), height_half_y(hy), ma(m) {} /* (x-xc)^2/a^2 + s1*(y-yc)^2/b^2 + (z-zc)^2/c^2 = s2 s1= -1,s2= 1: hyperboloid of one sheet s1= -1,s2= -1: hyperboloid of two sheets s1= -1,s2= 0: elliptic cone s1= 0,s2= 1: elliptic cylinder */virtual bool hit(const ray& r, float tmin, float tmax, hit_record& rec) const;vec3 center;float intercept_x;float intercept_y;float intercept_z;int sign1, sign2, height_half_y;material *ma; };#endif // QUADRATIC_H

----------------------------------------------quadratic.cpp ------------------------------------------

quadratic.cpp

?

#include "quadratic.h"#include <iostream> using namespace std;bool quadratic::hit(const ray& r, float t_min, float t_max, hit_record& rec) const {float ab_square = intercept_x*intercept_x*intercept_y*intercept_y;float bc_square = intercept_y*intercept_y*intercept_z*intercept_z;float ac_square = sign1*intercept_x*intercept_x*intercept_z*intercept_z;float abc_square = sign2*intercept_x*intercept_x*intercept_y*intercept_y*intercept_z*intercept_z;vec3 inter_square = vec3(bc_square, ac_square, ab_square);vec3 rd_square = vec3(r.direction().x()*r.direction().x(),r.direction().y()*r.direction().y(),r.direction().z()*r.direction().z());float A = dot(inter_square, rd_square);vec3 r0_c = r.origin() - center;vec3 r0_c_rd = vec3(r0_c.x()*r.direction().x(),r0_c.y()*r.direction().y(),r0_c.z()*r.direction().z());float B = 2*dot(r0_c_rd, inter_square);vec3 r0_c_square = vec3(r0_c.x()*r0_c.x(),r0_c.y()*r0_c.y(),r0_c.z()*r0_c.z());float C = dot(r0_c_square, inter_square) - abc_square;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)) {pc = rec.p - center;rec.normal = unit_vector(vec3(2*bc_square*pc.x(), 2*ac_square*pc.y(), 2*ab_square*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 temp2temp = temp1;temp1 = temp2;temp2 = temp;} /*對(duì)兩個(gè)實(shí)根進(jìn)行排序,t1<t2,先處理t1*/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)) {//限制曲面的高度pc = rec.p - center;rec.normal = unit_vector(vec3(2*bc_square*pc.x(), 2*ac_square*pc.y(), 2*ab_square*pc.z()));/*任何時(shí)候,都最好將法向量進(jìn)行標(biāo)準(zhǔn)化*/if (dot(rec.normal, r.direction()) > 0) {rec.normal = -rec.normal;} /*如果光線和前面內(nèi)表面相交,需要將法向量反向*/rec.mat_ptr = ma;return true;}else { // return false; /*這里要特別注意,一個(gè)實(shí)根不在高度范圍內(nèi),不能直接return false,還需在判斷另一個(gè)實(shí)根*/}}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)) { pc = rec.p - center;rec.normal = unit_vector(vec3(2*bc_square*pc.x(), 2*ac_square*pc.y(), 2*ab_square*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[5];list[0] = new sphere(vec3(0.0,-100.5,-1), 100, new lambertian(vec3(0.8, 0.8, 0.0)));list[1] = new quadratic(vec3(-2.5, 1.5, 0), 0.5, 0.7, 1, -1, 1, 1, new lambertian(vec3(0.0, 0.1, 0.5)));list[2] = new quadratic(vec3(-0.4, 1.5, 0), 0.15, 0.2, 0.2, -1, -1, 1, new lambertian(vec3(0.3, 0.1, 0.5)));list[3] = new quadratic(vec3(1.2, 1.5, 0), 0.5, 0.7, 1, -1, 0, 1, new lambertian(vec3(0.6, 0.1, 0.5)));list[4] = new quadratic(vec3(2.8, 1.5, 0), 0.5, 0.7, 1, 0, 1, 1, new lambertian(vec3(0.9, 0.1, 0.5)));hitable *world = new hitable_list(list,5);vec3 lookfrom(0,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);

輸出圖片:


從左到右依次是:單頁(yè)雙曲面、雙頁(yè)雙曲面、橢圓錐面、橢圓柱面



總結(jié)

以上是生活随笔為你收集整理的问题三十五: 怎么用ray tracing画二次曲面(quadratic surfaces)(2)——单页双曲面、双页双曲面、椭圆锥面、椭圆柱面的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。