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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

3DTools TrackballDecorator实现3D漫游

發布時間:2023/12/16 编程问答 60 豆豆
生活随笔 收集整理的這篇文章主要介紹了 3DTools TrackballDecorator实现3D漫游 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.基本原理

WPF提供的TrackballDecorator類用來實現三維漫游功能。TrackballDecorator可以看做是在Viewport3D后面的一個虛擬球面,當鼠標點擊TraclcballDecorator投影在Viewport3D的這個平面內時,可以在球面上找到與鼠標在平面上面一一對應的一個點。當鼠標運動的時候,照相機根據鼠標的運動來旋轉,以此來保證鼠標在這個虛擬球面上的位置是不變的。這樣就完成了把把鼠標的二維運動轉換為三維運動。下面以一個立方體為模型,簡單說明一下上述過程。


圖1.1 Viewport3D與TtackballDecorator位置關系



圖1.2 鼠標垂直拖動

圖1-2表示當鼠標進行垂直移動的時候,球面繞X軸進行旋轉,來保證鼠標在球面上的位置是不變的,同時球面內的模型會跟隨球面運動,就能得到預期的效果。

2.實現過程

對于每次鼠標移動,都需要計算一個旋轉來保證鼠標在球面上的位置是不變的。因此需要做以下兩個工作:首先,確定鼠標在球面上的位置;其次,計算鼠標從一個點移動到另一個點所進行的旋轉。為了找到鼠標在球體上對應的點,將UIElement坐標系中的二維點投影到的Viewport3D內部的球面上。

(1)首先如何將二維點映射到Viewport3D內部球面呢?下面顯示了兩個坐標系。


2.1 二維坐標系


2.2 三維坐標系

如圖2-1所示,鼠標顯示了其在UIElement坐標系中的位置,原點(0,0)位于坐標系的左上角。在圖2-2中把鼠標映射到Viewport3D內部的球面上,鼠標的坐標也變換為了三維坐標系中的坐標。

由于最終的目的是得到相機的旋轉,因此可以選擇最簡單的TrackballDecorator球面坐標系,因此可以假定這個球面半徑為1,其圓心為坐標系的原點(0,0,0)。只需要構建一個[0,0]—[2,2]的Viewport3D,然后將原點從左上角移動至中心,這樣 ViewportsD 就變成了從[-1,1]一[1,-1]。如圖 2-3,圖 2-4 所示。


2.3 建一個寬、高為2的Viewport3D


2.4 將原點平移至中心

假設鼠標在UIElement坐標系的坐標為(Px, Py),在TrackballDecorator坐標系中的坐標為(x,y, z)那么可得出x,y點坐標如式2-1,2-2所示。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?


根據球面半徑,就能得到Z坐標如式2-3所示。



獲取三維坐標信息代碼:

private Vector3D ProjectToTrackball(double width, double height. Point point) { double X = point.X / (width / 2); double y = point. Y / (height / 2); X = X - 1; y = 1 - y; double z2=l-x*x-y*y; double z = z2 > 0 ? Math.Sqrt(z2): 0; return new Vector3D(x, y, z); }

這樣就得到了鼠標在球面上的坐標(x,y,z)對于鼠標的每次拖動,都需要構建一個旋轉,使得鼠標在球面上的位置保持不變。因此需要記錄鼠標拖動之前的坐標,和鼠標拖動到當前位置的旋轉。為了得到這個旋轉需要計算旋轉軸和旋轉角度。



2.3用向量來描述鼠標的拖動

如圖2.3所示向量VI和向量V2分別為原點到鼠標拖動前所在位置和拖動后所在位置的向量。可以簡單計算得到旋轉軸Axis和旋轉角度0,如式2-4、2-5所示。


//根據右手定則,兩向量叉乘,確定垂直兩向量的軸,即旋轉軸




Θ為球面的旋轉角度,取Θ的相反數就得到了照相機的旋轉角度,當有了旋轉軸和旋轉角度就可以控制的照相機去進行旋轉。

//響應漫游

private void Track(Point currentPosition) { Vector3D currentPosition3D =ProjectToTrackball( EventSource.Actual Width,EventSource.ActualHeight, currentPosition);Vector3D axis =Vector3D.CrossProduct(_previousPosition3D, currentPosition3D); double angle =Vector3D.AngleBetween(_previousPosition3D, currentPosition3D); Quaternion delta = new Quaternion(axis, -angle); AxisAngleRotation3D r = _rotation; Quaternion q = new Quatemion(_rotation.Axis, _rotation.Angle); q*= delta; _rotation.Axis = q.Axis; _rotation.Angle = q.Angle; _previousPosition3 D = currentPosition3D; } 3.源代碼

點擊打開鏈接


總結

以上是生活随笔為你收集整理的3DTools TrackballDecorator实现3D漫游的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。