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

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

一、前言

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

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

支持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的實例教程中,以花瓣吊燈的建模設計為例,幫助大家在學習設計燈具產品的同時,掌握常規的三維CAD實體建模和曲面建模技巧。
  • 基於中望3D的漸開線齒輪三維CAD建模
    基於中望3D的漸開線齒輪三維CAD建模 2013年07月16日 12:19作者:廠商投稿編輯:李萬裡文章出處:泡泡網原創 本文將詳細介紹怎麼通過三維cad軟體快速解決以上問題。  本文以易學易用的中望3D為例,為讀者提供了齒輪的方程公式也可以自定義齒輪方程公式參數模板,給CAD設計師在設計齒輪時帶來了更高的效率。由於中望3D具有自帶的「邊學邊用」學習系統,因此非常適合三維CAD初學者使用。
  • 3D建模軟體哪個好?3D建模軟體排行榜
    3D建模就是通過三維製作軟體構建出具有三維數據的模型,目前使用最多的3D建模軟體就食3DMAX,下面跟小編一起來看看還有哪些好用的3D建模軟體吧!  一、3D MAX3DS MAX廣泛應用於廣告、影視、工業設計、建築設計、多媒體製作、遊戲、輔助教學以及工程可視化等領域。
  • 3Dmax高級建模技巧總結,收藏了!3D建模軟體大全
    適用於製作平面布置圖、地材圖、 水電圖、節點圖及大樣圖等。廣泛應用於土木建築、裝飾裝潢、城市規劃、園林設計、電子電路、機械設計、航空航天、輕工化工等諸多領域。大家買房時看的房型圖大部分都是用AutoCAD來做的。
  • JUST技術:基於無參生成模型的行人軌跡生成
    背景想要建模城市中的人群移動特性是很有挑戰的:1)軌跡狀態空間很大;2)軌跡具有很強的獨一無二性,很難找到兩個軌跡完全相同的人;3)人群的軌跡具有相似的隱式語義,比如上班、下班、旅遊,需要用有效的表徵刻畫出這些相似的語義來;4)軌跡序列內的位置相關性與軌跡間的相關性難以顯式定義。
  • 3d建模軟體手機版有哪些?這3款好用的手機3d建模軟體你一定要有
    3d建模軟體手機版有哪些?對於一些三維設計師來說,能夠在手機上隨時隨地進行三維建模是一件很方便的事。本期,模型云為您整理了這3款好用的手機3d建模軟體介紹,快來和我們一起看看吧!3款好用的手機3d建模軟體3d建模軟體手機版一:MeshMixerMeshMixer是一款操作簡單的手機3d建模工具,其主要功能包括3D列印改進、製造切片工具、拖放及把原本組合在一起的多個不同的幾何體分成單獨的對象等,且支持PLY二進位格式、3Dconnexion
  • 基於AutoCAD的三維實體建模探討
    結合實例從UCS坐標系、固層、多視口、實體編輯將二維圖形生成三維實體等方面,對三維實體建模進行了研究探討,旨在提高三維實體建模效率。    隨著計算機技術的飛速發展,三維CAD軟體日趨成熟,三維實體造型開始廣泛應用於產品或工程設計。目前,常用的三維建模軟體主要有AutoCAD、Pro/Engineer、UG、Solidwork、CAXA等。
  • 建模師迎來了最大職場危機!一張圖片就能快速生成3D角色
    只需要一張頭像照片,就能實時生成3D數字人類角色,自帶面部表情變形,身體骨骼!角色身體調整項多達1000+,可以隨意調整面部、身材造型,絕對是3d動畫、遊戲角色模型利器!整個過程從Jpeg頭像照片到動態模型只需要9分鐘的時間!這聽上去是不是很瘋狂?我們的建模師難道要被AI取代了嗎?
  • 3D電子圍欄搭建的小方法,使安防運維效率大幅提高
    本篇文章通過對工廠可視化場景的搭建和模型的加載,人物實時定位代碼的實現、電子圍欄和軌跡圖的實現進行闡述,幫助我們了解如何通過使用HT實現一個簡單的3D電子圍欄可視化。 代碼實現 人物模型及場景 項目中使用的人物模型是通過 3dMax 建模生成的,該建模工具可以導出 obj 與 mtl 文件,在 HT 中可以通過解析 obj 與 mtl 文件來生成 3d 場景中的攝像頭模型
  • 三維CAD繪圖技巧攻略:中望3D使用感悟
    進入21世紀以來,隨著信息技術的迅猛發展,一場新的工業設計領域的技術革命正在興起,製造業的信息化已成為發展的必然趨勢。傳統CAD系統主要針對產品二維工程圖的繪製與零件的三維設計,缺乏對產品創新和設計的足夠關注和有效的支持。而三維CAD則涵蓋從產品設計和製造的全套開發流程。
  • CAXA三維CAD教程:平面圖快速生成三維圖
    CAXA實體設計(三維CAD)是唯一集創新設計、工程設計、協同設計於一體的新一代三維 CAD解決方案。它包含三維建模、協同工作和分析仿真等各種功能,其無可匹敵的易操作性和設計速度幫助工程師將更多的精力用於產品設計本身。
  • 無人機+人工智慧,簡化3D場景建模
    今天我們就來了解一下利用無人機+人工智慧技術,簡化3D場景建模的應用。在此之前,我們在做大數據可視化的項目,很多客戶提出更高的要求,這其中就是利用3D技術,來呈現例如校園全貌,園區展示等。如下圖:於是,開始思考構建一套可視化建模的平臺,來簡化人工操作。
  • 三維CAD實例:用中望3D設計花瓣吊燈(中篇)
    [摘要]在上篇的教程文章中,我們已經掌握了使用三維CAD軟體中望3D設計燈座的建模操作,而本篇教程中,則將重點介紹吊燈支撐杆建模的操作以及對應的焊縫創建。首先,我們來看看支撐杆建模的具體操作步驟。第一步:支撐杆草圖繪製以XZ工作平面為基準,創建草圖。使用草圖模塊下的參考命令,拾取下圖1中黃色曲面提取參考線。
  • 3d模型製作軟體有哪些?6款常用的3d模型製作軟體推薦
    下載地址:Blender  二、moimoi  moi3d又名自由設計大師,是一款非常好用且功能強大的專業精準三維建模軟體,軟體雖然體積小巧,但是功能卻十分強大,它大大地簡化了建模的流程,能夠有效地提高設計師的工作效率,並可以完美兼容cad文件格式,能夠輕鬆地繪製出各種直線曲線矩形多邊形
  • iPad建模神器 —「Shapr3d」
    小編雖然是美術專業,但對於設計與3D建模根本沒有具體的概念,只是知道設計系的同學一般使用3D Max,自己曾想學習,但是看到複雜的操作界面與專業術語我就知道自己可能跟這個領域無緣了。直到有一天我在iPad Pro上遇到了「Shapr3d」這款App,這款App讓我徹底改變了對3D建模的認識,原來可能需要很長時間的專業學習,但是到了iPad Pro上藉助觸控屏與Apple pencile的精準指向,現在3D建模原來可以如此輕鬆。
  • 中望CAD建模功能操作便捷,滿足用戶三維繪圖需求
    中望CAD雖多數情況下被用於平面繪圖,但軟體具有三維坐標系統,包含了基本的三維建模功能。由於建模比較自由,且尺寸精準,標註方便,同時還可對模型設置材質並渲染出圖,中望CAD在五金、現代板式家具等設計中能夠幫助工程師快速高效建立三維模型,滿足設計需求。
  • 動畫公司介紹3d人物建模軟體有哪些
    隨著3d動畫的商業化趨勢,許多人想學習從事相關的製作,首先需要了解基礎人物的設計建模。下面藝虎動畫介紹,3d動畫人物建模軟體有哪些。 2、3DS Max 3D Studio Max簡稱3DS MAX,是當今銷售量大的三維建模、動畫及渲染軟體。可以說3DSMAX人物建模是容易上手的3D軟體,其早應用於計算機遊戲中的動畫,後開始參與影視片的製作。
  • Mars說光場(5)— 光場在三維人臉建模中的應用
    然而目前國內對光場(Light Field)技術的中文介紹十分匱乏,曹煊博士《Mars說光場》系列文章旨在對光場技術及其應用的科普介紹。曹煊博士系騰訊優圖實驗室高級研究員。優圖— 騰訊旗下頂級的機器學習研發團隊,專注於圖像處理、模式識別、深度學習。在人臉識別、圖像識別、醫療AI、OCR、哼唱識別、語音合成等領域都積累了領先的技術水平和完整解決方案。
  • 吊鉤,如何用AutoCAD繪製二維圖及三維建模
    AutoCAD吊鉤建模方法:●效果如下圖說明:繪製引吊鉤CAD三維立體模型,需要有一定的CAD三維建模能力。●操作方法第1步:打開CAD吊鉤平面圖--並複製一份--將複製出來的平面圖尺寸全部刪除--進入等軸軸測空間。
  • 花瓣吊燈實例(下):用中望3D進行燈罩的建模設計
    經過了前面兩篇文章的介紹,大家對如何使用三維CAD軟體中望3D進行花瓣吊燈主體的設計都已經清晰明了了,那麼在本篇中,我們將對剩餘部分的三維CAD設計進行介紹。下面,我們來看看吊燈的點綴之處——花瓣燈罩的建模設計。