好了,终于到了可以看到图片的环节了。之前的类,你一定要实现好了。所有关于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. 『忘了再学』Shell基础 — 20、Shell中的运算符

    目录 1.Shell常用运算符 2.Shell中数值运算的方法 (1)方式一 (2)方式二 (3)方式三(推荐) 1.Shell常用运算符 Shell中常用运算符如下表: 优先级数值越大优先级越高,具 ...

  2. st表 LCA

    我当时知道ST表可以 \(O(1)\) 求 LCA 的时候是极为震惊的,可以在需要反复使用 LCA 的时候卡常使用. ST表!用于解决 RMQ问题 ST表 我可能写得不好,看专业的 怎么实现? 考虑把 ...

  3. 手把手教你使用 Spring Boot 3 开发上线一个前后端分离的生产级系统(一) - 介绍

    项目简介 novel 是一套基于时下最新 Java 技术栈 Spring Boot 3 + Vue 3 开发的前后端分离的学习型小说项目,配备详细的项目教程手把手教你从零开始开发上线一个生产级别的 J ...

  4. Spring boot中最大连接数、最大线程数与最大等待数在生产中的异常场景

    在上周三下午时,客户.业务和测试人员同时反溃生产环境登录进入不了系统,我亲自测试时,第一次登录进去了,待退出后再登录时,复现了客户的问题,场景像是请求连接被拒绝了,分析后判断是spring boot的 ...

  5. seafile私有网盘搭建

    各种公有网盘确实很方便,但总有些特殊情况不是? 闲来无聊准备自己搭建一个私有网盘,也让自己的闲置的服务器好好利用一下 搜索一番,找到了专业户seafile 一顿操作,踩了无数大坑,特此总结一下 1.c ...

  6. SpringBoot Restful 接口实现

    目录 SpringBoot 核心注解 SpringBoot Restful 接口实现 封装响应数据 SpringBoot 核心注解 SpringBoot 基础入门 注解 说明 Component 声明 ...

  7. django框架4

    内容概要 编辑删除功能编写 虚拟环境 django路由层版本区别 视图函数的返回值 JsonResponse对象 form表单上传文件 request其他方法 FBV与CBV(基于函数的视图.基于类的 ...

  8. sqlmap自动检测漏洞并进行渗透

    使用案例靶场为上篇文章介绍的封神台---靶场 https://hack.zkaq.cn/   提示:采用开源靶场里面的猫舍进行渗透注入,仅用于安全防范无安全侵犯 1.首先检测是否已经安装成功sqlma ...

  9. 【Redis】skiplist跳跃表

    有序集合Sorted Set zadd zadd用于向集合中添加元素并且可以设置分值,比如添加三门编程语言,分值分别为1.2.3: 127.0.0.1:6379> zadd language 1 ...

  10. JS:String

    String数据类型:字符串 字符串是存储字符的变量. 字符串可以是引号中(可以使用单引号或双引号)的任意文本. var a = "abc"; var b = "123& ...