Skip to content

Latest commit

 

History

13 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

alt text

旋转甜甜圈(环面)教程

首先,这个代码是通过类似于点云的思想实现的。首先构造出环面的点云,之后对这些点进行旋转(围绕中心轴)和移动,从而确定每一个时刻的姿态。

得到3维空间的姿态后,再将3维模型在z轴进行透视投影。根据坐标z的远近关系确定ASCII字符的遮挡关系。

由于甜甜圈模型很难确定不同的面,如果使用的只是一个字符的话,展示效果会很差。所以还需要光照模型。

这里使用 兰伯特光照模型,即反射光线的强度与表面法线和光源方向之间的夹角余弦值成正比,夹角越大,收到的光线照射量就越少。

构造环面的三维模型

环面模型可以看作是一个小圆,围绕z轴旋转得来。

所以,我们定义:

  1. 环面大圆半径为R(绕z-轴的圆的半径), 对应的角度为 $\theta$
  2. 环面的小圆半径为r(生成环面的圆的半径), 对应的角度为 $\phi$

参数方程可以写为:

$$ x = (R + rcos\phi)cos\theta $$ $$ y = (R + rcos\phi)sin\theta $$ $$ z = rsin\phi $$

根据参数方程,我们遍历 $\theta$$\phi$ 就可以构造环面的点云了。

旋转

三维的旋转矩阵如下:

alt text

因此,如果模型进行旋转,可以写为:

$$ [x, y, z] \quad @ \quad R _x(A) \quad @ \quad R _y(B) \quad @ \quad R _z(C) $$

其中@ 表示矩阵乘法, [x, y, z] 表示坐标向量。

平移

在旋转操作之后,如果你想要把物体放到空间中的某个位置,就对旋转后的x, y, z坐标进行加减即可。

问:为何先旋转后平移?

答:这样可以保证旋转的时候,物体是中心对称的。

投影

在z轴进行透视投影,投影的坐标计算为:

$$ x' = \frac{x}{z} $$

$$ y' = \frac{y}{z} $$

根据z的远近确定遮挡关系,z的值越小,距离相机越近。

光照模型

反射光线的强度与表面法线和光源方向之间的夹角余弦值成正比,夹角越大,收到的光线照射量就越少。

计算表面法线和光源方向的点积:

$$ I = max(0, N \cdot L) $$

N: 表面法线向量(归一化后) L: 光源方向向量(归一化后) I:光照强度

环面模型法线向量的计算

曲面的某点的法向量可以通过两个切向量的叉积求得。这两个切向量是由曲面的参数方程分别对 $\theta$$\phi$求偏导得到的。

$$ \vec{N} = \frac{\partial \vec{P}}{\partial \theta} \times \frac{\partial \vec{P}}{\partial \phi} $$

其中 $\vec{P}(\theta, \phi) = [x(\theta, \phi), y(\theta, \phi), z(\theta, \phi)]$ 表示环面上的点

  1. $\theta$ 求导:

$$ \frac{\partial \vec{P}}{\partial \theta} = [-(R + rcos\phi)sin\theta, (R + rcos\phi)cos\theta, 0] $$

  1. $\phi$ 求导

$$ \frac{\partial \vec{P}}{\partial \phi} = [-rsin\phi cos\theta, -rsin\phi sin\theta, rcos\phi] $$

叉积计算法向量

alt text

带入前面计算的偏导数后,得到:

$$ \vec{N} = \begin{bmatrix} r \cos \phi (R + r \cos \phi) \cos \theta \\ r \cos \phi (R + r \cos \phi) \sin \theta \\ r \sin \phi (R + r \cos \phi) \end{bmatrix} $$

目前得到的法向量是没有归一化的, 为了简化表达。我们可以去除系数 $r (R + rcos\phi)$

以为这个系数是在每一个分量都存在的,最后归一化的时候还是会被消掉的。

所以,简化后的法向量为:

$$ \vec{N} = [\cos\theta \cos\phi, \sin\theta \cos\phi, \sin\phi] $$

About

This is a C language implementation for rendering a 3D torus that outputs to the console.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages