根据博文:https://www.cnblogs.com/duel/p/regular3dpoints.html获取足球的3D坐标后,在每一个坐标位置创建一个ModelVisual3D元素,既能实现炫酷的3D界面。在此基础上我基于这些点构建了3D足球。

动态效果图:

每一个足球的块上,我贴上了不同的图,点击图获取对应的信息在右侧显示。

实现原理:

首先对所有顶点根据Y值进行分层,第一层的顶点见下图:

所有与第一层相互连接的点为第二层:

以此类推,总共可获得八层顶点。

然后,拿到第一层(第一组)的顶点(5个),第一组五个顶点组成了正五边型,正五边形每一条边对应两个顶点,根据距离计算,可以从第二层中找到与第一层顶点距离最近的点,如下图第一层的正五边形的其中一条边AB,在第二层中可以通过计算拿到与A、B两个点距离最近的C、D两个点。然后以C、D作为基点从第三层中又可以得到同时距离C、D 两个点距离最近的两个点E、F。

 

从上面两个图你可以直观的看见,在第二层中分别与A、B距离最近的点只能是C、D。 在第三层中同时距离C点和D点最近的点只能是E、F。  ABCDEF六个点即构成了足球的一个面。

按照这种以层级和距离的方式即可计算得到足球的每一面所包含的3D坐标。

循环计算实现逻辑代码:

  1. // Get Bucky Ball all Blocks
  2. private void GetBuckyBallBlocks()
  3. {
  4. // BuckyBallPoints -> List<List<Point3D>>
  5. int nLevelCount = BuckyBallPoints.Count; // 总层数 - 8
  6. for (int i = ; i < nLevelCount; i++) //
  7. {
  8. int nCurLevel = i; //当前层
  9. // 下一层
  10. int nSecondLevelBaseCur = nCurLevel + ;
  11. // 第三层
  12. int nThirdLevelBaseCur = nCurLevel + ;
  13.  
  14. // three levels as a group, and every group defined five blocks
  15. //(1,2,3)(2,3,4)(3,4,5)(4,5,6)(5,6,7)(6,7,8)
  16. if (nThirdLevelBaseCur < nLevelCount)
  17. {
  18. // 计算距离,根据距离判断是否属于同一个面
  19. this.CalculateBuckyBallBlocks(BuckyBallPoints[nCurLevel],
  20. BuckyBallPoints[nSecondLevelBaseCur],
  21. BuckyBallPoints[nThirdLevelBaseCur]);
  22. }
  23. }
  24. // 第一层(现成的正五边形)
  25. this.BuckyBallBlocks.Add(BuckyBallPoints[]);
  26. // bottom block points 第八层(现成的正五边形)
  27. this.BuckyBallBlocks.Add(BuckyBallPoints[BuckyBallPoints.Count - ]);
  28. }

通过以上方式获得每一个面对应的顶点坐标后,即可通过坐标构建平面。

关键代码:

  1. // 根据顶面创建3D平面
  2. private MeshGeometry3D CreateBlockMeshGeometry3D(List<Point3D> ltPoints)
  3. {
  4. Point3D[] Point3Ds = new Point3D[ltPoints.Count];
  5. for (int i = ; i < ltPoints.Count; i++)
  6. Point3Ds[i] = ltPoints[i];
  7.  
  8. MeshGeometry3D oGeometry = new MeshGeometry3D()
  9. {
  10. Positions = new Point3DCollection(Point3Ds)
  11. };
  12.  
  13. if (ltPoints.Count == )
  14. oGeometry.TriangleIndices = new Int32Collection(new int[] { , , , , , , , , , , , });
  15. else if (ltPoints.Count == )
  16. oGeometry.TriangleIndices = new Int32Collection(new int[] { , , , , , , , , });
  17. else
  18. ShowErrorAndExit();
  19.  
  20. PointCollection texCoords = new PointCollection();
  21. for (int i = ltPoints.Count -; i >= ; i--)
  22. texCoords.Add(new Point(ltPoints[i].X, ltPoints[i].Y));
  23. oGeometry.TextureCoordinates = texCoords;
  24.  
  25. return oGeometry;
  26. }

最后给每一个构建的平面的Visual属性附上加载的图片和点击事件既能实现我Demo中的效果。

最后附上Demo整体效果图:

工具:Visual Studio 2017

工程:WPF C#

源代码下载

