小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

WPF 3D 獲取鼠標(biāo)在場(chǎng)景的3d坐標(biāo)

 xyjackxjw 2013-05-09

WPF 3D 獲取鼠標(biāo)在場(chǎng)景的3d坐標(biāo)

時(shí)間:2010-12-03 19:56來源:博客園 作者:ustc_msra_ase 點(diǎn)擊: 653次
上一篇中我們談到了WPF 3d做圖的一些簡(jiǎn)單原理,這里我們簡(jiǎn)單介紹一下怎樣獲得鼠標(biāo)在場(chǎng)景中的3d坐標(biāo),知道了3d坐標(biāo)就可以進(jìn)行很多操作了: 首先介紹一下3d圖形的構(gòu)成以及它的一些成員屬性: 在 3D 圖形編程中,沒有線條、Bezier 樣條曲線、矩形或橢圓。每個(gè) 3D 物體都是三維坐標(biāo)空間中的三角形的集合。三角形是 3D 編程的基
  

  上一篇中我們談到了WPF 3d做圖的一些簡(jiǎn)單原理,這里我們簡(jiǎn)單介紹一下怎樣獲得鼠標(biāo)在場(chǎng)景中的3d坐標(biāo),知道了3d坐標(biāo)就可以進(jìn)行很多操作了:

  首先介紹一下3d圖形的構(gòu)成以及它的一些成員屬性:

  在 3D 圖形編程中,沒有線條、Bezier 樣條曲線、矩形或橢圓。每個(gè) 3D 物體都是三維坐標(biāo)空間中的三角形的集合。三角形是 3D 編程的基本單位,這是因?yàn)槊總€(gè)單獨(dú)的三角形總是能定義一個(gè)平面,而三角形集合可以模仿立體物體,甚至可以模擬曲面。3D 視圖由 Viewport3D 元素組成。3D 場(chǎng)景需要一個(gè)或多個(gè) GeometryModel3D 類型的物體、一個(gè)或多個(gè)光源、以及一個(gè)用于控制 3D 物體如何投射到 2D 表面從而控制觀看者如何看到圖像的攝像機(jī)。

  GeometryModel3D 元素有三個(gè)重要屬性:Geometry、Material 和 BackMaterial。

  Geometry 屬性被設(shè)置為 MeshGeometry3D 元素,用于根據(jù)坐標(biāo)點(diǎn)和三角形描述可視物體。

  Material 和 BackMaterial 屬性說明物體的前面和背面如何著色。

  MeshGeometry3D 類,該類用于定義 3D 物體的實(shí)際幾何表示形式。該類有四個(gè)重要屬性:Positions、TriangleIndices、TextureCoordinates 和 Normals。

  Positions 屬性表示物體的所有頂點(diǎn)。這些頂點(diǎn)在定義物體時(shí)肯定是有作用的,但它們不能描述所有信息。任何一組三個(gè)頂點(diǎn)都可以組合成一個(gè)三角形,這就是 TriangleIndices 集合所說明的內(nèi)容

  TriangleIndices 集合實(shí)際上驅(qū)動(dòng)物體的呈現(xiàn)。TriangleIndices 未引用的任何 Positions 元素都會(huì)忽略(如果沒有 TriangleIndices,則 Positions 集合中的每個(gè) Point3D 三聯(lián)數(shù)都將解釋為一個(gè)三角形)。每個(gè)三角形都應(yīng)有正面和背面。查看三角形的正面時(shí),三聯(lián)數(shù)以反時(shí)針方向表示頂點(diǎn)。如果將第一個(gè)三聯(lián)數(shù)更改為 0 1 3,將看到左上三角形以紅色著色,這是因?yàn)椴榭吹氖侨切蔚谋趁?,而不是它的正面?/P>

  Normals 屬性是按與 Positions 集合的一對(duì)一對(duì)應(yīng)關(guān)系得到的向量的集合。每個(gè)頂點(diǎn)均被視為面向特定方向,該方向以該頂點(diǎn)的 Normals 向量表示。每個(gè)三角形內(nèi)的每個(gè)點(diǎn)基于在其三個(gè)頂點(diǎn)上的向量的內(nèi)插值,以不同方式反射光線。如果不提供 Normals 集合,則會(huì)基于在網(wǎng)格規(guī)范中共享的每個(gè)頂點(diǎn)上會(huì)合的三角形的 Normals 的平均值計(jì)算一個(gè)該集合。

  如果對(duì)其還是不明白,可以參考這一篇文章,這里有比較詳細(xì)的介紹:http://msdn.microsoft.com/zh-cn/magazine/cc163449.aspx

  有了上面的基礎(chǔ),下面我們就來介紹一下怎樣獲得鼠標(biāo)在三維場(chǎng)景中的坐標(biāo):

  主要是通過viewport3d中的三維視覺效果進(jìn)行命中測(cè)試:

  C#源碼如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
