使用SharpGL三維建模技術生成3D井眼軌跡圖

2020-12-06 程式設計師世界

一、前言

最近需要在項目的軟體中增加一個功能,根據連續測斜數據展示三維的井眼軌跡圖,由於購買的廠商的圖件效果不理想,所以研究自己寫代碼實現類似的功能。

井眼軌跡的計算內容繁雜涉及了大量的鑽井工程專業專業知識。由於筆者是信息技術專業出身,所以只能依照自己的行業經驗研究井眼軌跡的三維技術實現。其中涉及到鑽井工程細節部分可能不準確或錯誤,本文內容僅供技術實現方面參考。

支持3D繪圖方面的技術框架很多,本文介紹使用SharpGL這個開源項目來實現三維井眼軌跡圖。

一、開源SharpGL項目介紹

SharpGL 可以讓你在 Windows Forms 或者 WPF 應用中輕鬆的使用 OpenGL 開發圖形應用。從核心內容來說,SharpGL是一個OpenGL API的封裝。一般來說,OpenGL API可以直接用於C/C++應用的開發,但是使用起來比較複雜, SharpGL直接提供了OpenGL全部的功能和擴展。SharpGL將所有的函數和一組豐富的對象,以及高級功能的對象集合放到一個包裝器中,你可以使用SharpGL執行opengl繪圖。不過SharpGL也包括一些不屬於OpenGL的內容,針對WinForms和WPF的用戶控制項用戶控制項提供了OpenGL渲染界面和用於處理類似於shader和紋理等複雜問題能力。甚至提供了一個高級類SceneGraph可以更好的使用面向對象的思想創建各類場景。

SharpGL背後的原理是OpenGL in .NET, SharpGL並不是一個需要重新學習的新框架,它只不過是封裝的OpenGL。

為什麼不直接使用OpenGL,而是使用SharpGL呢?

首先是我喜歡做.Net開發,可以使用託管代碼輕鬆調用C API,Dlllmport可以方便的調用這些API。但是必須要為所有的函數創建籤名。如果發生錯誤,整個錯誤將是非常龐大的,並且很難分析錯誤。

另外一個使用SharpGL的原因是SharpGL可以作為標準平臺調用來調用多數OpenGL函數,而不用創建外部方法的籤名。OpenGL擴展函數在運行時被夾在-這就沒有一個固定的進入點進入DLL,這樣就增加了工作量。

在OpenGL中獲得一個RD是比較困難的,底層的Win32代碼有大量的函數獲得像素格式,這些工作是大量重複和痛苦的,好在這一切SharpGL幫我做了。

最後一個選擇使用SharpGL的原因是,在OpenGL中大量的很痛苦的重複的工作如加載信息等,但是這些工作在.NET中是非常容易處理的。

OpenGL內容很多,而且非常成熟,相應的SharpGL內容也很多, 我不會在本文中寫出太多細節,我們只是用了其中很簡單(小)的一部分內容,在寫代碼過程中發現網上SharpGL的中文資料很有限。谷歌的原因英文資料找起來也很費勁,SharpGL缺少一個官方技術社區,值得一說的是官方提供了比較詳細的示例代碼,說實話其中很多代碼都是參考官方示例寫的。

SharpGL中的主要對象介紹:

SharpGL - 包含主OpenGL對象- 這個對象包裝所有的OpenGL函數,枚舉和擴展。

SharpGL.SceneGraph 包含OpenGL對象和場景元素光。材質。紋理。NURBs。著色器和其他對象的所有包裝。

SharpGL.WinForms - 包含應用程式的Windows 窗體控制項。

SharpGL.WPF - 包含用於你的應用程式的WPF控制項。

SharpGL.Serialization - 包含用於從 3D Studio Max文件。謹慎obj文件和trueSpace文件加載幾何圖形和數據的類。

三、井眼軌跡參數介紹

實際中井連續測斜數據如下:

測量井深(斜深):指井口至測點的井眼長度。

