好了,终于到了可以看到图片的环节了。之前的类,你一定要实现好了。所有关于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. 从零搭建react+ts组件库(封装antd)

    为什么会有这样一篇文章?因为网上的教程/示例只说了怎么做,没有系统详细的介绍引入这些依赖.为什么要这样配置,甚至有些文章还是错的!迫于技术洁癖,我希望更多的开发小伙伴能够真正的理解一个项目搭建各个方面 ...

  2. 在 .NET 中使用 FixedTimeEquals 应对计时攻击

    计时攻击 在计算机安全中,计时攻击(Timing attack)是旁道攻击 (Side-channel attack) 的一种,而旁道攻击是根据计算机处理过程发出的信息进行分析,包括耗时,声音,功耗等 ...

  3. React简单教程-4-事件和hook

    前言 在上一章 React 简单教程-3-样式 中我们建立了一个子组件,并稍微美化了一下.在另一篇文章 React 简单教程-3.1-样式之使用 tailwindcss 章我们使用了 tailwind ...

  4. ubuntu下连microsoft sql server解决方案

    shell for MSSQL: https://github.com/dbcli/mssql-cli mssql-cli -S 127.0.0.1,1433 -d testDB -U myuser ...

  5. flink 流的合并

    flink 流的合并操作 union union只能合并类型相同的数据,合并的结果仍然是DataStream,结果操作与未合并之前一致. public static void main(String[ ...

  6. 新上线!3D单模型轻量化硬核升级,G级数据轻松拿捏!

    "3D模型体量过大.面数过多.传输展示困难",用户面对这样的3D数据,一定不由得皱起眉头.更便捷.快速处理三维数据,是每个3D用户对高效工作的向往. 在老子云最新上线的单模型轻量化 ...

  7. Java基础-并发篇

    3.1. JAVA 并发知识库 3.2. JAVA 线程实现/创建方式 3.2.1. 继承 Thread 类 ​ Thread 类本质上是实现了 Runnable 接口的一个实例,代表一个线程的实例. ...

  8. ssh空闲一段时间后自动断网

    ssh空闲一段时间后自动断网 用客户端工具,例如securecrt连接linux服务器,有的会出现过一段时间没有任何操作,客户端与服务器就断开了连接. 造成这个的原因,主要是因为客户端与服务器之间存在 ...

  9. AI场景存储优化:云知声超算平台基于 JuiceFS 的存储实践

    云知声是一家专注于语音及语言处理的技术公司.Atlas 超级计算平台是云知声的计算底层基础架构,为云知声在 AI 各个领域(如语音.自然语言处理.视觉等)的模型迭代提供训练加速等基础计算能力.Atla ...

  10. Nginx通过bat文件快速启动停止

    新建文本文件NginxRun.bat.(名字无所谓,后缀名得是bat) 将以下代码复制到bat文件中即可. @echo off ::进入D盘 d: ::进入nginx目录 这里是自己的nginx目录 ...