看《Ray Tracing in One Weekend》及其他时突然顿悟的一点


结论: 列举了几个例子,表明一个规律:
计算机中很多功能的实现,都是“先通过某种条件,筛选出符合要求的元素,然后对这些元素进行操作”。

《算法设计与分析》中的一个例子

以下例子来自于吕国英主编的《算法设计与分析》第二版(例20,82页)。

【例20】编程打印有如下规律的n*n方阵。

使左对角线和右对角线上的元素为0,它们上方的元素为0,左边元素为2,下方元素为3,右边元素为4,下图是一个符合条件的五阶矩阵。

0 1 1 1 0

2 0 1 0 4

2 2 0 4 4

2 0 3 0 4

0 3 3 3 0

算法设计:根据数据分布的特点,利用以上关于二维数组的基本常识,只考虑可读性的情况。

算法如下:(原书中为伪代码,此处我直接写成了C++)

#include <iostream>
int main()
{
    int i, j, a[100][100], n;
    std::cin >> n;
    for (i = 1; i <= n; i = i + 1)
    {
        for (int j = 1; j < n; j++)
        {
            if(i==j || i+j==n+1)    a[i][j]=0;
            if(i+j<n+1 && i<j)      a[i][j]=1;
            if(i+j<n+1 && i>j)      a[i][j]=2;
            if(i+j>n+1 && i>j)      a[i][j]=3;
            if(i+j>n+1 && i<j)      a[i][j]=4;
        }
    }

    for (i = 1; i <= n; i = i + 1)
    {
        for (int j = 1; j <= n; j++)
        {
            std::cout <<a[i][j] <<"\t";
        }
        std::cout <<"\n";
    }
    system("pause");
    return 0;
}

可以看到,在循环中,根据元素的位置,判断出当前位置所在的元素应该是几,然后赋给合理的值。

Python 中用来操作excel的 xlwings中的例子

在上个例子看过以后过了一两天,学到了使用xlwings来操作excel。在一个教程下面看到了大牛们操作excel输出图案的例子。https://blog.csdn.net/whalefall/article/details/102665002。于是想到自己也试试吧,做了两个练手。

import xlwings as xw
import math
def Cross(n):
    book=xw.Book()
    sht=book.sheets(1)

    H=7.5
    W=1.188
    for i in range(1,n+1):
        for j in range(1,n+1):
            rng=sht.range(i,j)
            if j==1:
                rng.row_height=H
            if i==1:
                rng.column_width=W
            if i==j:
                rng.color=(255,0,0)
            elif j==n+1-i:
                rng.color=(255,0,0)
    
def Sin(n):
    book=xw.Book()
    sht=book.sheets(1)

    H=7.5
    W=1.188
    for i in range(1,2*n+2):
        for j in range(1,2*n+1):
            rng=sht.range(i,j)
            if j==1:
                rng.row_height=H
            if i==1:
                rng.column_width=W
            if abs(n*math.sin(2*math.pi/(2*n+1) * (j-1))-(n+1-i))<0.7:
                rng.color=(255,0,0)
Cross(21)
# Sin(21)

在这里插入图片描述
在这里插入图片描述
实际上,这个例子和上面那一个课本中的例子非常像,也是遍历各个元素,在符合条件的位置处进行某种特殊操作。(实际上我刚开始想像书中的例子一样,把一个区域按对角线划分成四个块,分别给不同的颜色,不过后来觉得太过麻烦,就先划了叉)。

ANSYS Fluent 中的UDF

Fluent是一个仿真软件,如果没有接触过,可以直接跳过这一部分。
在Fluent中,可以通过UDF来实现一些较为复杂的操作。在Fluent的帮助中提供了很多例子,比如根据入口处网格的坐标,设定不同的入口压强。(这里是压强,压强,压强,不是压力!)
UDF语句能做的事情挺多,甚至可以直接修改整个场中的值(假如你是上帝,知道每个网格内物理量的值的话,你可以通过UDF直接给每个网格赋值,这样或许能节约一些节省计算时间)。我现在去做个例子。
做了个正方形,正方形的中心在坐标原点,正方形边长为10。通过以下UDF,对网格温度赋值,使每个网格的温度值等于其到原点的距离。

#include "udf.h"

// 注意,整个场是正方形,中心在原点,每条边长是20(单位就不写了)
DEFINE_ON_DEMAND(test)
{
    cell_t c;
    real pos[2];
    real x,y;
    real dis;  // 到原点的距离
    Domain *d=Get_Domain(1);
	Thread *ct=Lookup_Thread(d,8);
	begin_c_loop(c,ct)
	{
		C_CENTROID(pos,c,ct);
        x=pos[0];
        y=pos[1];
        dis=sqrt(x*x+y*y);
		C_T(c,ct)=dis;
	}
	end_c_loop(c,ct)
}

