ScheduleCanvas.cs
7.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
using RoboforkApp.DataModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace RoboforkApp
{
public class ScheduleCanvas : Canvas
{
const double COOR_Y = 65;
const double RADIUS_NODE = 25;
public simulationRobo simulation;
private VehicleModelList vehicleModelList;
private Point _startPoint;
private Point _endPoint;
private bool _isGoal = false;
private double _speed;
private int _index;
private List<ucNode> _lstNode;
/// <summary>
/// Create simulation
/// </summary>
/// <param name="lstNode">List node on schedule</param>
/// <param name="vehicleModel">Vehicle model on map</param>
/// <param name="vehicleIndex">Current index of vehicle</param>
public void CreateSimulation(List<ucNode> lstNode, VehicleModel vehicleModel, int vehicleIndex)
{
//If node is less than 2 so return
if (this.Children.Count < 2)
{
return;
}
this.Children.Remove(simulation);
//Init data
this._lstNode = lstNode;
this.vehicleModelList = vehicleModel.VehicleModelList[vehicleIndex];
this._startPoint = new Point(Canvas.GetLeft(_lstNode[_index]) + RADIUS_NODE, COOR_Y);
this._endPoint = new Point(Canvas.GetLeft(_lstNode[_index + 1]) + RADIUS_NODE, COOR_Y);
//Get speed
double scheDis = GetDistance(_startPoint, _endPoint);
double mapDis = GetDistance(new Point(vehicleModelList.pointMapList[_index].pointMap_X, vehicleModelList.pointMapList[_index].pointMap_Y),
new Point(vehicleModelList.pointMapList[_index + 1].pointMap_X, vehicleModelList.pointMapList[_index + 1].pointMap_Y + 1));
this._speed = GetSpeed(mapDis, scheDis, vehicleModelList.pointMapList[_index].speed_Map);
//Check next node is goal
this._index += 1;
if (_index == _lstNode.Count - 1)
{
_isGoal = true;
}
// Start simulation
RoboSimulation();
}
/// <summary>
/// Create robo simulation on line
/// </summary>
private void RoboSimulation()
{
simulation = new simulationRobo();
simulation.storyBoard = CreatPathAnimation(_startPoint, _endPoint, _speed);
this.Children.Add(simulation);
}
/// <summary>
/// Get storyboard
/// </summary>
/// <param name="startPoint">Point start line</param>
/// <param name="endPoit">Point end line</param>
/// <param name="speed">speed on line</param>
/// <returns>Storyboard</returns>
private Storyboard CreatPathAnimation(Point startPoint, Point endPoit, double speed)
{
PathGeometry animationPath = new PathGeometry();
PathFigure pFigure = new PathFigure();
pFigure.StartPoint = startPoint; //new Point(50, 65);
LineSegment lineSegment = new LineSegment();
lineSegment.Point = endPoit; // new Point(800, 65);
pFigure.Segments.Add(lineSegment);
animationPath.Figures.Add(pFigure);
// Freeze the PathGeometry for performance benefits.
animationPath.Freeze();
// Create a MatrixAnimationUsingPath to move the
// simulation along the path by animating
// its MatrixTransform.
MatrixAnimationUsingPath matrixAnimation = new MatrixAnimationUsingPath();
matrixAnimation.PathGeometry = animationPath;
matrixAnimation.SpeedRatio = speed;
matrixAnimation.AutoReverse = false;
matrixAnimation.DoesRotateWithTangent = true;
matrixAnimation.Completed += delegate { AnimationCompleted(this._isGoal); };
// Set the animation to target the Matrix property
// of the MatrixTransform named "ButtonMatrixTransform".
Storyboard.SetTargetName(matrixAnimation, "fl");
Storyboard.SetTargetProperty(matrixAnimation, new PropertyPath(MatrixTransform.MatrixProperty));
// Create a Storyboard to contain and apply the animation.
Storyboard pathAnimationStoryboard = new Storyboard();
pathAnimationStoryboard.Children.Add(matrixAnimation);
return pathAnimationStoryboard;
}
/// <summary>
/// Process when simulation is end line
/// </summary>
/// <param name="isGoal">check is node end</param>
private void AnimationCompleted(bool isGoal)
{
// If not end node
if (!isGoal)
{
this.Children.Remove(simulation);
this._startPoint = _endPoint;
this._endPoint = new Point(Canvas.GetLeft(_lstNode[_index + 1]) + RADIUS_NODE, COOR_Y);
//Get speed
double scheDis = GetDistance(_startPoint, _endPoint);
double mapDis = GetDistance(new Point(vehicleModelList.pointMapList[_index].pointMap_X, vehicleModelList.pointMapList[_index].pointMap_Y),
new Point(vehicleModelList.pointMapList[_index + 1].pointMap_X, vehicleModelList.pointMapList[_index + 1].pointMap_Y + 1));
this._speed = GetSpeed(mapDis, scheDis, vehicleModelList.pointMapList[_index].speed_Map);
//Check next node is goal
this._index += 1;
if (this._index == this._lstNode.Count - 1)
{
this._isGoal = true;
}
RoboSimulation();
return;
}
// Reset data when finish
this._index = 0;
this._speed = 0;
this._isGoal = false;
}
/// <summary>
/// Get speed on schedule
/// </summary>
/// <param name="mapDis">Distance the line on Map</param>
/// <param name="scheDis">Distance the line on Schedule</param>
/// <param name="mapSpeed">Speed the fork on Map</param>
/// <returns>Speed the fork on schedule</returns>
private double GetSpeed(double mapDis, double scheDis, double mapSpeed)
{
if (mapDis == 0)
return 0.0;
return mapSpeed * (scheDis / mapDis);
}
/// <summary>
/// Get distance between two point
/// </summary>
/// <param name="point1">Point 1</param>
/// <param name="point2">Point 2</param>
/// <returns>Distance between two point</returns>
private double GetDistance(Point point1, Point point2)
{
//pythagorean theorem c^2 = a^2 + b^2
//thus c = square root(a^2 + b^2)
double a = (double)(point2.X - point1.X);
double b = (double)(point2.Y - point1.Y);
return Math.Sqrt(a * a + b * b);
}
}
}