井斜角:井身軸線上某點的切線與垂線之間的夾角。

方位角:井身軸線上某點的切線的投影與正北方向的夾角。

依靠這三個參數可以繪製井眼軌跡,具體做法是通過這三個參數計算垂深、東西位移、南北位移。分別映射到SharpGL三維模型中世界坐標的Y軸坐標、X軸坐標、Z軸坐標。井眼軌跡參數計算本文不作介紹,感興趣的朋友可以去查找鑽井工程計算相關知識,我們這裡只介紹軟體實現方面內容。

四、三維井眼軌跡實現

4.1 三維繪圖中坐標系簡單介紹

二維繪圖:笛卡爾坐標有一個X軸和一個Y軸組成,X軸為水平方向,Y軸為垂直方向,X和Y相互垂直

三維繪圖:笛卡爾坐標多了一個Z軸,Z軸同時垂直於X和Y軸。Z軸的實際意義代表著三維物體的深度

為了描述3D世界,首先要設計一些三維模型出來。

設計三維模型的時候用的坐標系就是Model Coordinate System。

Model Space只負責描述一個模型。在Model Space設計模型的時候,要注意使模型的包圍盒的中心位於原點(0, 0,0)。

包圍盒就是能夠把模型包圍的最小的長方體。為什麼要圍繞原點?因為這樣才能在下文所述的WorldSpace裡"正常地"旋轉、縮放和平移模型。

世界坐標系它是一個特殊的坐標系,它建立了描述其他坐標系所需要的參考系。也就是說,可以用世界坐標系去描述其他所有坐標系或者物體的位置。所以有很多人定義世界坐標系是「我們所關心的最大坐標系」,通過這個坐標系可以去描述和刻畫所有想刻畫的實體。

世界坐標系又稱全局坐標系或者宇宙坐標系。

5種比較重要的坐標系系統

局部空間(Local Space,或者稱為物體空間(Object Space))

世界空間(World Space)

觀察空間(View Space,或者稱為視覺空間(Eye Space))

裁剪空間(Clip Space)

屏幕空間(Screen Space)

將頂點從一個坐標系轉換到另一個坐標系需要用到幾個變換矩陣,其中幾個比較重要的是模型(Model)、觀察(View)、投影(Projection)三個矩陣。

物體頂點的起始坐標按序經過上述5個坐標系系統最終轉換為屏幕坐標。

坐標系及坐標轉換的內容感興趣的朋友請自行baidu。

項目開始

啟動VS,建立一個Windows桌面程序,引入如下Dlls:

在這裡我們使用SharpGL.WinForms命名空間中的OpenGLControl 控制項。

把控制項拖拽到當前窗體中,這裡主要用到下面三個方法:

void openGLControl1_OpenGLInitialized(object sender, System.EventArgs e)

用於執行任何OpenGL初始化。

void openGLControl1_Resize(object sender, System.EventArgs e)

Resize方法:控制項大小變化是邏輯處理。

privatevoid openGLControl1_OpenGLDraw(object sender, RenderEventArgs e)

繪製方法:用於做OpenGL渲染。

繪製後背景面/左側背景面

如圖所示:灰色的兩個面就是左背景面和後背景面

首先需要在openGLControl1_OpenGLDraw方法中獲取SharpGL繪製對象

SharpGL.OpenGL gl = this.openGLControl1.OpenGL;

然後開始繪製背景面。

為了測試我們使用兩種方式分別繪製後背景面和左側背景面。

後背景面使用一個圖片來渲染,而左側背景面之間用顏色來繪製,這兩種方式顯示的效果是相同的。

後背景面:

Texture texture = new Texture();

texture.Create(gl, "20190919154917.png");

加載一個圖片當作材質。

繪製後背景面:

gl.Begin(OpenGL.GL_QUADS);

gl.TexCoord(1.0f, 0.0f); /

gl.Vertex(-2.0f, 0.0f, -2.0f); // 右下

