好了,终于到了可以看到图片的环节了。之前的类,你一定要实现好了。所有关于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类的更多相关文章

  1. 针对单个 js 文件禁用 ESLint 语法校验

    问题描述: 在 Vue-cli 创建的项目中,使用了 ESLint 规范代码的项目中 如何针对单个 js 文件禁用 ESLint 语法校验,但整个项目依然保留 ESLint 的校验规则? 解决方案: ...

  2. 针对多个球体的World类

    World类其他都一样的,就修改build函数就行了,以后测试所有代码,都是基于两个或多个球体的,不再重复阐述. void World::build() { vp.set_hres(200); vp. ...

  3. C#使用Xamarin开发可移植移动应用进阶篇(6.使用渲染器针对单个平台自定义控件..很很很很重要..),附源码

    前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 说点什么.. 本篇..基 ...

  4. selenium+java,实现部分截图功能,-针对单个元素的截图

    有时候需要元素的截图,不需要整个截图.整理一个针对元素的截图的方法. 创建一个Java类,实现截取元素的方法 package com.lozz.utils; import java.awt.Recta ...

  5. C# 站点IP访问频率限制 针对单个站点

    0x00 前言 写网站的时候,或多或少会遇到,登录,注册等操作,有时候,为了防止别人批量进行操作,不得不做出一些限制IP的操作(当前也可以用于限制某个账号的密码校验等). 这样的简单限制,我们又不想对 ...

  6. 针对安卓java入门:类和对象

    定义类 class Dog { String name; int age; void jump(){ } } 生成对象: public class Test { public static void ...

  7. PHP针对数字的加密解密类,可直接使用

    <?phpnamespace app;/** * 加密解密类 * 该算法仅支持加密数字.比较适用于数据库中id字段的加密解密,以及根据数字显示url的加密. * @author 深秋的竹子 *  ...

  8. java 中 针对数组进行的工具类

    1.遍历数组的方法: public static void printfArray(int[] arr)  2. 获取数组中最大值: public static int getMax(int[] ar ...

  9. 013_针对单个pid的cpu/内存/io的资源占用统计

    #!/usr/bin/env python import sys import os import subprocess from decimal import Decimal from decima ...

随机推荐

  1. 120_PowerBI堆积瀑布图_R脚本Visual

    博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 一.效果 二.data 三.添加字段 注意红色框标注地方 四.code # 下面用于创建数据帧并删除重复行的代码始终执行, ...

  2. 【SNOI2017 DAY1】炸弹

    题意:P5024 思路:首先\(O(n^2)\)向能炸到的点连边,所以能到达的点的个数就是能到达的点的个数.然后显然要缩点+拓扑排序(我写的记搜). 然后再写一个线段树优化建图. 然后就WA了,我想了 ...

  3. MySQL - 并发事务出现的问题

    1. 脏读 含义:在事务过程中,读到了其它事务为提交的数据. 解决方法:将数据库事务提升到读已提交或以上的隔离级别. 2. 不可重复读 含义:一次事务中,两次读操作中,读出来的数据内容不一致. 解决方 ...

  4. django框架11

    内容概要 用户登录之后跳转到用户登录之前想要访问的页面 django操作cookie补充 django操作session django操作session补充 CBV添加装饰器 django中间件 自定 ...

  5. SQL Server之自动创建视图

    本方法只适合特定模式的视图创建. 比如,创建需要整张表列名的视图,或者当表和需要的列名统计在一张数据表当中,如图所示: 首先要先获取要创建视图所需要的表,这里我获取的是整个数据库中的表, IF OBJ ...

  6. 关于swiper插件在vue2的使用

    最近做项目用到了vue-awesome-swiper,总结一下使用方法 第一步:安装依赖 npm install swiper vue-awesome-swiper --save or npm ins ...

  7. RPA应用场景-公积金贷款业务数据整合和报送

    场景概述 公积金贷款业务数据整合和报送 所涉系统名称 个贷系统.公积金管理系统 人工操作(时间/次) 0.5小时 所涉人工数量1000操作频率 每日 场景流程 1.机器人整理个人贷款信息.个人贷款账户 ...

  8. sql-DML-增删改

    DML:增删改表中数据 1. 添加数据: insert into 表名(列名1,列名2,...列名n) values(值1,值2,...值n); insert into 表名 values(值1,值2 ...

  9. Tapdata 与星环 KunDB 完成产品兼容互认证

      近日, Tapdata 实时数据即服务平台(Tapdata Real Time DaaS)与星环 KunDB 完成产品兼容互认证.经深圳钛铂数据有限公司和星环信息科技(上海)股份有限公司共同严格测 ...

  10. Servlet-3 :JDBC+重定向

    请求重定向 redirect1) Servlet接收到浏览器端请求并处理完成后,给浏览器端一个特殊的响应,这个特殊的响应要求浏览器去请求一个新的资源,整个过程中浏览器端会发出两次请求,且浏览器地址栏会 ...