public void HitTest(object sender, System.Windows.Input.MouseButtonEventArgs args)

{

    Point mouseposition = args.GetPosition(myViewport);

    Point3D testpoint3D = new Point3D(mouseposition.X, mouseposition.Y, 0);

    Vector3D testdirection = new Vector3D(mouseposition.X, mouseposition.Y, 10);

    PointHitTestParameters pointparams = new PointHitTestParameters(mouseposition);

    RayHitTestParameters rayparams = new RayHitTestParameters(testpoint3D, testdirection);

    //test for a result in the Viewport3D

    VisualTreeHelper.HitTest(myViewport, null, HTResult, pointparams);

  以下代碼中的 HitTestResultBehavior 確定如何處理命中測(cè)試結(jié)果。 UpdateResultInfo 和 UpdateMaterial 是本地定義的方法。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public HitTestResultBehavior HTResult(System.Windows.Media.HitTestResult rawresult)

{

    //MessageBox.Show(rawresult.ToString());

    RayHitTestResult rayResult = rawresult as RayHitTestResult;

    if (rayResult != null)

    {

        RayMeshGeometry3DHitTestResult rayMeshResult = rayResult as RayMeshGeometry3DHitTestResult;

        if (rayMeshResult != null)

        {

            GeometryModel3D hitgeo = rayMeshResult.ModelHit as GeometryModel3D;

        GeometryModel3D hitgeo = rayMeshResult.ModelHit as GeometryModel3D;

        MeshGeometry3D hitmesh = hitgeo.Geometry as MeshGeometry3D;

        Point3D p1=hitmesh.Positions.ElementAt(rayMeshResult.VertexIndex1);

       double weight1 = rayMeshResult.VertexWeight1;

        Point3D p2 = hitmesh.Positions.ElementAt(rayMeshResult.VertexIndex2);

        double weight2 = rayMeshResult.VertexWeight2;

         Point3D p3 = hitmesh.Positions.ElementAt(rayMeshResult.VertexIndex3);

          double weight3 = rayMeshResult.VertexWeight3;

       Point3D prePoint = new Point3D(p1.X * weight1 + p2.X * weight2 + p3.X * weight3,              p1.Y * weight1 + p2.Y * weight2 + p3.Y * weight3, p1.Z * weight1 + p2.Z * weight2 + p3.Z * weight3);

 

            UpdateResultInfo(rayMeshResult);

            UpdateMaterial(hitgeo, (side1GeometryModel3D.Material as MaterialGroup));

        }

    }

    return HitTestResultBehavior.Continue;

}

  代碼可以參見:http://msdn.microsoft.com/zh-cn/library/ms745195.aspx

  紅色代碼就是獲得鼠標(biāo)3d坐標(biāo)的關(guān)鍵,具體解釋一下:

  Hitgeo 是命中測(cè)試hittest的返回結(jié)果,具體屬性可以參見

  http://msdn.microsoft.com/zh cn/library/ms606198.aspx

  通過上面GeometryModel3D的介紹可以知道,hitgeo的geometry屬性就是MeshGeometry3D類型的,也就是三角形網(wǎng)絡(luò)圖形類,

  命中測(cè)試的返回結(jié)果非常豐富,VertexIndex1,VertexIndex2 VertexIndex3 代表的是命中小三角形的頂點(diǎn)坐標(biāo)在整個(gè)3d圖中的點(diǎn)集合的索引,而VertexWeight1 VertexWeight2 VertexWeight3 分別代表了命中點(diǎn)在各個(gè)點(diǎn)所占的權(quán)重,這樣通過權(quán)重和頂點(diǎn)坐標(biāo)我們就可以計(jì)算出鼠標(biāo)點(diǎn)擊的點(diǎn)在三維場(chǎng)景中的坐標(biāo)了。

本文來自u(píng)stc_msra_ase的博客,原文地址:http://www.cnblogs.com/ustc_msra_ase/archive/2010/11/28/1890431.html

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約