WPF实现平面三角形3D运动效果
更新时间:2020年9月3日 10:03 点击:1359
本文实例为大家分享了WPF实现平面三角形3D运动效果的具体代码,供大家参考,具体内容如下
实现效果如下:
思路:封装三角形三个顶点和路径的三角形类,图形渲染时同步更新公共顶点三角形的顶点位置。
步骤:
1、三角形类Triangle.cs
public Point A, B, C;//初始三个顶点 public Point VA, VB, VC;//运动的三个顶点 public Path trianglePath;//三角形路径 public Color triangleColor;//填充 public double ColorIndex;//颜色深度 public Triangle(Point a, Point b, Point c, Color co, double z) { A = VA = a; B = VB = b; C = VC = c; triangleColor = co; ColorIndex = z; trianglePath = new Path(); Draw(); } /// <summary> /// 绘制三角形 /// </summary> public void Draw() { var g = new StreamGeometry(); using (StreamGeometryContext context = g.Open()) { context.BeginFigure(VA, true, true); context.LineTo(VB, true, false); context.LineTo(VC, true, false); } trianglePath.Data = g; trianglePath.Fill = new SolidColorBrush(triangleColor); }
2、 三角形系统类TriangleSystem.cs
public class TriangleSystem { /// <summary> /// 三角形列表 /// </summary> private List<Triangle> triangles; /// <summary> /// 点和与其对应三角形字典 /// </summary> public Dictionary<Point, PointClass> pointTriangles; /// <summary> /// 容器 /// </summary> private Canvas containerCanvas; /// <summary> /// 三角形宽 /// </summary> private int triangleWidth = 100; /// <summary> /// 三角形高 /// </summary> private int triangleHeight = 100; /// <summary> /// 三角形横向数量 /// </summary> private int horizontalCount = 10; /// <summary> /// 三角形纵向数量 /// </summary> private int verticalCount = 5; /// <summary> /// X坐标运动范围 /// </summary> private int XRange = 100; /// <summary> /// Y坐标运动范围 /// </summary> private int YRange = 10; /// <summary> /// 坐标运动速度 /// </summary> private int speed = 10; /// <summary> /// 三角形颜色深度 /// </summary> private double zIndex = 10.0; /// <summary> /// 随机数 /// </summary> private Random random; public TriangleSystem(Canvas ca) { containerCanvas = ca; random = new Random(); triangles = new List<Triangle>(); pointTriangles = new Dictionary<Point, PointClass>(); SpawnTriangle(); } /// <summary> /// 三角形初始化 /// </summary> private void SpawnTriangle() { //清空队列 triangles.Clear(); for (int i = 0; i < horizontalCount; i++) { for (int j = 0; j < verticalCount; j++) { Point A = new Point(i * triangleWidth, j * triangleHeight); Point B = new Point(i * triangleWidth, (j + 1) * triangleHeight); Point C = new Point((i + 1) * triangleWidth, (j + 1) * triangleHeight); Point D = new Point((i + 1) * triangleWidth, j * triangleHeight); double index = (i * horizontalCount / zIndex + j * verticalCount / zIndex ) / zIndex; index = index > 1 ? 1 : index < 0.1 ? 0.1 : index; Triangle t1 = new Triangle(A, B, C, GetTriangleColor(index), index); Triangle t2 = new Triangle(A, D, C, GetTriangleColor(index - 0.1), index - 0.1); //公共点和三角形集合键值对 AddPointTriangles(A, t1, t2); AddPointTriangles(B, t1, t2); AddPointTriangles(C, t1, t2); AddPointTriangles(D, t1, t2); //添加三角形 this.containerCanvas.Children.Add(t1.trianglePath); this.containerCanvas.Children.Add(t2.trianglePath); this.triangles.Add(t1); this.triangles.Add(t2); } } } /// <summary> /// 添加公共点和三角形集合键值对 /// </summary> private void AddPointTriangles(Point p, Triangle t1, Triangle t2) { if (!this.pointTriangles.Keys.Contains(p)) { List<Triangle> ts = new List<Triangle>(); ts.Add(t1); ts.Add(t2); PointClass pc = new PointClass { triangles = ts, vector = new Vector(random.Next(-speed, speed) * 0.05, random.Next(-speed, speed) * 0.05), }; this.pointTriangles.Add(p, pc); } else { if (!this.pointTriangles[p].triangles.Contains(t1)) this.pointTriangles[p].triangles.Add(t1); if (!this.pointTriangles[p].triangles.Contains(t2)) this.pointTriangles[p].triangles.Add(t2); } } /// <summary> /// 获取三角形颜色 /// </summary> private Color GetTriangleColor(double index) { return Color.FromArgb((byte)(255 * index), 230, 18, 65); } /// <summary> /// 更新三角形 /// </summary> public void Update() { foreach (var pt in pointTriangles) { foreach (var t in pt.Value.triangles) { if (t.A == pt.Key) t.VA = GetPointValue(t.VA, t.A, ref pt.Value.vector, ref t.triangleColor, ref t.ColorIndex); if (t.B == pt.Key) t.VB = GetPointValue(t.VB, t.B, ref pt.Value.vector, ref t.triangleColor, ref t.ColorIndex); if (t.C == pt.Key) t.VC = GetPointValue(t.VC, t.C, ref pt.Value.vector, ref t.triangleColor, ref t.ColorIndex); t.Draw(); } } } /// <summary> /// 计算顶点值 /// </summary> private Point GetPointValue(Point p1, Point p2, ref Vector v, ref Color c, ref double index) { Point getPoint = new Point(); if (p1.X + v.X < p2.X + XRange && p1.X + v.X > p2.X - XRange) getPoint.X = p1.X + v.X; else { v.X = -v.X; index = index > 1 ? index - 0.01 : index < 0.01 ? index + 0.01 : index - 0.01; c = GetTriangleColor(index); getPoint.X = p1.X + v.X; } if (p1.Y + v.Y < p2.Y + YRange && p1.Y + v.Y > p2.Y - YRange) getPoint.Y = p1.Y + v.Y; else { v.Y = -v.Y; getPoint.Y = p1.Y + v.Y; } return getPoint; } }
3、PointClass.cs
public class PointClass { public List<Triangle> triangles; public Vector vector; }
4、主窗体交互逻辑
private TriangleSystem ts; public MainWindow() { InitializeComponent(); ts = new TriangleSystem(this.mainCanvas); CompositionTarget.Rendering += CompositionTarget_Rendering; } /// <summary> /// 帧渲染事件 /// </summary> private void CompositionTarget_Rendering(object sender, EventArgs e) { ts.Update(); }
不足:其中颜色渲染方式不够完善,无法完全模仿3D起伏的效果,有兴趣的可以一起探讨优化。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持猪先飞。
上一篇: C# 如何解析获取Url参数值
下一篇: 谈谈c#中的索引器
相关文章
c# WPF中通过双击编辑DataGrid中Cell的示例(附源码)
这篇文章主要介绍了c# WPF中通过双击编辑DataGrid中Cell的示例(附源码),帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下...2021-03-03- 最近在网上看到了新版的360安全卫士,感觉界面还不错,于是用WPF制作了一个,时间有限,一些具体的控件没有制作,用图片代替了。感兴趣的朋友一起跟着小编学习WPF实现类似360安全卫士界面的程序源码分享...2020-06-25
- 这篇文章主要为大家详细介绍了WPF仿三星手机充电界面实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要介绍了C# WPF 通过委托实现多窗口间的传值的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
- 这篇文章主要介绍了C#判断三角形的类型的方法,通过输入三角形的三条边长,判断是否能构成一个三角形,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要为大家详细介绍了WPF TextBox实现按字节长度限制输入功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要介绍了C#中WPF使用多线程调用窗体组件的方法,涉及C#中多线程的使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
- 这篇文章主要为大家详细介绍了WPF InkCanvas绘制矩形和椭圆,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要给大家介绍了关于WPF基础教程之形状画刷与变换的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
- 这篇文章主要给大家介绍了关于WPF如何自定义TabControl控件样式的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。...2020-06-25
- 这篇文章主要介绍了c#用for语句输出一个三角形的方法,可实现只用一个for语句来输出三角形的功能,需要的朋友可以参考下...2020-06-25
- 本篇文章是对C++中输出上三角/下三角/菱形/杨辉三角形的示例代码进行了详细的分析介绍,需要的朋友参考下...2020-04-25
- 下面小编就为大家分享一篇WPF水珠效果按钮组的实现教程,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-09-22
- 本篇文章是对WPF实现音频文件循环顺序播放的方法进行了详细的分析介绍,需要的朋友参考下...2021-09-22
- 如果注册快捷键,RegisterHotKey中的fsModifiers参数为0,即None选项,一些安全软件会警报,可能因为这样就可以全局监听键盘而造成安全问题,感兴趣的你可以参考下本文...2020-06-25
- 这篇文章主要为大家详细介绍了WPF实现转圈进度条效果,如何设计自定义的绕圈进度条,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-22
- 这篇文章主要为大家详细介绍了WPF中自定义GridLengthAnimation的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-22
- 这篇文章主要介绍了WPF/Silverlight实现图片局部放大的方法,结合实例形式分析了WPF/Silverlight针对图片属性操作相关实现技巧,需要的朋友可以参考下...2020-06-25
- 这篇文章主要为大家详细介绍了WPF MVVM发送短信小按钮的制作方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要给大家介绍了关于WPF中窗体最大化问题的解决方法,文中通过示例代码介绍的非常详细,对大家学习或者使用wpf具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25