internal void Randomize(double factor) { for (int i = 2; i < 8; i++) { Vector v = LinearCombinations.ElementAt(i); if (!ImmutablePoints.Contains(v)) { int sign = (i % 2 == 1) ? 1 : -1; Vector orth = Vector.Orthogonal(End - Start); orth = (orth / Vector.Abs(orth)) * (Utils.getNextDouble() * factor * sign); v.X += orth.X; v.Y += orth.Y; } } }
public void addPolygons() { Vector ChannelRadius = Channels[3].Start - Channels[0].Start; Point Ende = new Point(); Ende.longitude = c.XtoLongitude(Channels[3].Start.X); Ende.latitude = c.YtoLatitude(Channels[3].Start.Y); Point Start = new Point(); Start.longitude = c.XtoLongitude(Channels[0].Start.X); Start.latitude = c.YtoLatitude(Channels[0].Start.Y); double origDist = Converter.Distance(Ende, Start); ChannelRadius = (ChannelRadius / origDist) * (channel * (-1.0 / 2.0)); Vector ortho = Vector.Orthogonal(ChannelRadius) / 10.0; double factorLengthSides = 10.0; double distChannelRadius = -Vector.Abs(ChannelRadius); double orthoLengthFactor = 1.0; for (int i = 1; i < 8; i += 1) { Vector localChannelRadius; localChannelRadius = Vector.Orthogonal(Channels[0].LinearCombinations[i + 1] - Channels[0].LinearCombinations[i]); localChannelRadius = (localChannelRadius / Vector.Abs(localChannelRadius)) * distChannelRadius; ortho = Vector.Orthogonal(localChannelRadius) / orthoLengthFactor; Vector a1 = Channels[0].LinearCombinations[i] + localChannelRadius + ortho; Vector a2 = Channels[0].LinearCombinations[i + 1] + localChannelRadius - ortho; Vector a3 = a1 + ChannelRadius * factorLengthSides + ortho; Vector a4 = a2 + ChannelRadius * factorLengthSides - ortho; Polygons.Add(new ParcourPolygon(a1, a2, a4, a3)); Vector b1 = Channels[0].LinearCombinations[i] - localChannelRadius + ortho; Vector b2 = Channels[0].LinearCombinations[i + 1] - localChannelRadius - ortho; localChannelRadius = Vector.Orthogonal(Channels[1].LinearCombinations[i + 1] - Channels[1].LinearCombinations[i]); localChannelRadius = (localChannelRadius / Vector.Abs(localChannelRadius)) * distChannelRadius; ortho = Vector.Orthogonal(localChannelRadius) / orthoLengthFactor; Vector b3 = Channels[1].LinearCombinations[i] + localChannelRadius + ortho; Vector b4 = Channels[1].LinearCombinations[i + 1] + localChannelRadius - ortho; Polygons.Add(new ParcourPolygon(b1, b2, b4, b3)); Vector c1 = Channels[1].LinearCombinations[i] - localChannelRadius + ortho; Vector c2 = Channels[1].LinearCombinations[i + 1] - localChannelRadius - ortho; localChannelRadius = Vector.Orthogonal(Channels[2].LinearCombinations[i + 1] - Channels[2].LinearCombinations[i]); localChannelRadius = (localChannelRadius / Vector.Abs(localChannelRadius)) * distChannelRadius; ortho = Vector.Orthogonal(localChannelRadius) / orthoLengthFactor; Vector c3 = Channels[2].LinearCombinations[i] + localChannelRadius + ortho; Vector c4 = Channels[2].LinearCombinations[i + 1] + localChannelRadius - ortho; Polygons.Add(new ParcourPolygon(c1, c2, c4, c3)); Vector d1 = Channels[2].LinearCombinations[i] - localChannelRadius + ortho; Vector d2 = Channels[2].LinearCombinations[i + 1] - localChannelRadius - ortho; localChannelRadius = Vector.Orthogonal(Channels[3].LinearCombinations[i + 1] - Channels[3].LinearCombinations[i]); localChannelRadius = (localChannelRadius / Vector.Abs(localChannelRadius)) * distChannelRadius; ortho = Vector.Orthogonal(localChannelRadius) / orthoLengthFactor; Vector d3 = Channels[3].LinearCombinations[i] + localChannelRadius + ortho; Vector d4 = Channels[3].LinearCombinations[i + 1] + localChannelRadius - ortho; Polygons.Add(new ParcourPolygon(d1, d2, d4, d3)); Vector e1 = Channels[3].LinearCombinations[i] - localChannelRadius + ortho; Vector e2 = Channels[3].LinearCombinations[i + 1] - localChannelRadius - ortho; Vector e3 = e1 - ChannelRadius * factorLengthSides + ortho; Vector e4 = e2 - ChannelRadius * factorLengthSides - ortho; Polygons.Add(new ParcourPolygon(e1, e2, e4, e3)); } }
public void addPolygons() { Point Start = new Point(); Start.longitude = c.XtoLongitude(Channel.Start.X); Start.latitude = c.YtoLatitude(Channel.Start.Y); //TODO double latitude = Start.latitude; double longitude = Start.longitude; double channelMeterKm = channelWidth; double latitudePlus1 = latitude + 1; double longitudePlus1 = longitude + 1; double distLat1 = Converter.Distance(longitude, latitude, longitude, latitudePlus1); double distLong1 = Converter.Distance(longitude, latitude, longitudePlus1, latitude); double corridorDiffInLat = channelMeterKm / distLat1; double corridorDiffInLong = channelMeterKm / distLong1; double channelLatitude = corridorDiffInLat / 2; double channelLongitude = corridorDiffInLong / 2; double longitudePlusChannel = longitude + channelLongitude; double latitudePlusChannel = latitude + channelLatitude; double channelx = c.LongitudeToX(longitudePlusChannel) - Channel.Start.X; double channely = c.LatitudeToY(latitudePlusChannel) - Channel.Start.Y; Vector channel = new Vector(channelx, channely, 0); Vector startEnd = new Vector(Channel.End.X, Channel.End.Y, 0) - new Vector(Channel.Start.X, Channel.Start.Y, 0); Vector startEndOrtho = Vector.Orthogonal(startEnd) * (-1); Vector startEndOrthoNormalized = (startEndOrtho / Vector.Abs(startEndOrtho)) * Vector.Abs(channel); Vector startEndNormalized = (startEnd / Vector.Abs(startEnd)) * Vector.Abs(channel); for (int i = 1; i < 8; i++) { Vector localChannel = Channel.LinearCombinations[i + 1] - Channel.LinearCombinations[i]; Vector localChannelOrtho = Vector.Orthogonal(localChannel); Vector localChannelOrthoNormalized = (localChannelOrtho / Vector.Abs(localChannelOrtho)) * -Vector.Abs(channel); Vector a1_intersection = Vector.InterceptionLine(Channel.LinearCombinations[i], startEndOrtho, Channel.LinearCombinations[i] + localChannelOrthoNormalized - localChannel * 10, Channel.LinearCombinations[i + 1] + localChannelOrthoNormalized + localChannel * 10); { Vector localChannel2 = Channel.LinearCombinations[i] - Channel.LinearCombinations[i - 1]; Vector localChannelOrtho2 = Vector.Orthogonal(localChannel2); Vector localChannelOrthoNormalized2 = (localChannelOrtho2 / Vector.Abs(localChannelOrtho2)) * -Vector.Abs(channel); Vector a1_intersection2 = Vector.InterceptionLine(Channel.LinearCombinations[i], startEndOrtho, Channel.LinearCombinations[i] + localChannelOrthoNormalized2 - localChannel2 * 10, Channel.LinearCombinations[i] + localChannelOrthoNormalized2 + localChannel2 * 10); a1_intersection = new Vector(a1_intersection.X, Math.Min(a1_intersection.Y, a1_intersection2.Y), 0); } Vector a2_intersection = Vector.InterceptionLine(Channel.LinearCombinations[i + 1], startEndOrtho, Channel.LinearCombinations[i] + localChannelOrthoNormalized - localChannel * 10, Channel.LinearCombinations[i + 1] + localChannelOrthoNormalized + localChannel * 10); { Vector localChannel2 = Channel.LinearCombinations[i + 2] - Channel.LinearCombinations[i + 1]; Vector localChannelOrtho2 = Vector.Orthogonal(localChannel2); Vector localChannelOrthoNormalized2 = (localChannelOrtho2 / Vector.Abs(localChannelOrtho2)) * -Vector.Abs(channel); Vector a2_intersection2 = Vector.InterceptionLine(Channel.LinearCombinations[i + 1], startEndOrtho, Channel.LinearCombinations[i + 1] + localChannelOrthoNormalized2 - localChannel2 * 10, Channel.LinearCombinations[i + 1] + localChannelOrthoNormalized2 + localChannel2 * 10); a2_intersection = new Vector(a2_intersection.X, Math.Min(a2_intersection.Y, a2_intersection2.Y), 0); } Vector a1 = a1_intersection; Vector a2 = a2_intersection; Vector a3 = a1 + startEndOrtho / 3; Vector a4 = a2 + startEndOrtho / 3; Polygons.Add(new ParcourPolygon(a1, a2, a4, a3)); Vector b1_intersection = Vector.InterceptionLine(Channel.LinearCombinations[i], startEndOrtho, Channel.LinearCombinations[i] - localChannelOrthoNormalized - localChannel * 10, Channel.LinearCombinations[i + 1] - localChannelOrthoNormalized + localChannel * 10); { Vector localChannel2 = Channel.LinearCombinations[i] - Channel.LinearCombinations[i - 1]; Vector localChannelOrtho2 = Vector.Orthogonal(localChannel2); Vector localChannelOrthoNormalized2 = (localChannelOrtho2 / Vector.Abs(localChannelOrtho2)) * -Vector.Abs(channel); Vector b1_intersection2 = Vector.InterceptionLine(Channel.LinearCombinations[i], startEndOrtho, Channel.LinearCombinations[i] - localChannelOrthoNormalized2 - localChannel2 * 10, Channel.LinearCombinations[i] - localChannelOrthoNormalized2 + localChannel2 * 10); b1_intersection = new Vector(b1_intersection.X, Math.Max(b1_intersection.Y, b1_intersection2.Y), 0); } Vector b2_intersection = Vector.InterceptionLine(Channel.LinearCombinations[i + 1], startEndOrtho, Channel.LinearCombinations[i] - localChannelOrthoNormalized - localChannel * 10, Channel.LinearCombinations[i + 1] - localChannelOrthoNormalized + localChannel * 10); { Vector localChannel2 = Channel.LinearCombinations[i + 2] - Channel.LinearCombinations[i + 1]; Vector localChannelOrtho2 = Vector.Orthogonal(localChannel2); Vector localChannelOrthoNormalized2 = (localChannelOrtho2 / Vector.Abs(localChannelOrtho2)) * -Vector.Abs(channel); Vector b2_intersection2 = Vector.InterceptionLine(Channel.LinearCombinations[i + 1], startEndOrtho, Channel.LinearCombinations[i + 1] - localChannelOrthoNormalized2 - localChannel2 * 10, Channel.LinearCombinations[i + 1] - localChannelOrthoNormalized2 + localChannel2 * 10); b2_intersection = new Vector(b2_intersection.X, Math.Max(b2_intersection.Y, b2_intersection2.Y), 0); } Vector b1 = b1_intersection; Vector b2 = b2_intersection; Vector b3 = b1 - startEndOrtho / 3; Vector b4 = b2 - startEndOrtho / 3; Polygons.Add(new ParcourPolygon(b1, b2, b4, b3)); } }
public static List <PenaltySet> CalculatePenaltyPoints(FlightSet flight, out List <IntersectionPoint> lstIntersectionPoints) { bool useProhZoneCalculation = false; Point last = null; List <PenaltySet> result = new List <PenaltySet>(); List <LineP> PenaltyZoneLines = new List <LineP>(); // intersectionPoints will contain the intersection poinst of the flight path with SP, FP, PROH areas List <IntersectionPoint> intersectionPoints = new List <IntersectionPoint>(); QualificationRoundSet qr = flight.QualificationRoundSet; ParcourSet parcour = flight.QualificationRoundSet.ParcourSet; useProhZoneCalculation = (parcour.PenaltyCalcType != (int)ParcourType.CHANNELS); List <LineP> ChannelZoneLines = getAssignedChannelLineP(parcour, (Route)flight.Route); foreach (Line nl in parcour.Line.Where(p => p.Type == (int)LineType.PENALTYZONE)) { PenaltyZoneLines.Add(getLine(nl)); } // add also all channel-specific prohibited zones assigned channel PenaltyZoneLines.AddRange(getAssignedProhZonelLines(parcour, (Route)flight.Route)); List <LineP> dataLines = new List <LineP>(); foreach (Point g in flight.Point) { if (last != null) { LineP l = new LineP(); l.end = new Vector(g.longitude, g.latitude, 0); l.TimestamEnd = g.Timestamp; l.start = new Vector(last.longitude, last.latitude, 0); l.TimestamStart = last.Timestamp; dataLines.Add(l); } last = g; } LineP startLine = getStartLine(parcour, (Route)flight.Route); LineP endLine = getEndLine(parcour, (Route)flight.Route); if (startLine == null || endLine == null) { lstIntersectionPoints = intersectionPoints; return(result); } LineP takeOffLine = new LineP(); takeOffLine.start = new Vector(qr.TakeOffLine.A.longitude, qr.TakeOffLine.A.latitude, 0); takeOffLine.end = new Vector(qr.TakeOffLine.B.longitude, qr.TakeOffLine.B.latitude, 0); takeOffLine.orientation = Vector.Orthogonal(takeOffLine.end - takeOffLine.start); long maxTimestamp = 0; maxTimestamp = flight.Point.Max(x => x.Timestamp); // For TakeOff-, Start- and End Line, we obviously(?) assume that these lines should have been passed two minutes before the end of recording // below values are used in case they are not passed bool shouldHaveCrossedTakeOff = (maxTimestamp - 2 * tickOfMinute) > flight.TimeTakeOff; bool shouldHaveCrossedStart = (maxTimestamp - 2 * tickOfMinute) > flight.TimeStartLine; bool shouldHaveCrossedEnd = (maxTimestamp - 2 * tickOfMinute) > flight.TimeEndLine; bool haveCrossedTakeOff = false; bool haveCrossedStart = false; bool haveCrossedEnd = false; bool insidePenalty = false; long timeSinceInsidePenalty = 0; bool outsideOwnChannel = true; long timeSinceOutsideOwnChannel = 0; bool isFirstTimeIntoChannel = true; IntersectionPoint ipTakeOff = new IntersectionPoint(); IntersectionPoint ipStart = new IntersectionPoint(); IntersectionPoint ipEnd = new IntersectionPoint(); foreach (LineP l in dataLines) { double intersectionTakeOff = getIntersection(l, takeOffLine); double intersectionStart = getIntersection(l, startLine); double intersectionEnd = getIntersection(l, endLine); IntersectionPoint ip = new IntersectionPoint(); #region crossing takeOff line if (getIntersection(l, takeOffLine, out ip) && !haveCrossedTakeOff) { haveCrossedTakeOff = true; intersectionPoints.Add(ip); long crossTime = ip.Timestamp; crossTime = ((crossTime + (tickOfSecond / 2) + 1) / tickOfSecond) * tickOfSecond; // round ipTakeOff = ip; long diff = crossTime - flight.TimeTakeOff; PenaltySet penalty = new PenaltySet(); penalty.Points = (diff > C_TKOF_TimeUpper * tickOfSecond || diff < C_TKOF_TimeLower * tickOfSecond) ? C_TKOF_MaxPenalty : 0; penalty.Reason = string.Format("Take-off Line planned: {1}, actual: {0}", new DateTime((Int64)crossTime).ToString(C_TimeFormat, DateTimeFormatInfo.InvariantInfo), new DateTime((Int64)flight.TimeTakeOff).ToString(C_TimeFormat, DateTimeFormatInfo.InvariantInfo)); result.Add(penalty); } #endregion #region crossing start line if (getIntersection(l, startLine, out ip) & !haveCrossedStart) { haveCrossedStart = true; intersectionPoints.Add(ip); long crossTime = ip.Timestamp; ipStart = ip; long diff = Math.Abs(crossTime - flight.TimeStartLine); crossTime = ((crossTime + (tickOfSecond / 2) + 1) / tickOfSecond) * tickOfSecond; // round int sec = (int)((diff + (tickOfSecond / 2) + 1) / tickOfSecond); PenaltySet penalty = new PenaltySet(); penalty.Points = (diff > C_SPFP_TimeTolerance * tickOfSecond) ? Math.Min((sec - C_SPFP_TimeTolerance) * C_PointsPerSec, C_SPFP_MaxPenalty) : 0; penalty.Reason = string.Format("SP Line planned: {1}, actual: {0}", new DateTime((Int64)crossTime).ToString(C_TimeFormat, DateTimeFormatInfo.InvariantInfo), new DateTime((Int64)flight.TimeStartLine).ToString(C_TimeFormat, DateTimeFormatInfo.InvariantInfo)); result.Add(penalty); } #endregion if (useProhZoneCalculation || ChannelZoneLines.Count == 0) { #region entering or leaving prohibited zone bool stateChanged = false; //IntersectionPoint ip = new IntersectionPoint(); if (intersectsProhAreaPoint(PenaltyZoneLines, l, out stateChanged, out ip)) { if (stateChanged) { intersectionPoints.Add(ip); if (!insidePenalty) { insidePenalty = true; timeSinceInsidePenalty = ip.Timestamp; } else { insidePenalty = false; long diff = ip.Timestamp - timeSinceInsidePenalty; if (diff > tickOfSecond * C_PROH_TimeTolerance) { PenaltySet penalty = new PenaltySet(); // round times for entering/leaving penalty zone to nearest full second long pstart = ((timeSinceInsidePenalty + (tickOfSecond / 2) + 1) / tickOfSecond) * tickOfSecond; // rounded long pend = ((ip.Timestamp + (tickOfSecond / 2) + 1) / tickOfSecond) * tickOfSecond; // rounded int sec = (int)((pend - pstart) / tickOfSecond); penalty.Points = (sec - C_PROH_TimeTolerance) * C_PointsPerSec; // Max penalty inside PROH zone: ======>> NOTE: acc FAI rules disabled after NOV 2017; zero means no maximum per event penalty.Points = C_MaxPenaltyPerEvent > 0 ? Math.Min((sec - C_PROH_TimeTolerance) * C_PointsPerSec, C_MaxPenaltyPerEvent) : penalty.Points; //penalty.Points = C_MaxPenaltyPerEvent > 0 ? Math.Min((sec - 5) * 3, C_MaxPenaltyPerEvent) : penalty.Points; penalty.Reason = string.Format("Penalty zone for {0} sec, [{1} - {2}]", sec, new DateTime(pstart).ToString(C_TimeFormat, DateTimeFormatInfo.InvariantInfo), new DateTime(pend).ToString(C_TimeFormat, DateTimeFormatInfo.InvariantInfo)); result.Add(penalty); } } } } #endregion } else { #region entering or leaving channel bool stateChanged = false; if (intersectsOwnChannel(ChannelZoneLines, l, out stateChanged, out ip)) { if (stateChanged) { intersectionPoints.Add(ip); if (!outsideOwnChannel) { outsideOwnChannel = true; timeSinceOutsideOwnChannel = ip.Timestamp; } else { if (isFirstTimeIntoChannel) { isFirstTimeIntoChannel = false; if (haveCrossedStart) { timeSinceOutsideOwnChannel = ipStart.Timestamp; } else { timeSinceOutsideOwnChannel = flight.TimeStartLine; } } outsideOwnChannel = false; long diff = ip.Timestamp - timeSinceOutsideOwnChannel; if (diff > tickOfSecond * C_PROH_TimeTolerance) { PenaltySet penalty = new PenaltySet(); // round times for entering/leaving penalty zone to nearest full second long pstart = ((timeSinceOutsideOwnChannel + (tickOfSecond / 2) + 1) / tickOfSecond) * tickOfSecond; // rounded long pend = ((ip.Timestamp + (tickOfSecond / 2) + 1) / tickOfSecond) * tickOfSecond; // rounded int sec = (int)((pend - pstart) / tickOfSecond); penalty.Points = (sec - C_PROH_TimeTolerance) * C_PointsPerSec; penalty.Points = C_MaxPenaltyPerEvent > 0 ? Math.Min((sec - C_PROH_TimeTolerance) * C_PointsPerSec, C_MaxPenaltyPerEvent) : penalty.Points; //penalty.Points = C_MaxPenaltyPerEvent > 0 ? Math.Min((sec - 5) * 3, C_MaxPenaltyPerEvent) : penalty.Points; penalty.Reason = string.Format("outside channel for {0} sec, [{1} - {2}]", sec, new DateTime(pstart).ToString(C_TimeFormat, DateTimeFormatInfo.InvariantInfo), new DateTime(pend).ToString(C_TimeFormat, DateTimeFormatInfo.InvariantInfo)); result.Add(penalty); } } } } else { // check if end line is passed now but outside the cannel. if yes, set outSideOwnChannel = false if (getIntersection(l, endLine, out ip)) { outsideOwnChannel = false; long diff = ip.Timestamp - timeSinceOutsideOwnChannel; if (diff > tickOfSecond * C_PROH_TimeTolerance) { PenaltySet penalty = new PenaltySet(); // round times for entering/leaving penalty zone to nearest full second long pstart = ((timeSinceOutsideOwnChannel + (tickOfSecond / 2) + 1) / tickOfSecond) * tickOfSecond; // rounded long pend = ((ip.Timestamp + (tickOfSecond / 2) + 1) / tickOfSecond) * tickOfSecond; // rounded int sec = (int)((pend - pstart) / tickOfSecond); penalty.Points = (sec - C_PROH_TimeTolerance) * C_PointsPerSec; // Max penalty outside channel; zero value means no Max penalty penalty.Points = C_MaxPenaltyPerEvent > 0 ? Math.Min((sec - C_PROH_TimeTolerance) * C_PointsPerSec, C_MaxPenaltyPerEvent) : penalty.Points; //penalty.Points = C_MaxPenaltyPerEvent > 0 ? Math.Min((sec - 5) * 3, C_MaxPenaltyPerEvent) : penalty.Points; penalty.Reason = string.Format("outside channel for {0} sec, [{1} - {2}]", sec, new DateTime(pstart).ToString(C_TimeFormat, DateTimeFormatInfo.InvariantInfo), new DateTime(pend).ToString(C_TimeFormat, DateTimeFormatInfo.InvariantInfo)); result.Add(penalty); } } } #endregion } #region crossing end line if (getIntersection(l, endLine, out ip) & !haveCrossedEnd) { haveCrossedEnd = true; intersectionPoints.Add(ip); long crossTime = ip.Timestamp; ipEnd = ip; long diff = Math.Abs(crossTime - flight.TimeEndLine); crossTime = ((crossTime + (tickOfSecond / 2) + 1) / tickOfSecond) * tickOfSecond; // round int sec = (int)((diff + (tickOfSecond / 2) + 1) / tickOfSecond); PenaltySet penalty = new PenaltySet(); penalty.Points = (diff > C_SPFP_TimeTolerance * tickOfSecond) ? Math.Min((sec - C_SPFP_TimeTolerance) * C_PointsPerSec, C_SPFP_MaxPenalty) : 0; penalty.Reason = string.Format("FP Line planned: {1}, actual: {0}", new DateTime((Int64)crossTime).ToString(C_TimeFormat, DateTimeFormatInfo.InvariantInfo), new DateTime((Int64)flight.TimeEndLine).ToString(C_TimeFormat, DateTimeFormatInfo.InvariantInfo)); result.Add(penalty); } #endregion } #region handling cases where Takeoff-, Start- or End line are not observed/never crossed if (shouldHaveCrossedStart && !haveCrossedStart) { PenaltySet penalty = new PenaltySet(); penalty.Points = C_SPFP_MaxPenalty; penalty.Reason = "SP Line not passed"; result.Insert(0, penalty); // add to begin of list } ; if (shouldHaveCrossedTakeOff && !haveCrossedTakeOff) { PenaltySet penalty = new PenaltySet(); penalty.Points = C_TKOF_MaxPenalty; penalty.Reason = "Takeoff Line not passed"; result.Insert(0, penalty); // add to begin of list } ; if (shouldHaveCrossedEnd && !haveCrossedEnd) { PenaltySet penalty = new PenaltySet(); // TODO: handle the case where we have channel calculation but no FP line if (!(useProhZoneCalculation || ChannelZoneLines.Count == 0) && outsideOwnChannel) { outsideOwnChannel = false; long crossTime = flight.TimeEndLine; long diff = Math.Abs(crossTime - timeSinceOutsideOwnChannel); if (diff > C_SPFP_TimeTolerance * tickOfSecond) { crossTime = ((crossTime + (tickOfSecond / 2) + 1) / tickOfSecond) * tickOfSecond; // round int sec = (int)((diff + (tickOfSecond / 2) + 1) / tickOfSecond); penalty.Points = Math.Min((sec - C_SPFP_TimeTolerance) * C_PointsPerSec, C_SPFP_MaxPenalty); penalty.Reason = string.Format("outside channel for {0} sec, [{1} - {2}]", sec, new DateTime(timeSinceOutsideOwnChannel).ToString(C_TimeFormat, DateTimeFormatInfo.InvariantInfo), new DateTime(crossTime).ToString(C_TimeFormat, DateTimeFormatInfo.InvariantInfo)); result.Add(penalty); } } penalty = new PenaltySet(); penalty.Points = C_SPFP_MaxPenalty; penalty.Reason = "FP Line not passed"; result.Add(penalty); } ; #endregion lstIntersectionPoints = intersectionPoints; return(result); }