WPF 3D足球导览的更多相关文章

  1. WPF 3D 球面导览

    基于WPF的3D Sphere实现模式,升级实现了该3D导览Demo.先pose一张demo效果图 所有顶点的坐标来源于足球的顶点.足球整个球面完全由正五边形和正六边形拼成,每条拼缝的长度一致,故知道 ...

  2. WPF特效-实现3D足球效果

    原文:WPF特效-实现3D足球效果 WPF 实现 3D足球效果,效果图如下:  每个面加载不同贴图. <UserControl x:Class="MediaBalll.Model3Ds ...

  3. WPF 3D 知识点大全以及实例

    引言 现在物联网概念这么火,如果监控的信息能够实时在手机的客服端中以3D形式展示给我们,那种体验大家可以发挥自己的想象. 那生活中我们还有很多地方用到这些,如上图所示的Kinect 在医疗上的应用,当 ...

  4. 优化WPF 3D性能

    Maximize WPF 3D Performance .NET Framework 4.5   As you use the Windows Presentation Foundation (WPF ...

  5. WindowsPhone开发—— 使用手绘图片做景区导览地图

    前些日子在做景区App遇到需求,使用手绘图片做一个简易的地图,支持放大缩小平移以及显示景点Mark,安卓上可以使用一个叫做“mAppWidget”的开源库来完成,WP上有人建议用ArcGIS,但是考虑 ...

  6. js矩阵菜单或3D立体预览图片效果

    js矩阵菜单或3D立体预览图片效果 下载地址: http://files.cnblogs.com/elves/js%E7%9F%A9%E9%98%B5%E8%8F%9C%E5%8D%95%E6%88% ...

  7. WPF 3D 小小小小引擎 - ·WPF 3D变换应用

    原文:WPF 3D 小小小小引擎 - ·WPF 3D变换应用 WPF可以提供的3D模型使我们可以轻松地创建3D实体,虽然目前来看还很有一些性能上的问题,不过对于一些简单的3D应用应该是可取的,毕竟其开 ...

  8. WPF 3D 常用类(1)

    原文:WPF 3D 常用类(1) 几何数据相关类 Geometry3D 抽象类, 用于定义物体的几何数据, 可用于计算HitTest和BoundingBox MeshGeometry3D Geomet ...

  9. WPF 3D:使用GeometryModel3D的BackMaterial

    原文 WPF 3D:使用GeometryModel3D的BackMaterial 使用BackMaterial,我们可以定义3D物体的内部材质(或者说是背面),比如,我们定义一个四方体容器,外面现实的 ...

随机推荐

  1. 【Luogu P1439】最长公共子序列(LCS)

    Luogu P1439 令f[i][j]表示a的前i个元素与b的前j个元素的最长公共子序列 可以得到状态转移方程: if (a[i]==b[j]) dp[i][j]=dp[i-1][j-1]+1; d ...

  2. ehcache同步原理

    最近研究ehcache同步时发现一个问题: 现有A.B两个服务器,由A服务器向B服务器同步信息,采用RMI方式手动方式进行同步 配置信息如下: <?xml version="1.0&q ...

  3. Unicode和Ascii的区别

    计算机只能处理数字,如果要处理文本,就必须把文本转换成数字.    最早的计算机设计采用8bit作为一个字节,所以,一个字节只能表示的最大整数255.   0-255被用来表示数字和一些符号,这个编码 ...

  4. OAuth 2.0 概念及授权流程梳理

    本文可以转载,但请注明出处https://www.cnblogs.com/hellxz/p/oauth2_process.html OAuth2 的概念 OAuth是一个关于授权的开放网络标准,OAu ...

  5. 安装nvm管理多版本nodejs

    1.简介(什么是nvm) Node Version Manager(node版本管理器),用它在机器上安装并维护管理多个Node的版本 2.nvm临时切换(临时切换版本,只在当前终端内有效,新开终端无 ...

  6. 浅析vue混入(mixin)

    vue中的混入,可以在一定程度上提高代码的复用性.通俗来说,混入类似于“继承”,当前组件对象继承于组件对象,一般情况下遵循“就近原则”.但是与继承不同的是,继承一般都跟随着属性的重写与合并,混入在不同 ...

  7. Spring Boot 自动装配(二)

    目录 目录 前言 1.起源 2.Spring Boot 自动装配实现 2.1.@EnableAutoConfiguration 实现 2.1.1. 获取默认包扫描路径 2.1.2.获取自动装配的组件 ...

  8. ThinkPHP5——route(路由)的详解

    路由在框架中的作用打个比方的话,路由好比是WEB应用的总调度室,对于访问的URL地址,路由可以拒绝或者接受某个URL请求,并进行分发调度,而且还有一个副作用是因为路由规则可以随意定义,因此可以让你的U ...

  9. 八分音符(频率)卷积算子 Octave Convolution

    为什么读此系列文章? 优化数学和计算理论帮助机器学习完成问题分类: 1)按照领域划分,比如计算机视觉,自然语言处理,统计分析预测形: 2)按照算法复杂划分,比如是否是NP-Hard问题,是否需要精确解 ...

  10. 【Python成长之路】从 零做网站开发 -- 基于Flask和JQuery,实现表格管理平台

    [写在前面] 你要开发网站?    嗯.. 会Flask吗?    什么东西,没听过... 会JQuery吗?    是python的库吗 ? 那你会什么?    我会F12打开网站 好吧,那我们来写 ...