中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

WPF如何實現3D立方體波浪墻效果

發布時間:2020-09-24 09:26:24 來源:億速云 閱讀:359 作者:Leah 欄目:開發技術

今天就跟大家聊聊有關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);
}

看完上述內容,你們對WPF如何實現3D立方體波浪墻效果有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

葫芦岛市| 新绛县| 西安市| 织金县| 平顺县| 九龙城区| 石泉县| 陆丰市| 星子县| 西乌珠穆沁旗| 青冈县| 尼木县| 柘城县| 昌吉市| 德格县| 仁怀市| 安福县| 工布江达县| 龙里县| 延边| 南漳县| 林芝县| 句容市| 迭部县| 古蔺县| 陆川县| 团风县| 两当县| 库尔勒市| 平阴县| 巴林左旗| 阿勒泰市| 奇台县| 大姚县| 温州市| 杨浦区| 江山市| 工布江达县| 信阳市| 建湖县| 贡觉县|