/// <summary> /// Adds a new intermediate piont to the wire /// </summary> /// <param name="point"></param> public void AddIntermediatePoint(IPlanePosition point) { // If there are not enough coords to add intermediate points, throw an exception if (DefiningPoints.Count < 2) { throw new Exception("Can't add an intermediate point to a wire with less than 2 coords"); } // If the point that we add is already a construction point return if (ConstructionPoints.FirstOrDefault((position) => position.Equals(point)) != null) { return; } // If the point is not included in the wire as a construction point but it does lie on the wire if (FindPrecidingConstructionPoint(point, out int index)) { // Add it to the wire's construction points _ConstructionPoints.Insert(index + 1, point); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ConstructionPoints))); return; } // Otherwise signal error throw new Exception("The given position doesn't lie on the wire"); }
/// <summary> /// Adds a point to the beginning of the wire, adds necessary points to <see cref="_ConstructionPoints"/> /// </summary> /// <param name="point"></param> private void AddPointAtBeginning(IPlanePosition point) { _DefiningPoints.Insert(0, point); if (_ConstructionPoints.Count > 0) { _ConstructionPoints.Insert(0, new PlanePosition(point.X, _ConstructionPoints[0].Y)); } _ConstructionPoints.Insert(0, point); }
/// <summary> /// Adds a point to the end of the wire, adds necessary points to <see cref="_ConstructionPoints"/> /// </summary> /// <param name="point"></param> private void AddPointAtEnd(IPlanePosition point) { _DefiningPoints.Add(point); if (_ConstructionPoints.Count > 0) { _ConstructionPoints.Add(new PlanePosition(point.X, _ConstructionPoints[_ConstructionPoints.Count - 1].Y)); } _ConstructionPoints.Add(point); }
/// <summary> /// Adds a new point to the wire at beginning/end /// </summary> /// <param name="point"></param> public void AddPoint(IPlanePosition point, bool addAtEnd = true) { if (addAtEnd) { AddPointAtEnd(point); } else { AddPointAtBeginning(point); } PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ConstructionPoints))); }
/// <summary> /// Returns true if the point given by <paramref name="position"/> belongs to wire but is not in construction points yet, /// assigns the index of its preceding construction point to <paramref name="index"/>. If the point doesn't belong to wire /// returns false and assigns -1 to <paramref name="index"/> /// </summary> /// <param name="position"></param> /// <param name="index"></param> /// <returns></returns> private bool FindPrecidingConstructionPoint(IPlanePosition position, out int index) { for (int i = 0; i < ConstructionPoints.Count - 1; ++i) { // If the point lies on the line between two subsequent points if ((ConstructionPoints[i].X == position.X && ConstructionPoints[i + 1].X == position.X && (position.Y - ConstructionPoints[i].Y) * (position.Y - ConstructionPoints[i + 1].Y) < 0) || (ConstructionPoints[i].Y == position.Y && ConstructionPoints[i + 1].Y == position.Y && (position.X - ConstructionPoints[i].X) * (position.X - ConstructionPoints[i + 1].X) < 0)) { index = i; return(true); } } index = -1; return(false); }
/// <summary> /// Constructor taking an <see cref="IPlanePosition"/> /// </summary> /// <param name="position"></param> public Node(IPlanePosition position) { Position = position; }
/// <summary> /// Default constructor taking position of the terminal as a parameter /// </summary> public Terminal(IPlanePosition position) => Position = position;
/// <summary> /// Returns true if point given by <paramref name="position"/> belongs to this wire /// </summary> /// <param name="position"></param> /// <returns></returns> public bool BelongsToWire(IPlanePosition position) => FindPrecidingConstructionPoint(position, out var dummy) || ConstructionPoints.FirstOrDefault((constructionPoint) => position.Equals(constructionPoint)) != null;