针对单个球体的World类
好了,终于到了可以看到图片的环节了。之前的类,你一定要实现好了。所有关于World类的报错,现在我们一个一个解决来了。
先看看World类的声明:
#pragma once
#ifndef __WORLD_HEADER__
#define __WORLD_HEADER__ #include "geometry.h"
#include "viewplane.h"
#include "../objects/primitive/sphere.h"
#include "../tracers/tracer.h" class World {
public:
World();
World(const World& wr);
~World();
void build();//初始化数据
void render();//渲染
void add_object(Geometrics* obj);//添加几何对象
void remove_object(Geometrics* obj);//删除几何对象
integer get_object_size() const;//几何对象个数,这个在SingleSphere类中用到了哈
ShadeRec hit_bare_bones_objects(const Ray& ray);
private:
void open_window(const integer hres, const integer vres);//初始化视窗,有条件的可以用DirectX或者OpenGL显示,我这里用ppm文件显示
void display_pixel(const integer row, const integer column, const RGBColor& color);//写入像素
std::stringstream ss;//缓存
std::vector<Geometrics*> objects;
ViewPlane vp;//视窗类
RGBColor backgrd_color;//背景色
Tracer* tracer_ptr;//光线和几何对象的碰撞
};
#endif
类实现:
#include "pch.h"
#include "world.h"
#include "../tracers/singlesphere.h" World::World():tracer_ptr(nullptr) {} World::~World() {//写入到ppm文件
std::ofstream fout;
fout.open("test.ppm", std::ios::out);
fout.write(ss.str().c_str(), ss.str().size());
fout.close();
} World::World(const World& wr)
: vp(wr.vp), backgrd_color(wr.backgrd_color), tracer_ptr(wr.tracer_ptr) {
objects.clear();
} void World::build() {
vp.set_hres(200);
vp.set_vres(100);//200*100像素图片
tracer_ptr = new SingleSphere(this);
Geometrics* obj = new Sphere(0, 0.5);
obj->set_color(RGBColor(1, 0, 0));//球体颜色是红色
add_object(obj);
} void World::render() {
Ray ray;
ldouble x, y;
open_window(vp.hres, vp.vres);
Point3 sp;
ray.o = Point3(0, 0, 1);//光线源位置
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;
x = vp.s * (c - 0.5 * vp.hres);
y = vp.s * (r - 0.5 * vp.vres);
ray.d = Point3(x, y, -1);//只需要改变光线的方向
color = tracer_ptr->trace_ray(ray);
display_pixel(r, c, color);
}
} void World::add_object(Geometrics* obj) {
objects.push_back(obj);
} void World::remove_object(Geometrics* obj) {
for (auto it = objects.begin(); it != objects.end(); it++)
if ((*it) == obj)
objects.erase(it);
} integer World::get_object_size() const {
return objects.size();
} ShadeRec World::hit_bare_bones_objects(const Ray& ray) {//这个就是经常出现在SingleSphere和MultiSphere类中的函数了
ShadeRec sr(*this);
ldouble t, tmin= std::numeric_limits<ldouble>::max();
for (auto obj : objects)
if (obj->hit(ray, t, sr) && t < tmin) {
sr.hit_an_object = true;
tmin = t;
sr.color = obj->get_color();//保存碰撞后的颜色
}
return sr;
} void World::open_window(const integer hres, const integer vres) {
ss.clear();
ss << "P3\n" << hres << " " << vres << "\n255\n";//ppm文件头
} void World::display_pixel(const integer row, const integer column, const RGBColor& color) {
RGBColor c = color;
if (vp.g != 1.0)
c = color.powc(vp.g);
integer ir = (integer)(255.99 * c.r),
ig = (integer)(255.99 * c.g),
ib = (integer)(255.99 * c.b);
ss << ir << " " << ig << " " << ib << "\n";//写入颜色值
}
好了,现在我们看下main函数的调用吧(以后main函数的调用都是一样的,所以不再重复了)
#include "../Common/RayTracingGroundUp/utilities/world.h"
int main() {
World w;
w.build();
w.render();
return 0;
}
得到的图像如下(因为我是mac电脑下开的win7虚拟机,所以mac自带读取ppm文件,如果你的win7不能打开,请用photoshop等作图软件打开就行了),终于成功了:

