栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C# > C#教程

WPF实现3D立方体波浪墙效果

C#教程 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

WPF实现3D立方体波浪墙效果

本文实例为大家分享了WPF实现3D立方体波浪墙效果的具体代码,供大家参考,具体内容如下

实现效果如下:

思路:仿照3D粒子系统,将粒子颗粒的Geometry改造为立方体,鼠标移动时将鼠标位置转为3D场景中的坐标。

步骤:

1、粒子类Particle.cs

public Point3D Position;//位置
public double Width;//长方体底面宽
public double Height;//长方体侧面高

2、粒子系统ParticleSystem.cs

private readonly List _particleList;
private readonly GeometryModel3D _particleModel;
private readonly int CUBOIDHEIGHT = 20;
private readonly int MOUSERADIUS = 1000;
private int XParticleCount;
private int YParticleCount;
public Model3D ParticleModel => _particleModel;
 
public ParticleSystem(int amountX, int amountY, Color color)
    {
      XParticleCount = amountX;
      YParticleCount = amountY;
 
      _particleList = new List();
      _particleModel = new GeometryModel3D { Geometry = new MeshGeometry3D() };
      var material = new DiffuseMaterial(new SolidColorBrush(color));
      _particleModel.Material = material;
    }
 
public void SpawnParticle(double size)
    {
      // 初始化粒子位置和大小
      for (int ix = 0; ix < XParticleCount; ix++)
      {
 for (int iy = 0; iy < YParticleCount; iy++)
 {
   var p = new Particle
   {
     Position = new Point3D(ix * size, iy * size, 0),
     Width = size,
     Height = CUBOIDHEIGHT,
   };
   _particleList.Add(p);
 }
      }
    }
 
public void Update(Point mp)
    {
      foreach (var p in _particleList)
      {
 //求点到圆心的距离
 double c = Math.Pow(Math.Pow(mp.X - p.Position.X, 2) + Math.Pow(mp.Y - p.Position.Y, 2), 0.5);
 p.Height = (MOUSERADIUS / (c + CUBOIDHEIGHT)) * CUBOIDHEIGHT;
      }
      UpdateGeometry();
    }
 
private void UpdateGeometry()
    {
      var positions = new Point3DCollection();
      var indices = new Int32Collection();
 
      for (var i = 0; i < _particleList.Count; ++i)
      {
 var positionIndex = i * 8;
 var p = _particleList[i];
 
 var p1 = new Point3D(p.Position.X, p.Position.Y, p.Position.Z);
 var p2 = new Point3D(p.Position.X + p.Width, p.Position.Y, p.Position.Z);
 var p3 = new Point3D(p.Position.X + p.Width, p.Position.Y + p.Width, p.Position.Z);
 var p4 = new Point3D(p.Position.X, p.Position.Y + p.Width, p.Position.Z);
 var p5 = new Point3D(p.Position.X, p.Position.Y, p.Position.Z + p.Height);
 var p6 = new Point3D(p.Position.X + p.Width, p.Position.Y, p.Position.Z + p.Height);
 var p7 = new Point3D(p.Position.X + p.Width, p.Position.Y + p.Width, p.Position.Z + p.Height);
 var p8 = new Point3D(p.Position.X, p.Position.Y + p.Width, p.Position.Z + p.Height);
 
 positions.Add(p1);
 positions.Add(p2);
 positions.Add(p3);
 positions.Add(p4);
 positions.Add(p5);
 positions.Add(p6);
 positions.Add(p7);
 positions.Add(p8);
 
 indices.Add(positionIndex);
 indices.Add(positionIndex + 1);
 indices.Add(positionIndex + 3);
 indices.Add(positionIndex + 1);
 indices.Add(positionIndex + 2);
 indices.Add(positionIndex + 3);
 indices.Add(positionIndex);
 indices.Add(positionIndex + 4);
 indices.Add(positionIndex + 3);
 indices.Add(positionIndex + 4);
 indices.Add(positionIndex + 7);
 indices.Add(positionIndex + 3);
 indices.Add(positionIndex + 4);
 indices.Add(positionIndex + 6);
 indices.Add(positionIndex + 7);
 indices.Add(positionIndex + 4);
 indices.Add(positionIndex + 5);
 indices.Add(positionIndex + 6);
 indices.Add(positionIndex);
 indices.Add(positionIndex + 4);
 indices.Add(positionIndex + 1);
 indices.Add(positionIndex + 1);
 indices.Add(positionIndex + 4);
 indices.Add(positionIndex + 5);
 indices.Add(positionIndex + 1);
 indices.Add(positionIndex + 2);
 indices.Add(positionIndex + 6);
 indices.Add(positionIndex + 6);
 indices.Add(positionIndex + 5);
 indices.Add(positionIndex + 1);
 indices.Add(positionIndex + 2);
 indices.Add(positionIndex + 3);
 indices.Add(positionIndex + 7);
 indices.Add(positionIndex + 7);
 indices.Add(positionIndex + 6);
 indices.Add(positionIndex + 2);
      }
 
      ((MeshGeometry3D)_particleModel.Geometry).Positions = positions;
      ((MeshGeometry3D)_particleModel.Geometry).TriangleIndices = indices;
 }

3、主窗体调用

xaml:


    
      
 
      
      
 
   
     

     
   
 
      
    

交互逻辑:

private readonly ParticleSystem _ps;
private DispatcherTimer _frameTimer;
private Point pMouse = new Point(9999, 9999);
 
public MainWindow()
    {
      InitializeComponent();
 
      _frameTimer = new DispatcherTimer();
      _frameTimer.Tick += Onframe;
      _frameTimer.Interval = TimeSpan.FromMilliseconds(100);
      _frameTimer.Start();
 
      _ps = new ParticleSystem(30, 30, Colors.White);
      WorldModels.Children.Add(_ps.ParticleModel);
      _ps.SpawnParticle(50);
 
      KeyDown += Window_KeyDown;
    }
 
    private void Window_KeyDown(object sender, KeyEventArgs e)
    {
      if (e.Key == Key.Escape)
 Close();
    }
 
    private void onframe(object sender, EventArgs e)
    {
      _ps.Update(pMouse);
    }
 
    private void Grid_MouseMove(object sender, MouseEventArgs e)
    {
      Point mouseposition = e.GetPosition(myViewport);
      PointHitTestParameters pointparams = new PointHitTestParameters(mouseposition);
      VisualTreeHelper.HitTest(myViewport, null, HTResult, pointparams);
    }
 
    /// 
    /// 获取鼠标在场景中的3D坐标
    /// 
    public HitTestResultBehavior HTResult(System.Windows.Media.HitTestResult rawresult)
    {
      RayHitTestResult rayResult = rawresult as RayHitTestResult;
      if (rayResult != null)
      {
 RayMeshGeometry3DHitTestResult rayMeshResult = rayResult as RayMeshGeometry3DHitTestResult;
 if (rayMeshResult != null)
 {
   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);
   pMouse = new Point(prePoint.X, prePoint.Y);
 }
      }
      return HitTestResultBehavior.Continue;
    }
 
    private void Grid_MouseLeave(object sender, MouseEventArgs e)
    {
      pMouse = new Point(9999, 9999);
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/121848.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号