gl.TexCoord(1.0f, 1.0f);

gl.Vertex(-2.0f, 4.0f, -2.0f); // 右上

gl.TexCoord(0.0f,1.0f);

gl.Vertex(2.0f, 4.0f, -2.0f);// 左上

gl.TexCoord(0.0f, 0.0f);

gl.Vertex(2.0f, 0.0f, -2.0f);// 左下

然後繪製右側背景面:

設置灰色背景色

gl.Color(0.8f,0.8f,0.8f);

接著繪製四個頂點

gl.Vertex(-2.0f,0.0f, -2.0f);

gl.Vertex(-2.0f, 0.0f, 2.0f);

gl.Vertex(-2.0f, 4.0f, 2.0f);

gl.Vertex(-2.0f, 4.0f, -2.0f);

gl.End();

gl.Flush();

繪製底部網格

設置OpenGL.GL_LINES類型,繪製網格線。

在X,Z平面上繪製網格

for (float i = -2; i <= 2; i+= 0.5f)

{

//設置類型為繪製線

gl.Begin(OpenGL.GL_LINES);

//X軸方向

gl.Vertex(-2f, 0f, i);

gl.Vertex(2f, 0f, i);

//Z軸方向

gl.Vertex(i, 0f, -2f);

gl.Vertex(i, 0f, 2f);

gl.End();

}

}

繪製東西軸線/南北軸線/深度軸線

使用gl.Begin(OpenGL.GL_LINE_STRIP);來繪製坐標軸線

設置線寬,使用比網格粗一點的線。

gl.LineWidth(2f);

//Y軸方向

gl.Vertex(0.0f, 0.0f, 0.0f);

gl.Vertex(0.0f, 4.0f, 0.0f);

//X軸方向

gl.Vertex(-2.0f, 4.0f, 0.0f);

gl.Vertex(0.0f, 4.0f, 0.0f);

//Z軸方向

gl.Vertex(0.0f, 0.0f, -2.0f);

gl.Vertex(0.0f, 0.0f, 2.0f);

繪製井口橫縱投影線

井口橫縱投影線有點特殊,用的是虛線。

使用代碼:

//設置顏色

gl.Color(0.8f, 0.8f, 0.8f);

//線寬

gl.LineWidth(1f);

//允許繪製虛線

gl.Enable(OpenGL.GL_LINE_STIPPLE);

//設置虛線的種類,具體類型可搜索OpenGL文檔

gl.LineStipple(1, 0x3F07);

其它的代碼與前面一樣:

gl.Vertex(-2.0f, 4.0f, 0.0f);

gl.Vertex(0.0f, 4.0f, 0.0f);

繪製底部東西/南北刻度線/深度刻度線

接下來,我們在底部面上繪製刻度線。

我們把X軸當作東西軸,Z軸當作南部軸。

我們需要在背景面的底部線上和相鄰的底部面的一個邊上繪製刻度數,比如0米100米200米300米等。

說白了其實就是在不同的屏幕位置繪製文字。

在SharpGL中有兩種類型的繪製文字,立體文字和平面文字

立體文字是在世界坐標系上繪製文字,方法是:

gl.DrawText3D,

平面文字是在二維屏幕上繪製文字,對應的方法是:

gl.DrawText

這裡我們更適合使用平面文字,我們需要把三維的世界坐標轉換成只有x,y的二維屏幕坐標。只有這樣當旋轉三維圖形時候,二維文字一直會顯示在正面。

SharpGL中提供了OpenGLSceneGraphExtensions.Project,可以處理此類問題。

繪製刻度的代碼:

for (float i = 0; i<= 4;i=i+0.5f )

{

gl.Begin(OpenGL.GL_LINE_STRIP);

gl.Vertex(-0.04f, i, 0f);

gl.Vertex(0.04f, i, 0f);

gl.End();

//獲取三維點的二維坐標

var sv =OpenGLSceneGraphExtensions.Project(gl, new Vertex(0.05f, i, 0.0f));

gl.DrawText((int)(sv.X), (int)(sv.Y),1, 1, 1, "宋體",10, (i * 1000).ToString());

}

