好了,终于到了可以看到图片的环节了。之前的类,你一定要实现好了。所有关于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. Zookeeper安装学习(二)

    学习内容:Zookeeper集群安装(Zookeeper版本:Zookeeper3.5.7:注:master,s1,s2都需要部署) 解压安装: (1)在主机 master 解压 Zookeeper ...

  2. [codeforces] 暑期训练之打卡题(三)

    每个标题都做了题目原网址的超链接 Day21<Alphabetic Removals> 题意: 给定一个字符串,要求按照字典序按照出现的前后顺序删除 k 个字母 题解: 记录字符串中各个字 ...

  3. Tmux终端复用神器使用心得

    tmux在连接远程服务器做实验时很有帮助,可以为每一个项目设置一个Session,在Session中设置不同的Window同时跑多个实验,Window本身还可以分割为多个Pane,在一个视野内利用多个 ...

  4. Microsoft Office 代码执行漏洞临时防范方法

    一.删除ms-msdt URI 注册表 1.按下键盘上的快捷组合键:win键 和 R键,打开运行(也可以在开始菜单打开运行). 2.在运行窗口中输入命令:regedit,点击确定或敲回车键就可以快速打 ...

  5. Thymeleaf 公共css,js提取及自有css,js导入

    https://www.jianshu.com/p/2102fa4772ba

  6. JAVA - ArrayList是否会越界?

    JAVA - ArrayList是否会越界? ArrayList并发add()可能出现数组下标越界异常. ArrayList是实现了基于动态数组的数据结构. LinkedList是基于链表的数据结构 ...

  7. Linux(Centos7)静默安装Oracle19C

    Oracle数据库服务器一般都是Linux,Linux服务器一般都是在非图形界面的操作,本文章手把手教你如何在非图形界面安装Oracle19C. ORACLE 19C 的安装包自行在官网下载,下载免费 ...

  8. vue 使用npm install安装依赖失败 【问题分析与解决】

    1 进入项目根目录,先通过 npm install 命令安装项目所需依赖,再通过 vue ui 命令打开 Vue Cli 提供的图形化界面,选择项目所在文件夹将项目导入. 出现问题 npm insta ...

  9. hadoop集群搭建——单节点(伪分布式)

    1. 准备工作: 前提:需要电脑安装VM,且VM上安装一个Linux系统 注意:本人是在学习完尚学堂视频后,结合自己的理解,在这里做的总结.学习的视频是:大数据. 为了区分是在哪一台机器做的操作,eg ...

  10. ansible环境安装及数据恢复

    配置免密登录服务器及下载备份文件#!/bin/bash BACKUP=192.168.30.233 #一行写一个IP BACKUP_PASSWD="lxzl_root*#2021" ...