private void Init() { if (radiusDEG > 90) { //--spans more than half the globe Debug.Assert(enclosingBox.GetWidth() == 360); double backDistDEG = 180 - radiusDEG; if (backDistDEG > 0) { double backRadius = 180 - radiusDEG; double backX = DistanceUtils.NormLonDEG(GetCenter().GetX() + 180); double backY = DistanceUtils.NormLatDEG(GetCenter().GetY() + 180); //Shrink inverseCircle as small as possible to avoid accidental overlap. // Note that this is tricky business to come up with a value small enough // but not too small or else numerical conditioning issues become a problem. backRadius -= Math.Max(Ulp(Math.Abs(backY) + backRadius), Ulp(Math.Abs(backX) + backRadius)); if (inverseCircle != null) { inverseCircle.Reset(backX, backY, backRadius); } else { inverseCircle = new GeoCircle(ctx.MakePoint(backX, backY), backRadius, ctx); } } else { inverseCircle = null; //whole globe } horizAxisY = GetCenter().GetY(); //although probably not used } else { inverseCircle = null; double _horizAxisY = ctx.GetDistCalc().CalcBoxByDistFromPt_yHorizAxisDEG(GetCenter(), radiusDEG, ctx); //some rare numeric conditioning cases can cause this to be barely beyond the box if (_horizAxisY > enclosingBox.GetMaxY()) { horizAxisY = enclosingBox.GetMaxY(); } else if (_horizAxisY < enclosingBox.GetMinY()) { horizAxisY = enclosingBox.GetMinY(); } else { horizAxisY = _horizAxisY; } //Debug.Assert(enclosingBox.Relate_yRange(horizAxis, horizAxis, ctx).Intersects()); } }
private readonly GeoCircle inverseCircle; //when distance reaches > 1/2 way around the world, cache the inverse. #endregion Fields #region Constructors public GeoCircle(Point p, double dist, SpatialContext ctx) : base(p, dist, ctx) { Debug.Assert(ctx.IsGeo()); //In the direction of latitude (N,S), distance is the same number of degrees. distDEG = ctx.GetDistCalc().DistanceToDegrees(distRadius); if (distDEG > 90) { //--spans more than half the globe Debug.Assert(enclosingBox.GetWidth() == 360); double backDistDEG = 180 - distDEG; if (backDistDEG > 0) { double backDistance = ctx.GetDistCalc().DegreesToDistance(backDistDEG); //shrink inverseCircle as small as possible to avoid accidental overlap backDistance -= Ulp(backDistance); Point backPoint = ctx.MakePoint(GetCenter().GetX() + 180, GetCenter().GetY() + 180); inverseCircle = new GeoCircle(backPoint, backDistance, ctx); } else inverseCircle = null;//whole globe horizAxisY = GetCenter().GetY();//although probably not used } else { inverseCircle = null; double _horizAxisY = ctx.GetDistCalc().CalcBoxByDistFromPt_yHorizAxisDEG(GetCenter(), dist, ctx); //some rare numeric conditioning cases can cause this to be barely beyond the box if (_horizAxisY > enclosingBox.GetMaxY()) { horizAxisY = enclosingBox.GetMaxY(); } else if (_horizAxisY < enclosingBox.GetMinY()) { horizAxisY = enclosingBox.GetMinY(); } else { horizAxisY = _horizAxisY; } //Debug.Assert(enclosingBox.Relate_yRange(horizAxis, horizAxis, ctx).Intersects()); } }