注意:我們這裡只是示例,實際使用過程中可能需要根據一口井連續測斜數據,找到最大的東西位移和南北位移,然後結合井深來確定坐標刻度的大小。比如:東西位移和南北位移加起來不夠100米,那最大刻度值就設置成100米。又例如:井深10000米,南北和東西位移都比較小,還需要調整深度和底部面的比例尺範圍,讓圖形顯得更正常。而不是去顯示一條特別長,沒有什麼彎度的軌跡線。

繪製深度軸刻度方式與上面的類似。

繪製井眼軌跡線/投影線

井眼軌跡線分真正的井眼軌跡線(黃色),還有在背景面,左側面,和底部面的投影線。

這裡涉及到比例尺換算的問題,我們需要把井的實際井深換算到三維圖裡的世界坐標位置。具體做法如下根據測斜點測量井深和方位角算出該測點的的實際井垂深,根據垂深算出該測斜點的Y坐標值(比如:井深1000米對應三維高度4)。

根據測點方位角,計算出東西位移和南北位移值,然後換算出X坐標和Y坐標。這些內容與軟體技術沒什麼關係,就不細說了。

設置顏色

gl.Color(1.0f, 1.0f, 0f);

gl.LineWidth(1f);

//繪製連續的曲線

gl.Begin(OpenGL.GL_LINE_STRIP);

//獲取井眼軌跡的三維坐標值

var vertexList = LoadWellVertexList()

foreach(var vertex in vertexList)

{

//繪製測點

gl.Vertex(vertex);

}

繪製投影線就更簡單了,把測點對應的投影面的坐標設置為0即可。

繪製水平投影圖,把所有測點的Z坐標設置為0進行繪製。

繪製井底點水平線

查找到最底部的測點,然後繪製一條到Y軸的直線即可。

縮放/旋轉

縮放和旋轉就更簡單了

聲明一個縮放值變量,用滑鼠滾軸進行控制,對圖進行縮放。

gl.Scale(ScaleValue, ScaleValue, ScaleValue);

旋轉使用方法:

gl.Rotate(rtri,0.0f, 1.0f, 0.0f);

感興趣可以去查手冊。

五、後續完善

可以在井口處使用三維工具軟體設計好的模型,加載進來,效果好看很多。

井眼軌跡也可以使用材質渲染出一個實際的井的外觀,現在只畫一條線很醜。

增加光照和陰影效果

