private static void UpdateStrokeStats(CurrentChasingStroke stroke, Tuple<NearPointResult, NearPointResult[]> hits, Tuple<Point3D, Vector3D>[] strokePoints, Point3D botPosition, double skipPointRadius) { List<NearPointResult> allHits = new List<NearPointResult>(); allHits.Add(hits.Item1); if (hits.Item2 != null) { allHits.AddRange(hits.Item2); } double? distanceSquared = null; int? index = null; foreach (NearPointResult hit in allHits) { if (hit == null) { continue; } if (distanceSquared == null || distanceSquared.Value > hit.DistanceSquared) { distanceSquared = hit.DistanceSquared; } int maxIndex = Math.Max(hit.SegmentFrom, hit.SegmentTo); if ((index == null || index.Value < maxIndex) && hit.DistanceSquared < skipPointRadius * skipPointRadius) { index = maxIndex; } if (hit.SegmentTo == strokePoints.Length - 1 && Vector3D.DotProduct(botPosition - strokePoints[hit.SegmentFrom].Item1, strokePoints[hit.SegmentFrom].Item2) > 0) { // Chasing the last point, and beyond the point's velocity. So it would have to fly back to get to the point. // This means that it is done chasing this stroke index = strokePoints.Length; // setting to an index beyond the stroke's range } } // Store the values if (distanceSquared != null) { stroke.MinDistance = Math.Sqrt(distanceSquared.Value); } if (index != null) { stroke.MinIndex = index.Value; } }
private Vector3D? GetStrokeAccel(SwarmObjectiveStrokes.Stroke objectiveStroke, Point3D position, Vector3D velocity) { const double VELOCITYINFLUENCERADIUS = 2d; const double TOWARDRADIUSMULT = .5; // making this smaller than the size of the velocity influence radius so there aren't any dead spots const double SKIPPOINTRADIUSMULT = 1d; if (objectiveStroke == null) { return null; } // Current stroke CurrentChasingStroke currentlyChasingStroke = _currentlyChasingStroke; if (currentlyChasingStroke == null || currentlyChasingStroke.Token != objectiveStroke.Token) { currentlyChasingStroke = new CurrentChasingStroke(objectiveStroke.Token); _currentlyChasingStroke = currentlyChasingStroke; } // Get affected by the stroke var hits = GetNearestSegmentsOrPoint(objectiveStroke.Points, position, currentlyChasingStroke.MinIndex); if (hits == null || (hits.Item1 == null && (hits.Item2 == null || hits.Item2.Length == 0))) { currentlyChasingStroke.MinIndex = objectiveStroke.Points.Length; currentlyChasingStroke.MinDistance = double.MaxValue; return null; } // Stats UpdateStrokeStats(currentlyChasingStroke, hits, objectiveStroke.Points, position, this.Radius * SKIPPOINTRADIUSMULT); #region build return Vector3D retVal = new Vector3D(0, 0, 0); double accel = this.MaxAccel; if (hits.Item1 != null) { retVal += GetStrokeAccel_Point(hits.Item1, position, accel, VELOCITYINFLUENCERADIUS, TOWARDRADIUSMULT); } if (hits.Item2 != null) { for (int cntr = 0; cntr < hits.Item2.Length; cntr++) { bool shouldAttractToward = cntr == 0 && hits.Item1 == null; retVal += GetStrokeAccel_Segment(hits.Item2[cntr], position, accel, VELOCITYINFLUENCERADIUS, TOWARDRADIUSMULT, shouldAttractToward); } } #endregion return retVal; }