Microscopic Traffic Simulator
LaneBuildingRenderer.cs
Go to the documentation of this file.
1 using System.Collections.Generic;
2 using System.Diagnostics;
3 using System.Linq;
4 using System.Windows;
5 using System.Windows.Media;
6 
7 namespace Microscopic_Traffic_Simulator.Renderers
8 {
13  {
17  protected class LanePoints
18  {
22  internal const int StartPoint = 0;
26  internal const int EndPoint = 1;
27  }
28 
32  protected const double PenThickness = 1.0;
33 
38  protected const double DraggingCircleRadius = 4.0;
39 
44  protected const double DraggingCircleRadiusSquared = DraggingCircleRadius * DraggingCircleRadius;
45 
49  protected Pen pen = new Pen(Brushes.Green, PenThickness);
50 
54  protected Point? startWorldPoint = null;
58  internal Point? StartWorldPoint { get { return startWorldPoint; } }
59 
63  internal bool isStartPointBeingDragged = false;
64 
68  protected Point? endWorldPoint = null;
72  internal Point? EndWorldPoint { get { return endWorldPoint; } }
73 
77  internal bool isEndPointBeingDragged = false;
78 
83 
87  protected Point lastCursorPointOnCanvas;
91  internal Point LastCursorPointOnCavnas { get { return lastCursorPointOnCanvas; } }
92 
96  internal virtual bool IsLaneDefined
97  {
98  get { return startWorldPoint.HasValue && endWorldPoint.HasValue; }
99  }
100 
104  internal virtual bool IsSomePointBeingDragged
105  {
106  get { return isStartPointBeingDragged || isEndPointBeingDragged; }
107  }
108 
113  internal LaneBuildingRenderer(DrawingVisual visual)
114  : base(visual)
115  {
116  pen.Freeze();
117  }
118 
123  protected override void Render(Point currentMouseLocation)
124  {
125  RenderBuildingLane(currentMouseLocation);
126  }
127 
132  protected void DrawPreviewStraightLane(Point endPointOnCanvas)
133  {
134  using (DrawingContext dc = visual.RenderOpen())
135  {
136  dc.DrawLine(pen, TransformRealWorldPoint(startWorldPoint.Value), endPointOnCanvas);
137  if (IsLaneDefined)
138  {
139  dc.DrawEllipse(null, pen, TransformRealWorldPoint(startWorldPoint.Value), DraggingCircleRadius,
140  DraggingCircleRadius);
141  dc.DrawEllipse(null, pen, TransformRealWorldPoint(endWorldPoint.Value), DraggingCircleRadius,
142  DraggingCircleRadius);
143  }
144  }
145  }
146 
151  internal virtual void RenderBuildingLane(Point cursorPointOnCanvas)
152  {
153  lastCursorPointOnCanvas = cursorPointOnCanvas;
154  if (startWorldPoint.HasValue)
155  {
156  if (endWorldPoint.HasValue)
157  {
158  DrawPreviewStraightLane(TransformRealWorldPoint(endWorldPoint.Value));
159  }
160  else
161  {
162  DrawPreviewStraightLane(cursorPointOnCanvas);
163  }
164  }
165  }
166 
170  internal void RenderBuildingLane()
171  {
172  RenderBuildingLane(lastCursorPointOnCanvas);
173  }
174 
179  internal virtual void SetPoint(Point cursorPointOnCanvas)
180  {
181  if (startWorldPoint.HasValue)
182  {
183  Debug.Assert(!endWorldPoint.HasValue, "Incorrect application state");
184  endWorldPoint = TransformCanvasPoint(cursorPointOnCanvas);
185  }
186  else
187  {
188  startWorldPoint = TransformCanvasPoint(cursorPointOnCanvas);
189  }
190  RenderBuildingLane(cursorPointOnCanvas);
191  }
192 
196  internal virtual void ResetRendererAndClearAnyPreview()
197  {
198  startWorldPoint = endWorldPoint = null;
199  using (DrawingContext dc = visual.RenderOpen()) { }
200  }
201 
205  internal virtual void ResetDraggingOfPoint()
206  {
207  isStartPointBeingDragged = isEndPointBeingDragged = false;
208  }
209 
214  internal virtual void MovePointOfLane(Point cursorPointOnCanvas)
215  {
216  startWorldPoint += GetVectorOfMoveOfPointIfItIsBeingDragged(cursorPointOnCanvas, isStartPointBeingDragged);
217  endWorldPoint += GetVectorOfMoveOfPointIfItIsBeingDragged(cursorPointOnCanvas, isEndPointBeingDragged);
218  RenderBuildingLane(cursorPointOnCanvas);
219  }
220 
228  protected Vector GetVectorOfMoveOfPointIfItIsBeingDragged(Point cursorPointOnCanvas, bool isBeingDragged)
229  {
230  if (isBeingDragged)
231  {
232  Vector movement = (cursorPointOnCanvas - previousReferencePointForDragging) / PixelsPerMeter;
233  previousReferencePointForDragging = cursorPointOnCanvas;
234  return movement;
235  }
236  return new Vector();
237  }
238 
243  internal virtual void InitializeDraggingModeOfAPointIfAnyIsNear(Point cursorPointOnCanvas)
244  {
245  IList<double> squaredDistancesOfCanvasPointToWorldLanePoints =
246  GetSquaredDistancesOfCanvasPointToWorldLanePoints(cursorPointOnCanvas);
247  SetPointToDraggingModeIfCursorIsNearAndDragging(ref isStartPointBeingDragged, cursorPointOnCanvas,
248  squaredDistancesOfCanvasPointToWorldLanePoints[LanePoints.StartPoint],
249  squaredDistancesOfCanvasPointToWorldLanePoints);
250  SetPointToDraggingModeIfCursorIsNearAndDragging(ref isEndPointBeingDragged, cursorPointOnCanvas,
251  squaredDistancesOfCanvasPointToWorldLanePoints[LanePoints.EndPoint],
252  squaredDistancesOfCanvasPointToWorldLanePoints);
253  }
254 
264  protected void SetPointToDraggingModeIfCursorIsNearAndDragging(ref bool pointIsInDraggingMode,
265  Point cursorPointOnCanvas, double squaredDistanceOfWorldPointFromCanvasPoint,
266  IList<double> squaredDistancesOfRemainingWorldPointsFromCanvasPoint)
267  {
268  if (squaredDistanceOfWorldPointFromCanvasPoint < DraggingCircleRadiusSquared)
269  {
270  if (squaredDistancesOfRemainingWorldPointsFromCanvasPoint.All(
271  i => i >= squaredDistanceOfWorldPointFromCanvasPoint))
272  {
273  pointIsInDraggingMode = true;
274  previousReferencePointForDragging = cursorPointOnCanvas;
275  RenderBuildingLane(cursorPointOnCanvas);
276  }
277  }
278  }
279 
285  protected virtual IList<double> GetSquaredDistancesOfCanvasPointToWorldLanePoints(
286  Point cursorPointOnCanvasPoint)
287  {
288  return new List<double>
289  {
290  (cursorPointOnCanvasPoint - TransformRealWorldPoint(startWorldPoint.Value)).LengthSquared,
291  (cursorPointOnCanvasPoint - TransformRealWorldPoint(endWorldPoint.Value)).LengthSquared
292  };
293  }
294 
299  internal void TransferPoints(LaneBuildingRenderer previousLaneBuildingRenderer)
300  {
301  startWorldPoint = previousLaneBuildingRenderer.startWorldPoint;
302  endWorldPoint = previousLaneBuildingRenderer.EndWorldPoint;
303  lastCursorPointOnCanvas = previousLaneBuildingRenderer.lastCursorPointOnCanvas;
304  }
305  }
306 }
virtual IList< double > GetSquaredDistancesOfCanvasPointToWorldLanePoints(Point cursorPointOnCanvasPoint)
Get squared distances of all lane world points from cursor point on canvas.
Point lastCursorPointOnCanvas
Last cursor point after rendering prewview of building lane.
void SetPointToDraggingModeIfCursorIsNearAndDragging(ref bool pointIsInDraggingMode, Point cursorPointOnCanvas, double squaredDistanceOfWorldPointFromCanvasPoint, IList< double > squaredDistancesOfRemainingWorldPointsFromCanvasPoint)
Set point to dragging mode if cursor is near to any point of lane.
Vector GetVectorOfMoveOfPointIfItIsBeingDragged(Point cursorPointOnCanvas, bool isBeingDragged)
Gets vector of move of point if the point is being dragged and update the previous reference point fo...
override void Render(Point currentMouseLocation)
Render preview change of move or zoom. Current mouse location.
Renderer for drawing lanes during their building.
void DrawPreviewStraightLane(Point endPointOnCanvas)
Draws preview of straight lane.
Point previousReferencePointForDragging
Previous reference point for dragging
Assigns integer identifiers for each point of a lane.
Point startWorldPoint
Start point of a previewing building lane.