/// <summary> /// Constructor from another PathChartPoint, only shifted in distance along the path /// </summary> /// <param name="sourcePoint">The point to copy from</param> /// <param name="distanceShift">Extra distance along the path</param> public PathChartPoint(PathChartPoint sourcePoint, float distanceShift) { HeightM = sourcePoint.HeightM; DistanceAlongPath = sourcePoint.DistanceAlongPath + distanceShift; Curvature = sourcePoint.Curvature; DistanceAlongNextSection = sourcePoint.DistanceAlongNextSection; GradePercent = sourcePoint.GradePercent; TrackItemText = sourcePoint.TrackItemText; TrackItemType = sourcePoint.TrackItemType; }
/// <summary> /// Constructor where all information is given externally /// </summary> /// <param name="curvature">The curvature to store</param> /// <param name="height">The height to store</param> /// <param name="grade">The grade along the path (raw, so not in percent)</param> /// <param name="distanceAlongSection">The distance along the section to store</param> /// <param name="itemText">The text to show on an item when drawing</param> /// <param name="type">The type of trackitem (if any) at this point</param> public PathChartPoint(float height, float curvature, float grade, float distanceAlongSection, string itemText = "", ChartableTrackItemType type = ChartableTrackItemType.None) { HeightM = height; DistanceAlongPath = 0; Curvature = curvature; GradePercent = grade * 100; DistanceAlongNextSection = distanceAlongSection; TrackItemText = itemText; TrackItemType = type; }
/// <summary> /// Constructor for a first point /// </summary> /// <param name="node">The node describing where the location of the point is</param> public PathChartPoint(TrainpathNode node) { HeightM = node.Location.Location.Y; DistanceAlongPath = 0; Curvature = 0; GradePercent = 0; DistanceAlongNextSection = 0; TrackItemText = String.Empty; TrackItemType = ChartableTrackItemType.None; }
/// <summary> /// From section information create a point for charting the path, and add it to newPoints. /// In case there are track items in this particular section, add those also (starting with the last item as seen from the direction of the path) /// </summary> /// <param name="newPoints">The list to which to add the point</param> /// <param name="vectorNode">The vectorNode to use for curvature and grade</param> /// <param name="trackItems">A list of track items in this vector tracknode</param> /// <param name="isForward">Is the path in the same direction as the tracknode</param> /// <param name="height">Height to store in the point</param> /// <param name="tvsi">The section index in the track vector node</param> /// <param name="sectionOffsetStart">Offset of the start of this section (in forward direction of track, not of path)</param> /// <param name="sectionOffsetStart">Offset of the end of this section (in forward direction of track, not of path)</param> private void AddPointAndTrackItems(List <PathChartPoint> newPoints, TrVectorNode vectorNode, IEnumerable <ChartableTrackItem> trackItems, bool isForward, float height, int tvsi, float sectionOffsetStart, float sectionOffsetEnd) { //Note, we are adding points in in reverse direction var additionalPoints = new List <PathChartPoint>(); // not a percentage. We can safely assume the pitch is small enough so we do not to take tan(pitch) float gradeFromPitch = -vectorNode.TrVectorSections[tvsi].AX * (isForward ? 1 : -1); float curvature = GetCurvature(vectorNode, tvsi, isForward); List <ChartableTrackItem> items_local = trackItems.ToList(); if (isForward) { items_local.Reverse(); } PathChartPoint newPoint; foreach (ChartableTrackItem chartableItem in items_local) { if (chartableItem.TrackVectorSectionIndex == tvsi && sectionOffsetStart <= chartableItem.TrackVectorSectionOffset && chartableItem.TrackVectorSectionOffset < sectionOffsetEnd) { if (isForward) { //For forward, we start at the last item in the track newPoint = new PathChartPoint(chartableItem.Height, curvature, gradeFromPitch, sectionOffsetEnd - chartableItem.TrackVectorSectionOffset, chartableItem.ItemText, chartableItem.ItemType); sectionOffsetEnd = chartableItem.TrackVectorSectionOffset; } else { //For reverse, we have to swap forward and reverse speed limits ChartableTrackItemType itemType = chartableItem.ItemType == ChartableTrackItemType.SpeedLimitForward ? ChartableTrackItemType.SpeedLimitReverse : chartableItem.ItemType == ChartableTrackItemType.SpeedLimitReverse ? ChartableTrackItemType.SpeedLimitForward : chartableItem.ItemType; //For reverse, we start at the first item in the track newPoint = new PathChartPoint(chartableItem.Height, curvature, gradeFromPitch, chartableItem.TrackVectorSectionOffset - sectionOffsetStart, chartableItem.ItemText, itemType); sectionOffsetStart = chartableItem.TrackVectorSectionOffset; } additionalPoints.Add(newPoint); } } newPoint = new PathChartPoint(height, curvature, gradeFromPitch, sectionOffsetEnd - sectionOffsetStart); additionalPoints.Add(newPoint); newPoints.AddRange(additionalPoints); }
/// <summary> /// Constructor /// </summary> /// <param name="item">The original track item</param> /// <param name="travellerAtItem">The traveller located at the location of the track item</param> public ChartableTrackItem(TrackItem item, Traveller travellerAtItem) { this.Height = item.Location.Location.Y; this.ItemText = string.Empty; this.ItemType = ChartableTrackItemType.Station; switch (item) { case PlatformItem platformItem: ItemText = platformItem.Station; ItemType = ChartableTrackItemType.Station; break; case SpeedPostItem speedPostItem: this.ItemText = speedPostItem.Distance.ToString(System.Globalization.CultureInfo.CurrentCulture); if (speedPostItem.IsMilePost) { this.ItemType = ChartableTrackItemType.MilePost; } if (speedPostItem.IsLimit) { float relativeAngle = Microsoft.Xna.Framework.MathHelper.WrapAngle(travellerAtItem.RotY + speedPostItem.Angle - (float)Math.PI / 2); bool inSameDirection = Math.Abs(relativeAngle) < Math.PI / 2; if (inSameDirection) { this.ItemType = ChartableTrackItemType.SpeedLimitForward; } else { this.ItemType = ChartableTrackItemType.SpeedLimitReverse; } } break; } this.TrackVectorSectionIndex = travellerAtItem.TrackVectorSectionIndex; var travellerAtSectionStart = new Traveller(travellerAtItem); travellerAtSectionStart.MoveInSection(float.MinValue); // Move to begin of section this.TrackVectorSectionOffset = travellerAtItem.TrackNodeOffset - travellerAtSectionStart.TrackNodeOffset; }
/// <summary> /// Constructor /// </summary> /// <param name="item">The original track item</param> /// <param name="travellerAtItem">The traveller located at the location of the track item</param> public ChartableTrackItem(TrItem item, Traveller travellerAtItem) { this.Height = item.Y; this.ItemText = string.Empty; this.ItemType = ChartableTrackItemType.Station; switch (item.ItemType) { case TrItem.trItemType.trEMPTY: break; case TrItem.trItemType.trCROSSOVER: break; case TrItem.trItemType.trSIGNAL: break; case TrItem.trItemType.trSPEEDPOST: SpeedPostItem speedPost = item as SpeedPostItem; this.ItemText = speedPost.SpeedInd.ToString(System.Globalization.CultureInfo.CurrentCulture); if (speedPost.IsMilePost) { this.ItemType = ChartableTrackItemType.MilePost; } if (speedPost.IsLimit) { float relativeAngle = Microsoft.Xna.Framework.MathHelper.WrapAngle(travellerAtItem.RotY + speedPost.Angle - (float)Math.PI / 2); bool inSameDirection = Math.Abs(relativeAngle) < Math.PI / 2; if (inSameDirection) { this.ItemType = ChartableTrackItemType.SpeedLimitForward; } else { this.ItemType = ChartableTrackItemType.SpeedLimitReverse; } } break; case TrItem.trItemType.trPLATFORM: this.ItemText = (item as PlatformItem).Station; this.ItemType = ChartableTrackItemType.Station; break; case TrItem.trItemType.trSOUNDREGION: break; case TrItem.trItemType.trXING: break; case TrItem.trItemType.trSIDING: break; case TrItem.trItemType.trHAZZARD: break; case TrItem.trItemType.trPICKUP: break; case TrItem.trItemType.trCARSPAWNER: break; default: break; } this.TrackVectorSectionIndex = travellerAtItem.TrackVectorSectionIndex; var travellerAtSectionStart = new Traveller(travellerAtItem); travellerAtSectionStart.MoveInSection(float.MinValue); // Move to begin of section this.TrackVectorSectionOffset = travellerAtItem.TrackNodeOffset - travellerAtSectionStart.TrackNodeOffset; }