问题三十六:ray tracing中的Inverse Mapping(2)——凸四边形(含三角形)Inverse Maping
来源:互联网 发布:msn即时软件 编辑:程序博客网 时间:2024/06/09 01:58
36.2 凸四边形(含三角形)Inverse Maping
36.2.1 数学推导
参考“问题三十一”
36.2.2 看C++代码实现
----------------------------------------------polygon.cpp ------------------------------------------
polygon.cpp
#include "polygon.h"#include "vec2.h"#include "log.h"#include <iostream>#include <fstream>using namespace std;bool in_polygon_test(vec2 *vertexes_uv, int number) { int sh, nsh; int nc = 0; if(vertexes_uv[0].v() < 0) { sh = -1;} else { sh = 1;} for(int j=0; j<number; j++) { if(vertexes_uv[j+1].v() < 0) { nsh = -1;} else { nsh = 1;} if(sh != nsh) { if((vertexes_uv[j].u() > 0) && (vertexes_uv[j+1].u() >0)) { nc++;} else if((vertexes_uv[j].u() > 0) || (vertexes_uv[j+1].u() >0)) { if(vertexes_uv[j].u() - (vertexes_uv[j].v())*(vertexes_uv[j+1].u()-vertexes_uv[j].u())/(vertexes_uv[j+1].v()-vertexes_uv[j].v()) > 0) { nc++;} } } sh = nsh; } if((nc)%(2)) {return true;} else {return false;}}bool in_polygon_test2(vec2 *vertexes_uv, int number) { int sh, nsh; int nc = 0; if(vertexes_uv[0].v() < 0) { sh = -1;} else { sh = 1;} for(int j=0; j<number; j++) { if(vertexes_uv[j+1].v() < 0) { nsh = -1;} else { nsh = 1;} if(sh != nsh) { if((vertexes_uv[j].u() > 0) && (vertexes_uv[j+1].u() >0)) { if(vertexes_uv[j].v() > vertexes_uv[j+1].v()) { nc = nc + 1;} else { nc = nc - 1;} } else if((vertexes_uv[j].u() > 0) || (vertexes_uv[j+1].u() >0)) { if(vertexes_uv[j].u() - (vertexes_uv[j].v())*(vertexes_uv[j+1].u()-vertexes_uv[j].u())/(vertexes_uv[j+1].v()-vertexes_uv[j].v()) > 0) { if(vertexes_uv[j].v() > vertexes_uv[j+1].v()) { nc = nc + 1;} else { nc = nc - 1;} } } } sh = nsh; } if(nc != 0) {return true;} else {return false;}}bool polygon::hit(const ray& r, float t_min, float t_max, hit_record& rec) const { vec3 poly_n; for(int i=0; i<number-2; i++) { poly_n = unit_vector(cross((vertexes[i]-vertexes[i+1]), (vertexes[i+1]-vertexes[i+2])));//determine the normal of the plane if (dot(poly_n, r.direction()) > 0) { poly_n = - poly_n; } if(!vector_equ(poly_n, vec3(0,0,0))) { break; } } float poly_d = -(dot(poly_n, vertexes[0]));//determine the distance from the origin to the plane float vd = dot(poly_n, r.direction()); float v0 = -(dot(poly_n, r.origin()) + poly_d); if(vd == 0) {//the ray is parallel to the polygon plane return false; } else { float t = v0/vd;//determine t and intersection pi vec3 pi = r.point_at_parameter(t); /*find the dominant coordinate, X, Y, or Z? i=1: means that X is the dominant coordinate; i=2: means that Y is the dominant coordinate; i=3: means that Z is the dominant coordinate; */ float temp = abs(poly_n.x()); int i = 1; if(temp <= abs(poly_n.y())) { temp = abs(poly_n.y()); i++; } if(temp <= abs(poly_n.z())) { i++; } /*throw the dorminant coordinate of 3-d vector, then we get 2-d vector in uv-plane*/ vec2 vertexes_uv[number+1]; switch (i) { case 1: for(int i=0; i<number; i++) { vertexes_uv[i] = vec2(vertexes[i].y(),vertexes[i].z()); } vertexes_uv[number] = vec2(pi.y(),pi.z()); break; case 2: for(int i=0; i<number; i++) { vertexes_uv[i] = vec2(vertexes[i].x(),vertexes[i].z()); } vertexes_uv[number] = vec2(pi.x(),pi.z()); break; case 3: for(int i=0; i<number; i++) { vertexes_uv[i] = vec2(vertexes[i].x(),vertexes[i].y()); } vertexes_uv[number] = vec2(pi.x(),pi.y()); break; } /*move intersection uv-coordinate to origin. so all the vertexes substract intersection uv-coordinate.*/ for(int i=0; i<number; i++) { vertexes_uv[i] = vertexes_uv[i] - vertexes_uv[number]; } vertexes_uv[number] = vertexes_uv[0]; //set the first vertex to the last position of the array, so that we get the whole vertexes loop if(in_polygon_test2(vertexes_uv,number)) {//check if the intersection locates inside the polygon or not if (t < t_max && t > t_min) { rec.t = t; rec.p = r.point_at_parameter(rec.t); rec.normal = poly_n; rec.mat_ptr = ma; if (number <= 4) { vec3 p00 = vertexes[0]; vec3 p10 = vertexes[1]; vec3 p11 = vertexes[2]; vec3 p01 = vertexes[0]; if (number == 4) { p01 = vertexes[3]; } vec3 pa = p00-p01+p11-p10; vec3 pb = p10-p00; vec3 pc = p01-p00; vec3 pd = p00; vec3 pn = rec.normal; vec3 na = cross(pa, pn); vec3 nb = cross(pb, pn); vec3 nc = cross(pc, pn); float du0 = dot(nc, pd); float du1 = dot(na, pd) + dot(nc, pb); float du2 = dot(na, pb); float dv0 = dot(nb, pd); float dv1 = dot(na, pd) + dot(nb, pc); float dv2 = dot(na, pc); vec3 pi = rec.p; float Au = du2; float Bu = du1 - dot(na, pi); float Cu = du0 - dot(nc, pi); float Av = dv2; float Bv = dv1 - dot(na, pi); float Cv = dv0 - dot(nb, pi); if (Au == 0) { rec.u = -Cu/Bu; } else { float u_temp = (-Bu + sqrt(Bu*Bu-4*Au*Cu)) / (2*Au); if ((u_temp >= 0) && (u_temp <= 1)) { rec.u = u_temp; } else { rec.u = (-Bu - sqrt(Bu*Bu-4*Au*Cu)) / (2*Au); } } if (Av == 0) { rec.v = -Cv/Bv; } else { float v_temp = (-Bv + sqrt(Bv*Bv-4*Av*Cv)) / (2*Av); if ((v_temp >= 0) && (v_temp <= 1)) { rec.v = v_temp; } else { rec.v = (-Bv - sqrt(Bv*Bv-4*Av*Cv)) / (2*Av); } } } return true; } return false; } return false; }}
----------------------------------------------main.cpp ------------------------------------------
main.cpp
//triangle vec3 vertexes3_1[3]; vertexes3_1[0] = vec3(-6.75, 0.0, 0.0); vertexes3_1[1] = vec3(-4.25, 0.0, 0.0); vertexes3_1[2] = vec3(-5.25, 2.5, 0.0);//quadrilateral1 vec3 vertexes4_1[4]; vertexes4_1[0] = vec3(-6.5, 3.0 ,0.0); vertexes4_1[1] = vec3(-1.5, 3.0 ,0.0); vertexes4_1[2] = vec3(-1.5, 5.5 ,0.0); vertexes4_1[3] = vec3(-6.5, 5.5 ,0.0);//quadrilateral2 vec3 vertexes4_2[4]; vertexes4_2[0] = vec3(-1.25, 3.0 ,0.0); vertexes4_2[1] = vec3(3.75, 3.0 ,0.0); vertexes4_2[2] = vec3(3.0, 5.5 ,0.0); vertexes4_2[3] = vec3(-0.0, 4.0 ,0.0); hitable *list[4]; list[0] = new sphere(vec3(0.0,-100,0), 100, new lambertian(vec3(0.8, 0.8, 0.0))); list[1] = new polygon(vertexes3_1, 3, new lambertian(vec3(0.8, 0.8, 0.0))); list[2] = new polygon(vertexes4_1, 4, new lambertian(vec3(0.8, 0.8, 0.0))); list[3] = new polygon(vertexes4_2, 4, new lambertian(vec3(0.8, 0.8, 0.0))); hitable *world = new hitable_list(list,4); vec3 lookfrom(0, 2.5, 20); vec3 lookat(0, 2.5, 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);
输出图片:
uv原图:
4 0
- 问题三十六:ray tracing中的Inverse Mapping(2)——凸四边形(含三角形)Inverse Maping
- 问题三十六:ray tracing中的Inverse Mapping(1)——球面Inverse Mapping
- 问题三十六:ray tracing中的Inverse Mapping(3)——圆盘Inverse Mapping
- 问题三十六:ray tracing中的Inverse Mapping(4)——圆柱面Inverse Mapping
- 问题三十六:ray tracing中的Inverse Mapping(5)——圆锥面Inverse Mapping
- 问题三十六:ray tracing中的Inverse Mapping(0)——概要
- 问题三十六:ray tracing中的Inverse Mapping(6)——汇总
- 问题三十一:ray tracing中Convex Quadrilateral Inverse Mapping
- 问题六十三:怎么用ray tracing画sphere sweeping图形(2)——teapot
- 《An Introduction to Ray Tracing》——2.2 Ray/Sphere Intersection And Mapping
- 《An Introduction to Ray Tracing》——2.3 Ray/Polygon Intersection And Mapping
- 《An Introduction to Ray Tracing》—— 2.5 Ray/Quadric Intersection And Mapping
- Q78:规则网格(Regular Grids)——Ray Tracing中的一种加速技术
- 问题五十四:怎么用ray tracing画参数方程表示的曲面(2)—— bezier surface
- 问题三十五: 怎么用ray tracing画二次曲面(quadratic surfaces)(1)——椭球面
- 问题三十五: 怎么用ray tracing画二次曲面(quadratic surfaces)(3)——椭球抛物面
- 问题三十五: 怎么用ray tracing画二次曲面(quadratic surfaces)(5)——汇总
- Hibernate---inverse,cascade(2)
- 1月15日的机试
- Android中Adapter接口及其实现类详解
- windows service 2012:[7]搭建FTP服务器
- 使用git提交本地代码到github上
- 在Ubuntu16.04下安装mysql
- 问题三十六:ray tracing中的Inverse Mapping(2)——凸四边形(含三角形)Inverse Maping
- Zabbix_Agent的安装
- oracle 数据库密码修改
- C#电子书 第四章
- LeetCode 247. Strobogrammatic Number II
- Huffman压缩解压器
- C语言知识点
- oracle 11g安装教程完整版
- HTTP Status 500 - java.lang.ClassNotFoundException: org.apache.jsp.WEB_002dINF.jsp.index_jsp