针对单个球体的World类的更多相关文章
- 针对单个 js 文件禁用 ESLint 语法校验
问题描述: 在 Vue-cli 创建的项目中,使用了 ESLint 规范代码的项目中 如何针对单个 js 文件禁用 ESLint 语法校验,但整个项目依然保留 ESLint 的校验规则? 解决方案: ...
- 针对多个球体的World类
World类其他都一样的,就修改build函数就行了,以后测试所有代码,都是基于两个或多个球体的,不再重复阐述. void World::build() { vp.set_hres(200); vp. ...
- C#使用Xamarin开发可移植移动应用进阶篇(6.使用渲染器针对单个平台自定义控件..很很很很重要..),附源码
前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 说点什么.. 本篇..基 ...
- selenium+java,实现部分截图功能,-针对单个元素的截图
有时候需要元素的截图,不需要整个截图.整理一个针对元素的截图的方法. 创建一个Java类,实现截取元素的方法 package com.lozz.utils; import java.awt.Recta ...
- C# 站点IP访问频率限制 针对单个站点
0x00 前言 写网站的时候,或多或少会遇到,登录,注册等操作,有时候,为了防止别人批量进行操作,不得不做出一些限制IP的操作(当前也可以用于限制某个账号的密码校验等). 这样的简单限制,我们又不想对 ...
- 针对安卓java入门:类和对象
定义类 class Dog { String name; int age; void jump(){ } } 生成对象: public class Test { public static void ...
- PHP针对数字的加密解密类,可直接使用
<?phpnamespace app;/** * 加密解密类 * 该算法仅支持加密数字.比较适用于数据库中id字段的加密解密,以及根据数字显示url的加密. * @author 深秋的竹子 * ...
- java 中 针对数组进行的工具类
1.遍历数组的方法: public static void printfArray(int[] arr) 2. 获取数组中最大值: public static int getMax(int[] ar ...
- 013_针对单个pid的cpu/内存/io的资源占用统计
#!/usr/bin/env python import sys import os import subprocess from decimal import Decimal from decima ...
随机推荐
- mysqldump速查手册
一.mysqldump用法 1.1 常见选项 --all-databases, -A: 备份所有数据库 --databases, -B: 用于备份多个数据库,如果没有该选项,mysqldump把第一个 ...
- Hadoop安装学习(第二天)
学习任务: 1.对VMnet8进行设置 2.配置主机名,对host文件进行编辑 3.将Hadoop文件以及jdk通过Xshell7传输到Linux系统 4.设置免密登录
- Java测试报告
测试题目:ATM机 程序说明:本程序中共包含了两个类,分别为Account类和AccountManager类 Account类代码: public class Account { private St ...
- 5分钟快速搭建一个springboot的项目
现在开发中90%的人都在使用springboot进行开发,你有没有这样的苦恼,如果让你新建一个springboot开发环境的项目,总是很苦恼,需要花费很长时间去调试.今天来分享下如何快速搭建. 一 ...
- 耗时半年,Eoapi 终于正式发布 API 工具的插件广场
这是我们的第一篇月报,每个月和每个来之不易的开发者分享产品故事以及产品进展. 在 5.20 这个极具中国特色的"节日"里,Eoapi 发布了 1.0.0 版,三个程序员掉了半年 ...
- Redis中的原子操作(2)-redis中使用Lua脚本保证命令原子性
Redis 如何应对并发访问 使用 Lua 脚本 Redis 中如何使用 Lua 脚本 EVAL EVALSHA SCRIPT 命令 SCRIPT LOAD SCRIPT EXISTS SCRIPT ...
- Spring AOP快速使用教程
Spring是方法级别的AOP框架,我们主要也是以某个类的某个方法作为连接点,用动态代理的理论来说,就是要拦截哪个方法织入对应的AOP通知.为了更方便的测试我们首先创建一个接口 public in ...
- JS:this关键字1
this 代表了当前的对象,哪个对象调用了this所在的函数,this就代表了哪个对象: 例1: function fn(){ var a = 1; console.log(this) } fn() ...
- Maven的安装 和idea的配置
Maven的安装 和idea的配置 工欲善其事 必先利其器 1 下载maven 官网 下滑 找到Files tar.gz 是linux系统的 .zip window系统 2 maven安装和配置到环境 ...
- 论文解读(SR-GNN)《Shift-Robust GNNs: Overcoming the Limitations of Localized Graph Training Data》
论文信息 论文标题:Shift-Robust GNNs: Overcoming the Limitations of Localized Graph Training Data论文作者:Qi Zhu, ...