幾何向量:點與直線
這一篇是幾何向量的擴充套件篇之一,因為後面要講到的CG技術需要這一篇的數學基礎,所以額外開一篇進行講解。
這次我們就觀察學習二維中點與直線的重要關係,垂線或者說圖形學中的法線,因為這和後續的反射向量、光追計算、鏡面計算等有很大依賴關係,比如說我們有一個頂點P處於一塊二維鏡面前,求這個頂點P在二維鏡面中的倒影頂點P',這就需要求出頂點P到鏡面所處的直線L的垂線及距離了,如下圖:
首先確定鏡面直線L的方程:A*x+B*y+C = 0,這個方程怎麼來的呢?無非就是一元一次方程y = K*x+B的另一種寫法形式,具體如下:
那麼接下來我們已知一個頂點P(x0,y0),想求出頂點P在鏡面直線L中的倒影P'(x',y'),我們連線P和P'得到的新直線垂直於直線L,同時相交點為P1(x1,y1),那麼我們先起碼得求出新直線L'的方程,求法如下:
這裡有一個關鍵的斜率的問題,我們把直線L方程y = K*x + B中K稱為斜率,意思就是以單位圓為參考,直線與x座標軸的夾角θ的正切值,也就是tanθ,那麼直線L的垂線L'的斜率就是-1/k,如下圖:
我們拋開平移不談,只談y和x的比例K也就是斜率符合三角函式中正切值tan的定義。
這裡我們就總結一下,我們已經把垂線L'方程和相交點P1得到了,如下圖:
接下來就是求解倒影點P'的座標公式了,無非就是根據向量相等去計算,如下圖:
推到這裡基本沒什麼問題了,最後為了程式實現,我們順便寫上根據兩已知頂點求直線的公式,這裡我們通過上面講的斜率方法推導,如下圖:
求直線的方程無非就是求動點P的座標公式。
最後我們就來程式模擬了,假設我有一條隨時變化的鏡面直線L,鏡面直線L前方有一個物體P,求物體P在鏡面中倒影P',模擬程式如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ReflectObject : MonoBehaviour { public LineRenderer mLineRender; public Transform mMirrorPosA; public Transform mMirrorPosB; public Transform mObjectP; public Transform mObjectPInvert; private float mA; private float mB; private float mC; private Vector3 mInvertPos; void Start() { } void Update() { //計算鏡面直線的方程引數,A*x + B*y + C = 0 //根據之前推導的方程我們可以得出 mA = mMirrorPosB.position.y - mMirrorPosA.position.y; mB = mMirrorPosA.position.x - mMirrorPosB.position.x; mC = mMirrorPosB.position.x * mMirrorPosA.position.y - mMirrorPosA.position.x * mMirrorPosB.position.y; //同樣根據之前推導的倒影點P'座標公式計算出座標引數 float x0 = mObjectP.position.x; float y0 = mObjectP.position.y; float x = (mB * mB * x0 - 2 * mA * mB * y0 - 2 * mA * mC - mA * mA * x0) / (mA * mA + mB * mB); float y = (mA * mA * y0 - 2 * mA * mB * x0 - 2 * mB * mC - mB * mB * y0) / (mA * mA + mB * mB); float z = 0; mInvertPos = new Vector3(x, y, z); mObjectPInvert.position = mInvertPos; //給鏡面直線畫個linerender方便顯示 mLineRender.positionCount = 2; mLineRender.SetWidth(0.2f, 0.2f); mLineRender.SetPosition(0, mMirrorPosA.position); mLineRender.SetPosition(1, mMirrorPosB.position); } }
程式碼很簡單,我只進行了簡單的註釋,無非就是通過上面推導的公式進行模擬,效果圖如下:
講到這裡,這一篇部落格的目的就達到了,後面我們繼續深入,在立體幾何中進行講解點與面的關係,最終實現我們想要的真實反射和光追。
so,我們接下來繼續。