Microscopic Traffic Simulator
BezierLaneBuildingRenderer.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 BezierLanePoints : LanePoints
18  {
19  internal const int FirstControldPoint = 2;
20  internal const int SecordControlPoint = 3;
21  }
22 
26  private const double ControlPointCircleRadius = 2.0;
27 
31  protected Point? firstWorldControlPoint;
35  public Point? FirstWorldControlPoint { get { return firstWorldControlPoint; } }
36 
41 
45  protected Point? secondWorldControlPoint;
49  public Point? SecondWorldControlPoint { get { return secondWorldControlPoint; } }
50 
55 
59  internal override bool IsLaneDefined
60  {
61  get
62  {
63  return base.IsLaneDefined && firstWorldControlPoint.HasValue && secondWorldControlPoint.HasValue;
64  }
65  }
66 
70  internal override bool IsSomePointBeingDragged
71  {
72  get
73  {
74  return base.IsSomePointBeingDragged || isFirstControlPointBeingDragged || secondControlPointIsMoving;
75  }
76  }
77 
82  internal BezierLaneBuildingRenderer(DrawingVisual visual) : base(visual) { }
83 
88  internal override void RenderBuildingLane(Point cursorPointOnCanas)
89  {
90  if (startWorldPoint.HasValue)
91  {
92  if (endWorldPoint.HasValue)
93  {
94  lastCursorPointOnCanvas = cursorPointOnCanas;
95  if (firstWorldControlPoint.HasValue)
96  {
97  if (secondWorldControlPoint.HasValue)
98  {
99  using (DrawingContext dc = visual.RenderOpen())
100  {
101  dc.DrawGeometry(null, pen, new BezierCurveGeometryCreator()
102  .GetBezierCurveGeometry(TransformRealWorldPoint(startWorldPoint.Value),
103  TransformRealWorldPoint(endWorldPoint.Value),
104  TransformRealWorldPoint(firstWorldControlPoint.Value),
105  TransformRealWorldPoint(secondWorldControlPoint.Value)));
106  dc.DrawEllipse(Brushes.Green, null,
107  TransformRealWorldPoint(firstWorldControlPoint.Value), ControlPointCircleRadius,
108  ControlPointCircleRadius);
109  dc.DrawEllipse(Brushes.Green, null,
110  TransformRealWorldPoint(secondWorldControlPoint.Value), ControlPointCircleRadius,
111  ControlPointCircleRadius);
112  if (IsLaneDefined)
113  {
114  dc.DrawEllipse(null, pen, TransformRealWorldPoint(startWorldPoint.Value),
115  DraggingCircleRadius, DraggingCircleRadius);
116  dc.DrawEllipse(null, pen, TransformRealWorldPoint(endWorldPoint.Value),
117  DraggingCircleRadius, DraggingCircleRadius);
118  dc.DrawEllipse(null, pen, TransformRealWorldPoint(firstWorldControlPoint.Value),
119  DraggingCircleRadius, DraggingCircleRadius);
120  dc.DrawEllipse(null, pen, TransformRealWorldPoint(secondWorldControlPoint.Value),
121  DraggingCircleRadius, DraggingCircleRadius);
122  }
123  }
124  }
125  else
126  {
127  using (DrawingContext dc = visual.RenderOpen())
128  {
129  dc.DrawGeometry(null, pen, new BezierCurveGeometryCreator()
130  .GetBezierCurveGeometry(TransformRealWorldPoint(startWorldPoint.Value),
131  TransformRealWorldPoint(endWorldPoint.Value),
132  TransformRealWorldPoint(firstWorldControlPoint.Value), cursorPointOnCanas));
133  dc.DrawEllipse(Brushes.Green, null,
134  TransformRealWorldPoint(firstWorldControlPoint.Value), ControlPointCircleRadius,
135  ControlPointCircleRadius);
136  }
137  }
138  }
139  else
140  {
141  using (DrawingContext dc = visual.RenderOpen())
142  {
143  dc.DrawGeometry(null, pen, new BezierCurveGeometryCreator().GetBezierCurveGeometry(
144  TransformRealWorldPoint(startWorldPoint.Value),
145  TransformRealWorldPoint(endWorldPoint.Value), cursorPointOnCanas, cursorPointOnCanas));
146  }
147  }
148  }
149  else
150  {
151  base.RenderBuildingLane(cursorPointOnCanas);
152  }
153  }
154  }
155 
160  internal override void SetPoint(Point cursorPointOnCanvas)
161  {
162  if (firstWorldControlPoint.HasValue)
163  {
164  Debug.Assert(!secondWorldControlPoint.HasValue, "Incorrect application state");
165  secondWorldControlPoint = TransformCanvasPoint(cursorPointOnCanvas);
166  RenderBuildingLane(cursorPointOnCanvas);
167  }
168  else if (endWorldPoint.HasValue)
169  {
170  firstWorldControlPoint = TransformCanvasPoint(cursorPointOnCanvas);
171  RenderBuildingLane(cursorPointOnCanvas);
172  }
173  else
174  {
175  base.SetPoint(cursorPointOnCanvas);
176  }
177  }
178 
182  internal override void ResetRendererAndClearAnyPreview()
183  {
184  firstWorldControlPoint = secondWorldControlPoint = null;
185  base.ResetRendererAndClearAnyPreview();
186  }
187 
191  internal override void ResetDraggingOfPoint()
192  {
193  base.ResetDraggingOfPoint();
194  isFirstControlPointBeingDragged = secondControlPointIsMoving = false;
195  }
196 
201  internal override void MovePointOfLane(Point point)
202  {
203  firstWorldControlPoint += GetVectorOfMoveOfPointIfItIsBeingDragged(point, isFirstControlPointBeingDragged);
204  secondWorldControlPoint += GetVectorOfMoveOfPointIfItIsBeingDragged(point, secondControlPointIsMoving);
205  base.MovePointOfLane(point);
206  }
207 
212  internal override void InitializeDraggingModeOfAPointIfAnyIsNear(Point cursorPointOnCanvas)
213  {
214  base.InitializeDraggingModeOfAPointIfAnyIsNear(cursorPointOnCanvas);
215  IList<double> squaredDistancesOfCanvasPointToWorldLanePoints =
216  GetSquaredDistancesOfCanvasPointToWorldLanePoints(cursorPointOnCanvas);
217  SetPointToDraggingModeIfCursorIsNearAndDragging(ref isFirstControlPointBeingDragged, cursorPointOnCanvas,
218  squaredDistancesOfCanvasPointToWorldLanePoints[BezierLanePoints.FirstControldPoint],
219  squaredDistancesOfCanvasPointToWorldLanePoints);
220  SetPointToDraggingModeIfCursorIsNearAndDragging(ref secondControlPointIsMoving, cursorPointOnCanvas,
221  squaredDistancesOfCanvasPointToWorldLanePoints[BezierLanePoints.SecordControlPoint],
222  squaredDistancesOfCanvasPointToWorldLanePoints);
223  }
224 
230  protected override IList<double> GetSquaredDistancesOfCanvasPointToWorldLanePoints(Point canvasPoint)
231  {
232  return base.GetSquaredDistancesOfCanvasPointToWorldLanePoints(canvasPoint).Concat(
233  new List<double>
234  {
235  (canvasPoint - TransformRealWorldPoint(firstWorldControlPoint.Value)).LengthSquared,
236  (canvasPoint - TransformRealWorldPoint(secondWorldControlPoint.Value)).LengthSquared
237  }).ToList();
238  }
239  }
240 }
Renderer for drawing bezier lanes during their building.
Point secondWorldControlPoint
The second control point of a previewing building lane.
bool isFirstControlPointBeingDragged
Determines whether the firstWorldControlPoint is currently being dragged.
Renderer for drawing lanes during their building.
Assigns integer identifiers for additional points of a bezier lane.
bool secondControlPointIsMoving
Determines whether the secondWorldControlPoint is currently being dragged.
Assigns integer identifiers for each point of a lane.
Class for creating geometry with bezier curve from canvas-coordinated points.
override IList< double > GetSquaredDistancesOfCanvasPointToWorldLanePoints(Point canvasPoint)
Get squared distances of all lane world points from cursor point on canvas.
Point firstWorldControlPoint
The first control point of a previewing building lane.