日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

射线与平面相交检测

發(fā)布時間:2023/12/2 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 射线与平面相交检测 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

射線與平面相交檢測

3D 中射線與平面相交檢測
本篇討論的射線是無限長,平面無限大
下圖展示的幾種位置關(guān)系:相交、不相交
相交包括:只有一個交點 (射線3)、射線在平面內(nèi)有無數(shù)交點 (射線4)
不相交:射線與平面平行 (射線1),射線與平面不平行也不相交 (射線2、射線5)

判斷射線2和射線5和平面不相交,添加輔助線如下

在平面上任取一點C
射線2中:P1為射線起點,向量P1A 是射線的方向向量, 連接P1C
點乘:Dot(向量P1A,平面法向量 Normal) > 0
點乘:Dot(向量P1C,平面法向量 Normal < 0
兩個點乘結(jié)果異號(一個大于0,一個小于0) 則判定射線2 與平面不相交

射線5中:P2為射線起點,向量 P2B 是射線的方向向量,連接P2C
點乘:Dot(向量P2B,平面法向量 Normal) < 0
點乘:Dot(向量P2C,平面法向量 Normal > 0
兩個點乘結(jié)果異號(一個大于0,一個小于0) 則判定射線2 與平面不相交

判斷射線1、射線4,添加輔助線如下圖

在平面上任取一點C
射線1中:P1為射線起點,向量P1A 是射線的方向向量, 連接P1C
點乘:Dot(向量P1A,平面法向量 Normal) = 0 說明 P1A 垂直于平面法向量,則P1A平行于平面
點乘:Dot(向量P1C,平面法向量 Normal < 0 說明 P1C 至少一個端點不在平面上
兩個點乘結(jié)果(一個等于0,一個小于0) 則判定射線2 與平面平行但不在平面內(nèi)

射線4中:P2為射線起點,向量 P2B 是射線的方向向量,連接P2C
點乘:Dot(向量P2B,平面法向量 Normal) = 0 說明 P2B 垂直于平面法向量,則P2B平行于平面
點乘:Dot(向量P2C,平面法向量 Normal = 0 說明 P2C 垂直于平面法向量,則P2C平行于平面
則 P2BC 所組成的平面和原平面平行,C點又是原平面中的點,則P2BC和平面重合,則P2B在原平面內(nèi)
結(jié)論射線4在平面內(nèi)

射線3的相交檢測,如果相交,求交點坐標。看下圖輔助線以及標記

平面上任取一點C
PB 為從點P到平面做的垂線,h 為向量PB 在平面法向量 Normal 的投影長度
O為射線3與平面的交點,f 為向量PO的長度,
O點坐標 = P坐標 + 向量PO
向量PO = rayDirection * f
O點坐標 = P坐標 + rayDirection * f
我們通過點C來求解 f

在三角形 PBC 中
h = Dot(向量PC,平面法向量Normal)

在三角形 PBO 中
h = Dot(向量PO,平面法向量Normal)

h = Dot(rayDirection * f,平面法向量Normal), 其中 f 是標量,可以提取出來

h = f * Dot(rayDirection , 平面法向量 Normal)

f = h 除以 Dot(rayDirection, 平面法向量 Normal)

代碼邏輯如下

/// <summary> /// 射線與平面相交檢測 /// </summary> public class RayPlaneCollision {float dot_rayDir_planeNormal;float dot_pc_planeNormal;/// <summary>/// 射線與平面相交檢測/// </summary>/// <param name="source">射線起點坐標</param>/// <param name="rayDirection">射線方向</param>/// <param name="planePos">平面上任一點坐標</param>/// <param name="planeNormal">平面法向量</param>/// <returns></returns>public RayPlaneCollisionEnum IsCollision(Vector3 source, Vector3 rayDirection, Vector3 planePos, Vector3 planeNormal){Vector3 PC = planePos - source;dot_rayDir_planeNormal = Dot(rayDirection, planeNormal);dot_pc_planeNormal = Dot(PC, planeNormal);// 射線平行于平面if (dot_rayDir_planeNormal == 0) {if (dot_pc_planeNormal == 0){// 射線和平面平行并且射線在平面內(nèi)return RayPlaneCollisionEnum.IN_PLANE;}// 射線和平面平行但是射線不在平面內(nèi)return RayPlaneCollisionEnum.SEPARATION;}if (dot_rayDir_planeNormal > 0 && dot_pc_planeNormal > 0){return RayPlaneCollisionEnum.COLLISION;}if (dot_rayDir_planeNormal < 0 && dot_pc_planeNormal < 0){return RayPlaneCollisionEnum.COLLISION;}return RayPlaneCollisionEnum.SEPARATION;}public Vector3 CollisionPosition(Vector3 source, Vector3 rayDirection, Vector3 planePos, Vector3 planeNormal){if (IsCollision(source, rayDirection, planePos, planeNormal) != RayPlaneCollisionEnum.COLLISION){return Vector3.zero;}float length = dot_pc_planeNormal / dot_rayDir_planeNormal;Debug.LogError(dot_pc_planeNormal + " " + dot_rayDir_planeNormal);return source + rayDirection * length;}public float Dot(Vector3 vector1, Vector3 vector2){return vector1.x * vector2.x + vector1.y * vector2.y + vector1.z * vector2.z;} }

本篇開始說的限制條件 射線無限長、平面無限大,如果射線限制了長度 s,平面限制了區(qū)域(有N個頂點的多邊形),對于不相交的判定沒有影響

對于射線和平面相交的,如果射線限制長度,則 根據(jù)上邊計算的長度 f 和 限制長度 s 比較,如果 s 小于 f,則射線長度不夠,不相交
如果 s >= f,計算出 O 點坐標,然后判斷 O點坐標是否在平面范圍內(nèi)

對于射線在平面內(nèi)的思考下

總結(jié)

以上是生活随笔為你收集整理的射线与平面相交检测的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。