相關焦點

  • 三維CAD實例教程:使用中望3D設計葉輪
    三維CAD實例教程:使用中望3D設計葉輪 2016年08月09日 13:44作者:薛麗潔編輯:薛麗潔文章出處:泡泡網原創 葉輪的造型獨特,而在中望3D中,僅需要通過旋轉、圓周陣列、掃掠、拉伸、倒圓角等功能即可輕鬆完成葉輪的建模設計。在本篇文章中,小編將以圖1中的葉輪為實例,向大家介紹如何使用中望3D進行葉輪設計。
  • 3D建模軟體哪個好?3D建模軟體排行榜
    3D建模就是通過三維製作軟體構建出具有三維數據的模型,目前使用最多的3D建模軟體就食3DMAX,下面跟小編一起來看看還有哪些好用的3D建模軟體吧!  一、3D MAX3DS MAX廣泛應用於廣告、影視、工業設計、建築設計、多媒體製作、遊戲、輔助教學以及工程可視化等領域。
  • 基於中望3D的漸開線齒輪三維CAD建模
    基於中望3D的漸開線齒輪三維CAD建模 2013年07月16日 12:19作者:廠商投稿編輯:李萬裡文章出處:泡泡網原創 本文將詳細介紹怎麼通過三維cad軟體快速解決以上問題。  本文以易學易用的中望3D為例,為讀者提供了齒輪的方程公式也可以自定義齒輪方程公式參數模板,給CAD設計師在設計齒輪時帶來了更高的效率。由於中望3D具有自帶的「邊學邊用」學習系統,因此非常適合三維CAD初學者使用。
  • 「勘探」超深電磁數據的三維反演
    也許可以使用其他圖像工具來確定油井是如何偏離該砂體,但是對於該位置或河道砂是否繼續存在,仍有很大的不確定性。這種情形可以用一個簡單的模型來表示,然後使用三維算法進行反演,以展示三維油藏評價的優勢(圖2)。
  • Qudro FX1700部署Petrel三維地質建模軟體
    油藏勘探與Petrel    由全球最大的油田技術服務商斯倫貝謝公司提供的Petrel是惟一一個完全整合到完整的油藏描述系統中的油藏精細描述、建模工具。其他商業化三維建模系統都只是獨立的軟體,而不是一個一體化油藏描述軟體的一部分,真正的一體化油藏描述軟體應包括從地震解釋、儲層建模到油藏模擬的所有領域。
  • 2020年煤礦三維通風仿真系統軟體與建模技術培訓
    使用計算機圖形技術建立礦井真三維通風網絡模型,對巷道的斷面、風阻以及通風構築物等參數進行賦值,實現通風系統的數位化和三維可視化,然後通過成熟的算法對通風網絡數據進行處理、解算,對通風過程進行動態模擬,從而為礦山管理人員和技術人員提供必要的數據支持,以輔助通風和生產決策。
  • 傾斜攝影和雷射掃描技術在城市三維建模中的融合應用研究
    摘 要: 基於提高傾斜攝影技術在城市三維建模效果目的,採用了地面雷射掃描技術在傾斜攝影建模基礎上進行匹配融合的方法,通過對某個小區建築物進行無人機傾斜攝影和地面擺站雷射掃描相結合的數據處理實驗,得出了通過兩者技術融合在城市建築三維模型建設中紋理效果有效提升的可行性結論,並在實驗結論中提出了改進意見。
  • 「3d掃描儀結合3d列印技術」學校3d創新教育的一把利器
    那麼3d掃描儀和3d列印技術是怎麼樣配合應用呢?3d列印技術獨特的魅力就在於所想即所得,可以輕鬆完美實現師生的創意和想像。問題是3d印表機要怎麼樣讀取我們的構想呢?解決這個問題,目前仍然離不開機器語言:數位化模型。這對於師生創客來講,也許是唯一棘手的問題。
  • Facebook AI 正在升維突破:教AI像人類一樣理解三維世界
    ,比如將二維圖片中的沙發、餐桌和茶几以三維建模的方式重現出來。 研究團隊相信,通過加強對三維物體的了解,AI 可以更緊密地連接二維和三維世界,在計算機視覺領域扮演更重要的角色,推動 3D 列印、AR 和 VR 等技術在現實生活中的進步,將這些技術拓展到更廣泛的任務上,最終像人類一樣理解三維世界。
  • 3d物聯網之工業3D數字可視化三維仿真技術解決方案
    一:項目方案介紹3D工業物聯網3d可視化解決方案是結合3D物聯網利用三維仿真、數字映射、人工智慧和大數據等技術,在三維仿真世界使用三維建模技術對真實場景進行一比一高度仿真還原。通過3D數字可視化技術讓界面簡單直觀的展示現監控信息,防止突發事故,提高工作效率。
  • 一張圖實現3D人臉建模!中科院博士ECCV的新研究
    所謂穩定,是指在視頻的相鄰幀中,重建的三維圖像的變化應該與真實物體的細粒度移動保持一致。然而,現有的大多數方法都無法滿足這一要求,也難以避免隨機抖動的影響。此外,由於沒有公開的三維密集人臉配準的視頻資料庫,採用視頻進行預訓練的方法也行不通。那麼還有其他什麼辦法能改善靜態圖像轉化視頻的穩定性?
  • CAXA三維CAD教程:平面圖快速生成三維圖
    CAXA實體設計(三維CAD)是唯一集創新設計、工程設計、協同設計於一體的新一代三維 CAD解決方案。它包含三維建模、協同工作和分析仿真等各種功能,其無可匹敵的易操作性和設計速度幫助工程師將更多的精力用於產品設計本身。
  • 衛星影像也能實景三維建模——用三維遠觀地球
    從衛星影像上獲取三維模型的方式,數據獲取不受限制,可以快速獲取大範圍的三維模型。像素工廠從16年開始已經具備衛星三維生成技術,如今已經用於實際生產項目當中,成為一種成熟的解決方案。  本文就像素工廠的衛星三維技術,以及一些用戶案例做一些介紹。
  • 三維CAD實例:用中望3D設計花瓣吊燈(中篇)
    在上篇的教程文章中,我們已經掌握了使用三維CAD軟體中望3D設計燈座的建模操作,而本篇教程中,則將重點介紹吊燈支撐杆建模的操作以及對應的焊縫創建。首先,我們來看看支撐杆建模的具體操作步驟。使用「草圖模塊」下的「參考」命令,把圖3中的曲線進行提取,如圖7所示。
  • 無人機空地一體三維雷射掃描技術應用研究
    但傳統的三維雷射技術與應用有許多弊端: 傳統三維建模方式從數據採集到成圖周期太長,如航測; 傳統街景方式為二維,清晰度低,不夠逼真; 傳統城市部件採集方式效率低。 因此,現代三維雷射技術基本上都是基於地面或機載某種單一方式,或將兩種方式結合在一起的應用。
  • 基於中望3D的漸開線齒輪三維CAD建模教程
    本文將詳細介紹怎麼通過三維cad軟體快速解決以上問題。  本文以易學易用的中望3D為例,為讀者提供了齒輪的方程公式也可以自定義齒輪方程公式參數模板,給CAD設計師在設計齒輪時帶來了更高的效率。由於中望3D具有自帶的「邊學邊用」學習系統,因此非常適合三維CAD初學者使用。
  • 基於微小井眼鑽井技術的A/D轉換器選型研究
    摘要:微小井眼鑽井技術是國外近年來發展起來一種前沿技術,具有成本低、安全環保和勘探開發效率高等特點。通過A/D、D/A轉換器將井下模擬信號轉換為數位訊號,經處理後,將數位訊號在轉換成模擬信號去控制設備,實現井下的採集、通訊、控制任務。
  • 國漫崛起了,但你知道3D動漫的製作過程嗎?
    三維動畫軟體在計算機中首先建立一個虛擬的世界,不受時間、空間、地點、條件、對象的限制,可以運用各種表現形式把複雜、抽象的內容用形象、生動的形式表現出來,能做到脫離真人拍攝的需要,還能達到真人拍攝的逼真效果。最後按要求為模型賦上特定的材質,並打上燈光。當這一切完成後就可以讓計算機自動運算,生成最後的畫面。
  • 亦明圖記:SolidWorks繪製花籃,使用圓周陣列生成的完美效果
    3d花籃模型:使用SolidWorks2014繪製;繪製過程:1、在前視基準面上繪製草圖 直線;2、拉伸曲面:兩側對稱100;點擊關注@亦明圖記 進入主頁觀看更多精彩內容。精彩回放:亦明圖記:SolidWorks繪製奔馳車標,拉伸凸臺建模,過程只需4步
  • 高精度3d雷射掃描儀大空間雷射掃描三維掃描技術對老舊工廠改造
    打開APP 高精度3d雷射掃描儀大空間雷射掃描三維掃描技術對老舊工廠改造 發表於 2020-04-12 10:05:31 三維掃描技術對老舊工廠改造 項目背景 對於這些老舊工業廠房,現在有很多種處置態度,完全保留不動或是全部拆除都不是很好方法