public static Vector2 GetClosestOutsidePoint(Vector2 from, List<Geometry.Polygon> polygons) { var result = new List<Vector2>(); foreach (var poly in polygons) { for (var i = 0; i <= poly.Points.Count - 1; i++) { var sideStart = poly.Points[i]; var sideEnd = poly.Points[(i == poly.Points.Count - 1) ? 0 : i + 1]; result.Add(from.ProjectOn(sideStart, sideEnd).SegmentPoint); } } return result.MinOrDefault(vector2 => vector2.Distance(from)); }
//http://csharphelper.com/blog/2014/09/determine-where-a-line-intersects-a-circle-in-c/ // Find the points of intersection. public static int FindLineCircleIntersections( Vector2 center, float radius, Vector2 from, Vector2 to, out Vector2 intersection1, out Vector2 intersection2) { float cx = center.X; float cy = center.Y; float dx, dy, A, B, C, det, t; dx = to.X - from.X; dy = to.Y - from.Y; A = dx * dx + dy * dy; B = 2 * (dx * (from.X - cx) + dy * (from.Y - cy)); C = (from.X - cx) * (from.X - cx) + (from.Y - cy) * (from.Y - cy) - radius * radius; det = B * B - 4 * A * C; if ((A <= 0.0000001) || (det < 0)) { // No real solutions. intersection1 = new Vector2(float.NaN, float.NaN); intersection2 = new Vector2(float.NaN, float.NaN); return 0; } else if (det == 0) { // One solution. t = -B / (2 * A); intersection1 = new Vector2(from.X + t * dx, from.Y + t * dy); intersection2 = new Vector2(float.NaN, float.NaN); var projection1 = intersection1.ProjectOn(from, to); if (projection1.IsOnSegment) { return 1; } else { return 0; } } else { // Two solutions. t = (float)((-B + Math.Sqrt(det)) / (2 * A)); intersection1 = new Vector2(from.X + t * dx, from.Y + t * dy); t = (float)((-B - Math.Sqrt(det)) / (2 * A)); intersection2 = new Vector2(from.X + t * dx, from.Y + t * dy); var numIntersections = 0; var projection1 = intersection1.ProjectOn(from, to); var projection2 = intersection2.ProjectOn(from, to); if (projection1.IsOnSegment && projection2.IsOnSegment) { return 2; } else if (projection1.IsOnSegment && !projection2.IsOnSegment) { return 1; } else if (!projection1.IsOnSegment && projection2.IsOnSegment) { intersection1 = intersection2; return 1; } return 0; } }
public static Vector2 GetSpellProjection(this Spell spell, Vector2 pos, bool predictPos = false) { if (spell.SpellType == SpellType.Line || spell.SpellType == SpellType.Arc) { if (predictPos) { var spellPos = spell.CurrentSpellPosition; var spellEndPos = spell.GetSpellEndPosition(); return pos.ProjectOn(spellPos, spellEndPos).SegmentPoint; } return pos.ProjectOn(spell.StartPos, spell.EndPos).SegmentPoint; } if (spell.SpellType == SpellType.Circular) { return spell.EndPos; } return Vector2.Zero; }
public static bool inSkillShot(Spell spell, Vector2 position, float radius) { if (spell.info.spellType == SpellType.Line) { Vector2 spellPos = SpellDetector.GetCurrentSpellPosition(spell); //leave little space at back of skillshot if (spell.info.projectileSpeed == float.MaxValue && Evade.GetTickCount() - spell.startTime > spell.info.spellDelay) { return false; } var projection = position.ProjectOn(spellPos, spell.endPos); if (projection.SegmentPoint.Distance(spell.endPos) < 100) //Check Skillshot endpoints { //unfinished } return projection.SegmentPoint.Distance(position) <= GetSpellRadius(spell) + radius; } else if (spell.info.spellType == SpellType.Circular) { return position.Distance(spell.endPos) <= GetSpellRadius(spell) + radius; } else if (spell.info.spellType == SpellType.Cone) { } return false; }