使用上述UDF后查看温度场,得到结果如下。
在这里插入图片描述
可以看到,这其实与前面是相同的,又是一个找到合理的点,给点赋值的操作。

光线追踪(不知道这算不算图形学的入门内容)

很久不搞UDF,刚才做了好半天好半天啊,都有点没有刚开始写东西的时候的感觉了,我得酝酿一下。
今天看了一点很多人推荐的图形学入门资料,Peter Shirley 的《Ray Tracing in One Weekend》。磕磕绊绊地把书上的内容做了一点。现在刚做到第五章。
虽然确实能感觉这书通俗易懂,但是有些地方以我的水平看着还是挺费劲。书上的向量运算倒是不难,但是我总觉得表示光线的那个向量怎么那么别扭。反复看了看,突然有一刻我发现,这怎么跟操作Excel单元格一样!
其实不管多复杂,都是为了最终给每个像素算一组想要的颜色,比如要显示球,就要找到在当前的光线下,屏幕上哪个点应该是可以显示球,再算出来具体颜色值应该是多少。这样一看,我觉得现在接触到的这几章里的内容,与之前几个例子之间最大的不同可能就是复杂程度了。而且感觉,为了将程序通用化,在目前这个阶段看写出来的代码,似乎有些冗长。其实整个程序就是得到每个像素点的颜色,然后再输出到文本文件里,我甚至直接不用看书,按之前说的Python,或者Fluent UDF的思路也,肯定完全是可以的!
光线追踪这部分的代码有点长,我就偷懒不贴了。给个抄书中代码得到的ppm结果图意思一下,是用matlab打开的。
在这里插入图片描述

总结

发现了,从宏观上来看我现在接触到的图形学的这点入门知识,总结成一句话就是计算出每个像素中的颜色,并输出。
于是,从战略角度,对图形学没有一点生疏和恐惧,因为我类似的事情早就做过很多次了!
当然从具体实现手段来讲,肯定需要用到非常多的计算,想要掌握还是要付出巨大的努力。
(写的途中搞了一些杂七杂八的事情,感觉没开始时那么兴奋了,可能真的是个显而易见的东西,耽误大佬们的时间了。)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Ray Tracing光线追踪)是一种在计算机图形学中使用的技术,用于生成高度逼真的图像。它通过跟踪光线从视点开始的路径,来模拟光在场景中的运动,计算出光线与物体的交点以及光线在经过物体时的反射、折射等效果,并最终生成图像。 以下是光线追踪的基本步骤[^1]: 1. 从相机位置发出一条光线。 2. 确定该光线与场景中物体的交点。 3. 计算该交点处的光照强度,包括直接光照和间接光照。 4. 根据物体的表面特性,计算反射或折射光线的方向和强度。 5. 递归计算反射或折射光线的路径,直到达到最大递归深度或光线不再与物体相交。 6. 将所有光线的颜色值组合在一起,得到最终的图像。 下面是一个简单的 Python 代码示例,演示了如何使用 Pygame 和 PyOpenGL 库实现简单的光线追踪效果[^2]: ```python import pygame from OpenGL.GL import * # 初始化 Pygame 和 PyOpenGL pygame.init() display = (800, 600) pygame.display.set_mode(display, pygame.DOUBLEBUF | pygame.OPENGL) # 设置相机位置和方向 glMatrixMode(GL_MODELVIEW) glLoadIdentity() gluLookAt(0, 0, 0, 0, 0, -1, 0, 1, 0) # 设置场景中的物体 glColor3f(1, 1, 1) glBegin(GL_TRIANGLES) glVertex3f(-1, -1, -5) glVertex3f(1, -1, -5) glVertex3f(0, 1, -5) glEnd() # 定义光线追踪函数 def raytrace(x, y): glReadBuffer(GL_BACK) color = glReadPixels(x, y, 1, 1, GL_RGB, GL_FLOAT) return color # 创建主循环 while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() # 绘制场景和光线 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glBegin(GL_LINES) glVertex3f(0, 0, 0) glVertex3f(0, 0, -5) glEnd() # 调用光线追踪函数 x, y = pygame.mouse.get_pos() w, h = display color = raytrace(w - x, h - y) # 输出光线追踪结果 print("Color at (%d, %d): %s" % (x, y, color)) # 更新 Pygame 显示窗口 pygame.display.flip() ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值