WPF實現(xiàn)3D立方體波浪墻效果
本文實例為大家分享了WPF實現(xiàn)3D立方體波浪墻效果的具體代碼,供大家參考,具體內(nèi)容如下
實現(xiàn)效果如下:
思路:仿照3D粒子系統(tǒng),將粒子顆粒的Geometry改造為立方體,鼠標(biāo)移動時將鼠標(biāo)位置轉(zhuǎn)為3D場景中的坐標(biāo)。
步驟:
1、粒子類Particle.cs
public Point3D Position;//位置 public double Width;//長方體底面寬 public double Height;//長方體側(cè)面高
2、粒子系統(tǒng)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、主窗體調(diào)用
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> /// 獲取鼠標(biāo)在場景中的3D坐標(biāo) /// </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); }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C#使用正則表達(dá)式實現(xiàn)首字母轉(zhuǎn)大寫的方法
這篇文章主要介紹了C#使用正則表達(dá)式實現(xiàn)首字母轉(zhuǎn)大寫的方法,涉及C#基于正則表達(dá)式操作字符串的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-11-11C#實現(xiàn)Json轉(zhuǎn)DataTable并導(dǎo)出Excel的方法示例
這篇文章主要介紹了C#實現(xiàn)Json轉(zhuǎn)DataTable并導(dǎo)出Excel的方法,結(jié)合實例形式總結(jié)分析了Json轉(zhuǎn)換DataTable,以及DataTable導(dǎo)出Excel相關(guān)操作技巧,需要的朋友可以參考下2019-02-02