• 一些几何


    直线方程

    只列出二维的情况,因为三维可以分解到二维来看。

    斜率怎么算?写成 y = kx 的形式。

    方向向量怎么算?斜率分子=y, 斜率分母=x。斜率就是 tan 夹角,对边比斜边,正好是方向向量的 step 。

    法向量怎么算?法向量乘方向向量等于零(因为互相垂直)。

    截距怎么算?令另一个轴坐标为零。

    名称 形式 斜率 法向量 方向向量 x 轴截距 y 轴截距
    一般式 ax + by + c = 0 -a / b (a, b) (b, -a) -c / a -c / b
    斜截式 y = kx + b k (k, -1) (1, k) -b / k b
    截距式 x / a + y / b = 1 -b / a (1/a, 1/b) (a, -b) a b
    点斜式 y - y0 = k(x - x0) k (k, -1) (1, k) -y0/k + x0 y0 - kx0
    两点式 (y - y0) / (y1 - y0) = (x - x0) / (x1 - x0) (y1 - y0) / (x1 - x0) (y1 - y0, x0-x1 ) (x1-x0, y1 - y0) ... ...
    点向式 (y - y0) / a = (x - x0) / b ... ... ... ... ...
    点法式 a(x - x0) + b(y - y0) = 0 ... ... ... ... ...

    主要记住:

    • 写成一般式过后,x 和 y 前面的系数就是法向量。
    • 法向量与方向向量垂直。

    平面方程

    名称 形式 说明
    一般式 ax + by + cz + d = 0 法向量 (a, b, c)
    点法式 a(x - x0) + b(y - y0) + c(z - z0) = 0 法向量 (a, b, c)
    截距式 x/a + y/b + z/c = 1 截距 a, b, c

    对于一般式的平面方程要特别注意的情形有:

    • 某些系数 = 0 : x 前系数为 0 说明平面垂直于 x 轴,x, y 前系数为 0 说明平面垂直于 xoy 平面。
    • d = 0 :说明平面经过原点。

    图形学里常用的形式是:N · P + D = d [1]

    N 代表法向量, P 代表平面上的一个已知点。这个式子可以从一般式推导出来:

    ax + by + cz + d' = 0 可以写成 (a,b,c) · (x, y, z) + d' = 0 。令 (a,b,c) = N ,(x, y, z) = P ,d' = D - d 即可。

    其中 D 是有几何意义的。考虑一般式中 d = 0 的情况。此时平面经过原点,且可以算出 :

    | D | = | - N · P | = || N || || P || / cos<P, N>

    那么 | D | / || N || = || P || / cos<P, N> 如下图所示。也就是说,当规定法向量为单位向量时,| D | 就是两个平面的距离。一个是给出的平面,一个是与给出平面平行且经过原点的平面。

    具体应用比如算平面外一点到平面的距离,设 Po 为平面外一点,那么 Po 到平面 N · P + D = d 的最短距离为 N · Po - D

    【DX 里我们 Vertex Shader 要输出的 SV_CullDistance,就是要算每个顶点到定义裁剪空间的平面的距离】

    投影

    Orthographic Projection

    一个简单的正交投影:把点 (x, y, z) 投影到平面 z = 0 上变成 (x, y) 。特点:

    • z 值不可还原。无论 z 是正是负都会变成 0 ,而且再也还原不回来。
    • 类似于一个降低维度的操作。

    正交投影更普遍的形式是把一个由 (l, r, t, b, n, f) 定义的 axis-aligned bounding box (AABB) 变成一个 中心在原点、轴对齐 的正方体[2]

    这个正方体叫做 canonical view volume (CVV),它里面点的坐标叫做 normalized device coordinates (NDC)。

    DX 的 CVV 是 (-1,-1, 0) ~ (1, 1, 1) ,OpenGL 的 CVV 是 (-1, -1, -1) ~ (1, 1, 1) 。

    e.g. 常见的俯视45度角就是 fixed 了一个 orthographic 的 camera。【拍自己脑阔:决定你 camera 看向哪里的是 lookat 的 y! 不是 up 的 y! 】

    DX 有俩 Ortho 的 API :

    1. XMMatrixOrthographic( float ViewWidth, float ViewHeight, float NearZ, float FarZ)

    2. XMMatrixOrthographicOffCenter( float ViewLeft, float ViewRight, float ViewBottom, float ViewTop, float NearZ, float FarZ )

    前者默认 AABB 的中心在原点,后者不在,所以要求给出 AABB 全部的六个参数。

    // Initialize the view matrix
    XMVECTOR Eye = XMVectorSet( -5.0f, 5.0f, -5.0f, 0.0f );
    // 往45°那个方向,实际上是(1, -1, 1);如果纯 45° 应该是 (1/2, -sqrt(2)/2, 1/2)
    XMVECTOR At = XMVectorSet( -4.0f, 4.0f, -4.0f, 0.0f ); 
    XMVECTOR Up = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );
    g_View = XMMatrixLookAtLH( Eye, At, Up );
    
    // Initialize the orthographic projection matrix
    g_Projection = XMMatrixOrthographicLH( 10, 10, 0.01f, 100.0f );
    
    1                    0                     0                     0   
    
    0                    1                     0                     0   
    
    0                    0                     1                     0          = T
    
    -(l+r)/2          -(t+b)/2              -(n+f)/2                 1
    
    2/(r-l)          0          0          0 
    
    0          2/(t-b)          0          0
    
    0                0        2/(f-n)      0                = S
    
    0                0          0          1
    

    首先做一个平移操作。拿 [l, r] 举例,让所有区间内的点都变成相对 (l+r)/2 的数,即 [l, r] 变成了 [l - (l+r)/2, r - (l+r)/2] = [(l-r)/2, (r-l)/2] = [-(r-l)/2, (r-l)/2]。接着是缩放操作,把 [-(r-l)/2, (r-l)/2] 除以 (r-l) 得到 [-1/2, 1/2] 然后乘2得到 [-1, 1] 。

    应用上就是这样 v * M_ortho = v * T * S

    Perspective Projection

    // Initialize the view matrix
    XMVECTOR Eye = XMVectorSet( -5.0f, 5.0f, -5.0f, 0.0f );
    XMVECTOR At = XMVectorSet( -4.0f, 4.0f, -4.0f, 0.0f );
    XMVECTOR Up = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );
    g_View = XMMatrixLookAtLH( Eye, At, Up );
    
    // Initialize the perspective projection matrix
    g_Projection = XMMatrixPerspectiveFovLH( XM_PIDIV2, width / (FLOAT)height, 0.01f, 100.0f );
    

    Ref


    1. Mathematics for 3D Game Programming and Computer Graphics 3rd Ch5.2 ↩︎

    2. Real-time Rendering 4th Ch4.7 ↩︎

  • 相关阅读:
    iOS----------WKWebView修改userAgent
    Vmware路由配置
    【手机APP开发】指南
    【Git】git 指南
    【微信小程序开发】阮一峰老师的微信小程序开发入门教程——学起来~
    【vue】2-Keycode对照表
    【vue】1-vue简介与基础
    Meaning
    数据增强
    Dropout
  • 原文地址:https://www.cnblogs.com/tandandan/p/14760387.html
Copyright © 2020-2023  润新知