using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing; using System.Threading.Tasks; namespace Txgy.EWS.Client.FocalMechanism.Model { // summary // object for the result of polygon public class Polygon :Graph { public List upperBound { get; set; } public List lowerBound { get; set; } public Line axis { get; set; } public Polygon() { upperBound = new List(); lowerBound = new List(); } // summary // add point to current polygon public void addPoint(FMStation p) { if (p == null) return; //upper bound int upIndex = getPoint(upperBound, p); if (upIndex == upperBound.Count) { upperBound.Add(p); smoothUppderBound(upperBound, upperBound.Count - 1); } else if (upIndex == -1) { upperBound.Insert(0, p); smoothUppderBound(upperBound, 0); } else if (p.X == upperBound[upIndex].X) { if (p.Y > upperBound[upIndex].Y) { upperBound[upIndex] = p; smoothUppderBound(upperBound, upIndex); } } else { if (isAbove(upperBound[upIndex - 1], upperBound[upIndex], p)) { upperBound.Insert(upIndex, p); smoothUppderBound(upperBound, upIndex); } } //lower bound int downIndex = getPoint(lowerBound, p); if (downIndex == lowerBound.Count) { lowerBound.Add(p); smoothLowerBound(lowerBound, lowerBound.Count - 1); } else if (downIndex == -1) { lowerBound.Insert(0, p); smoothLowerBound(lowerBound, 0); } else if (p.X == lowerBound[downIndex].X) { if (p.Y > lowerBound[downIndex].Y) { lowerBound[downIndex] = p; smoothLowerBound(lowerBound, downIndex); } } else { if (isBelow(lowerBound[downIndex - 1], lowerBound[downIndex], p)) { lowerBound.Insert(downIndex, p); smoothLowerBound(lowerBound, downIndex); } } } // summary // check if this polygon contains this station public bool contains(FMStation p) { if (p == null) return false; //upper bound int upIndex = getPoint(upperBound, p); if (upIndex == upperBound.Count || upIndex == -1) { return false; } else if (p.X == upperBound[upIndex].X) { if (p.Y > upperBound[upIndex].Y) { return false; } } else { if (isAbove(upperBound[upIndex - 1], upperBound[upIndex], p)) { return false; } } //lower bound int downIndex = getPoint(lowerBound, p); if (downIndex == lowerBound.Count || downIndex == -1) { return false; } else if (p.X == lowerBound[downIndex].X) { if (p.Y > lowerBound[downIndex].Y) { return false; } } else { if (isBelow(lowerBound[downIndex - 1], lowerBound[downIndex], p)) { return false; } } return true; } private int getPoint(List l, FMStation p) { if (l.Count == 0 || p.X < l[0].X) return -1; for (int i = 0; i < l.Count; i++) { if (p.X <= l[i].X) return i; } return l.Count; } private void smoothUppderBound(List l, int i) { while (l.Count - i > 2 && isBelow(l[i], l[i + 2], l[i + 1])) { l.RemoveAt(i + 1); } while (i > 1 && isBelow(l[i - 2], l[i], l[i - 1])) { l.RemoveAt(i - 1); i--; } } private void smoothLowerBound(List l, int i) { while (l.Count - i > 2 && isAbove(l[i], l[i + 2], l[i + 1])) { l.RemoveAt(i + 1); } while (i > 1 && isAbove(l[i - 2], l[i], l[i - 1])) { l.RemoveAt(i - 1); i--; } } // summary // return if target point is above the line from a to b private bool isAbove(FMStation a, FMStation b, FMStation target) { double lineY = (b.Y - a.Y) / (b.X - a.X) * (target.X - a.X) + a.Y; return target.Y >= lineY; } // summary // return if target point is below the line from a to b private bool isBelow(FMStation a, FMStation b, FMStation target) { double lineY = (b.Y - a.Y) / (b.X - a.X) * (target.X - a.X) + a.Y; return target.Y <= lineY; } } }