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<Particle> _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<Particle>();
      _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:

<Grid x:Name="mainGrid" Background="#0D6589" >
    <Viewport3D Name="myViewport" MouseLeave="Grid_MouseLeave" MouseMove="Grid_MouseMove">
      <Viewport3D.Camera>
        <PerspectiveCamera Position="-1500,3000,2200" LookDirection="1,-1,-1" UpDirection="0,0,1"/>
      </Viewport3D.Camera>
      <Viewport3D.Children>
        <ModelVisual3D>
          <ModelVisual3D.Content>
            <Model3DGroup x:Name="WorldModels">
              <DirectionalLight Color="White" Direction="-1,-1,-3" />
            </Model3DGroup>
          </ModelVisual3D.Content>
        </ModelVisual3D>
      </Viewport3D.Children>
    </Viewport3D>
</Grid>

交互逻辑:

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);
    }

    /// <summary>
    /// 获取鼠标在场景中的3D坐标
    /// </summary>
    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);
}

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

(0)

相关推荐

  • c# 实例——绘制波浪线(附源码)

    效果图 界面绘制操作 private Point? _startPoint = null; private void ContainerCanvas_OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { var position = e.GetPosition(ContainerCanvas); if (_startPoint == null) { _startPoint = position; } else

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

    本文实例为大家分享了WPF实现3D立方体波浪墙效果的具体代码,供大家参考,具体内容如下 实现效果如下: 思路:仿照3D粒子系统,将粒子颗粒的Geometry改造为立方体,鼠标移动时将鼠标位置转为3D场景中的坐标. 步骤: 1.粒子类Particle.cs public Point3D Position;//位置 public double Width;//长方体底面宽 public double Height;//长方体侧面高 2.粒子系统ParticleSystem.cs private re

  • WPF实现3D粒子波浪效果

    本文实例为大家分享了WPF实现3D粒子波浪效果的具体代码,供大家参考,具体内容如下 实现效果如下: 步骤: 1.3D粒子类Particle.cs public class Particle { public Point3D Position;//位置 public double Size;//尺寸 public int XIndex;//X位置标识 public int YIndex;//Y位置标识 } 2.粒子系统ParticleSystem类 public class ParticleSys

  • 基于css3新属性transform及原生js实现鼠标拖动3d立方体旋转

    通过原生JS,点击事件,鼠标按下.鼠标抬起和鼠标移动事件,实现3d立方体的拖动旋转,并将旋转角度实时的反应至界面上显示. 实现原理:通过获取鼠标点击屏幕时的坐标和鼠标移动时的坐标,来获得鼠标在X轴.Y轴移动的距离,将距离实时赋值给transform属性 从而通过改变transform:rotate属性值来达到3d立方体旋转的效果 HTML代码块: <body> <input type="button" class="open" value=&quo

  • jQuery+CSS3实现3D立方体旋转效果

    本文介绍了如何利用jQuery+CSS3实现3D立方体旋转效果,先看一看效果图: 切换图片过程中,图片进行旋转: HTML结构 3D图片画廊的图片列表和导航按钮分别使用两个无序列表来制作. <section> <div id="css3dimageslider" class="transparency"> <ul> <li> <img src="img/css3dimg1.jpg"> &

  • Qt使用QPainter绘制3D立方体

    本文实例为大家分享了使用QPainter绘制3D立方体的具体代码,供大家参考,具体内容如下 1.实现思路 (网上有另一篇类似的,不过他不是用的 Qt 自带的矩阵运算类) 实现思路有点类似使用 OpenGL 画立方体,先准备顶点数据: //立方体前后四个顶点,从右上角开始顺时针 vertexArr=QVector<QVector3D>{ QVector3D{1,1,1}, QVector3D{1,-1,1}, QVector3D{-1,-1,1}, QVector3D{-1,1,1}, QVec

  • WPF实现3D翻牌式倒计时特效

    本文实例为大家分享了WPF实现3D翻牌式倒计时的具体代码,供大家参考,具体内容如下 实现效果如下: 思路:使用自定义控件,设置一个背板 MyCardControlBottom,一个卡牌翻动的前部 MyCardControlFront,一个卡牌翻动后的背部 MyCardControlBack,另外实现卡牌翻动的MyCardControl:在主窗体中设置一计时器,根据卡牌上的数字和计时器时间启动翻牌动作. 主要代码: 1.自定义控件MyCardControlBottom <UserControl x

  • 利用JavaScript实现3D可旋转粒子矩阵效果

    目录 演示 技术栈 dat.gui.min.js 源码 js部分 演示 技术栈 本次使用了dat.gui.min.js这个新库(就是在我文章里没有出现过的那么他们的功能有哪些呢?——可以百度搜搜)不想搜的话就听我简单絮叨两句吧. dat.gui.min.js 就是能调节数据的功能框 使用起来也很简单例如建立一个对象 gui = { lightY:30, //灯光y轴的位置 sphereX:0, //球的x轴的位置 sphereZ:0, //球的z轴的位置 cubeX:25, //立方体的x轴位置

  • JS实现六边形3D拖拽翻转效果的方法

    效果图 实例代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv=&q

  • JS实现3D图片旋转展示效果代码

    本文实例讲述了JS实现3D图片旋转展示效果代码.分享给大家供大家参考.具体如下: 这是一段JavaScript代码,围绕成3D模型样式的JavaScript图片旋转展示代码,这里为了演示方便,将图片替换成了数字,预留出了图片的位置,这样速度快些,会HTML的朋友都知道用时候该怎么做.本图片旋转需要手功控制,每点击一下,图片旋转一次,很方便. 运行效果截图如下: 在线演示地址如下: http://demo.jb51.net/js/2015/js-3d-pic-scroll-show-style-c

  • Android实现波浪线效果(xml bitmap)

    我们要实现的效果如下: 在这之前先带大家了解一下xml bitmap,何为XML Bitmap? XML Bitmap 是一个用XML定义的文件放在资源目录,定义的对象是图片,为bitmap定义别名,这个文件可以给bitmap定义一些额外的属性.例如:抖动. 1.文件存放位置 res/drawable/filename.xml 2.语法 <?xml version="1.0" encoding="utf-8"?> <bitmap xmlns:and

随机推荐