WPF實現平面三角形3D運動效果
阿新 • • 發佈:2020-09-03
本文例項為大家分享了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,false); context.LineTo(VC,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,C,GetTriangleColor(index),index); Triangle t2 = new Triangle(A,D,GetTriangleColor(index - 0.1),index - 0.1); //公共點和三角形集合鍵值對 AddPointTriangles(A,t1,t2); AddPointTriangles(B,t2); AddPointTriangles(C,t2); AddPointTriangles(D,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 t.ColorIndex); if (t.C == pt.Key) t.VC = GetPointValue(t.VC,t.C,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起伏的效果,有興趣的可以一起探討優化。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。