public PeriodicDrawableBox(LocalCS cs, Geometry.IRandomAccessRange <Geometry.Point> points, Geometry.Unit unit) : base(true) { int count = points.Count + 1; xs_orig = new float[count]; points_rel = new PointF[count]; xs_orig[0] = cs.ConvertX(points[0][0]); points_rel[0] = cs.Convert(points[0]); for (int i = 1; i < points.Count; ++i) { xs_orig[i] = cs.ConvertX(points[i][0]); // always relative to p0 double distNorm = Geometry.NormalizedAngleUnsigned(points[i][0] - points[0][0], unit); // [0, 2pi] - min is always lesser than max double x_curr = points[0][0] + distNorm; // always relative to p0 points_rel[i] = new PointF(cs.ConvertX(x_curr), cs.ConvertY(points[i][1])); } // close xs_orig[points.Count] = xs_orig[0]; points_rel[points.Count] = points_rel[0]; }
public PeriodicDrawablePolygon(LocalCS cs, Geometry.IRandomAccessRange <Geometry.Point> outer, IEnumerable <Geometry.IRandomAccessRange <Geometry.Point> > inners, Geometry.Box box, Geometry.Unit unit) { this.outer = new PeriodicDrawableRange(cs, outer, box, unit); minf = this.outer.minf; maxf = this.outer.maxf; periodf = this.outer.periodf; box_minf = this.outer.box_minf; box_maxf = this.outer.box_maxf; this.inners = new List <PeriodicDrawableRange>(); int i = 0; foreach (var inner in inners) { this.inners.Add(new PeriodicDrawableRange(cs, inner, box, unit)); // expand relative box X if (this.inners[i].minf < minf) { minf = this.inners[i].minf; } if (this.inners[i].maxf > maxf) { maxf = this.inners[i].maxf; } } }
// For GraphicalWatch public static bool Draw(Graphics graphics, IDrawable drawable, Geometry.Traits traits, Settings settings, Colors colors) { if (drawable == null) { return(false); } if (traits != null && traits.CoordinateSystem == Geometry.CoordinateSystem.SphericalPolar) { throw new Exception("This coordinate system is not yet supported."); } if (settings.color == Color.Empty) { settings.color = DefaultColor(drawable, colors); } Geometry.Box aabb = drawable.Aabb(traits, true); if (aabb.IsValid()) { Geometry.Unit unit = (traits != null) ? traits.Unit : Geometry.Unit.None; bool fill = (traits == null); Drawer.DrawAxes(graphics, aabb, unit, colors, fill); drawable.Draw(aabb, graphics, settings, traits); } return(true); }
public static Geometry.Interval RelativeEnvelopeLon(NSphere nsphere, Geometry.Unit unit) { double cx = nsphere.Center[0]; double r = Math.Abs(nsphere.Radius); // NOTE: The radius is always in the units of the CS which is technically wrong return(new Geometry.Interval(cx - r, cx + r)); }
public static Geometry.Interval RelativeEnvelopeLon(Geometry.IRandomAccessRange <Geometry.Point> outer, IEnumerable <Geometry.IRandomAccessRange <Geometry.Point> > inners, Geometry.Unit unit) { Geometry.Interval result = RelativeEnvelopeLon(outer, true, unit); foreach (var inner in inners) { result.Expand(RelativeEnvelopeLon(inner, true, unit)); } return(result); }
public void DrawPeriodic(LocalCS cs, Geometry.Box box, Geometry.Interval interval, Geometry.Unit unit, IPeriodicDrawable drawer, bool fill, bool drawDirs, bool drawDots) { double twoPi = Geometry.FullAngle(unit); float periodf = cs.ConvertDimensionX(twoPi); float box_minf = cs.ConvertX(box.Min[0]); float box_maxf = cs.ConvertX(box.Max[0]); float minf = cs.ConvertX(interval.Min); float maxf = cs.ConvertX(interval.Max); if (maxf >= box_minf && minf <= box_maxf) { drawer.DrawOne(this, 0, fill, drawDirs, drawDots); } // west float minf_i = minf; float maxf_i = maxf; float translationf = 0; while (maxf_i >= box_minf && Util.Assign(ref maxf_i, maxf_i - periodf)) { translationf -= periodf; minf_i -= periodf; //maxf_i -= periodf; // subtracted above if (maxf_i >= box_minf && minf_i <= box_maxf) { drawer.DrawOne(this, translationf, fill, drawDirs, drawDots); } } // east minf_i = minf; maxf_i = maxf; translationf = 0; while (minf_i <= box_maxf && Util.Assign(ref minf_i, minf_i + periodf)) { translationf += periodf; //minf_i += periodf; // added above maxf_i += periodf; if (maxf_i >= box_minf && minf_i <= box_maxf) { drawer.DrawOne(this, translationf, fill, drawDirs, drawDots); } } }
public PeriodicDrawablePolygon(LocalCS cs, Geometry.IRandomAccessRange <Geometry.Point> outer, IEnumerable <Geometry.IRandomAccessRange <Geometry.Point> > inners, Geometry.Unit unit, bool densify) { this.outer = new PeriodicDrawableRange(cs, outer, true, unit, densify); this.inners = new List <PeriodicDrawableRange>(); foreach (var inner in inners) { PeriodicDrawableRange pd = new PeriodicDrawableRange(cs, inner, true, unit, densify); this.inners.Add(pd); } }
public void DrawPeriodic(LocalCS cs, Geometry.Box box, Geometry.Interval interval, Geometry.Unit unit, IPeriodicDrawable drawer, bool fill, bool drawDirs, bool drawDots) { double pi = Geometry.HalfAngle(unit); float periodf = cs.ConvertDimensionX(2 * pi); float box_minf = cs.ConvertX(box.Min[0]); float box_maxf = cs.ConvertX(box.Max[0]); float minf = cs.ConvertX(interval.Min); float maxf = cs.ConvertX(interval.Max); if (maxf >= box_minf && minf <= box_maxf) { drawer.DrawOne(this, 0, fill, drawDirs, drawDots); } // west float minf_i = minf; float maxf_i = maxf; float translationf = 0; while (maxf_i >= box_minf) { translationf -= periodf; minf_i -= periodf; maxf_i -= periodf; if (maxf_i >= box_minf && minf_i <= box_maxf) { drawer.DrawOne(this, translationf, fill, drawDirs, drawDots); } } // east minf_i = minf; maxf_i = maxf; translationf = 0; while (minf_i <= box_maxf) { translationf += periodf; minf_i += periodf; maxf_i += periodf; if (maxf_i >= box_minf && minf_i <= box_maxf) { drawer.DrawOne(this, translationf, fill, drawDirs, drawDots); } } }
// For GeometryWatch and PlotWatch static Geometry.Box Draw(Graphics graphics, bool ignoreTraits, IDrawable[] drawables, Geometry.Traits[] traits, Settings[] settings, Colors colors, ZoomBox zoomBox) { if (drawables.Length != traits.Length || drawables.Length != settings.Length) { throw new ArgumentOutOfRangeException("drawables.Length, traits.Length, settings.Length"); } Geometry.Box box = new Geometry.Box(); Geometry.AssignInverse(box); int drawnCount = 0; int count = drawables.Length; bool[] drawnFlags = new bool[count]; HashSet <int> dimensions = new HashSet <int>(); HashSet <Geometry.CoordinateSystem> csystems = new HashSet <Geometry.CoordinateSystem>(); HashSet <Geometry.Unit> units = new HashSet <Geometry.Unit>(); for (int i = 0; i < count; ++i) { if (ignoreTraits) { traits[i] = null; } if (drawables[i] != null) { if (traits[i] != null) { dimensions.Add(traits[i].Dimension); csystems.Add(traits[i].CoordinateSystem); units.Add(traits[i].Unit); } Geometry.Box aabb = drawables[i].Aabb(traits[i], false); Geometry.Expand(box, aabb); ++drawnCount; drawnFlags[i] = aabb.IsValid(); } } if (drawnCount > 0) { if (csystems.Count > 1) { throw new Exception("Multiple coordinate systems detected."); } if (csystems.Count > 0 && csystems.First() == Geometry.CoordinateSystem.SphericalPolar) { throw new Exception("This coordinate system is not yet supported."); } if (units.Count > 1) { throw new Exception("Multiple units detected."); } Geometry.Traits commonTraits = (dimensions.Count > 0 && csystems.Count > 0 && units.Count > 0) ? new Geometry.Traits(dimensions.Max(), csystems.First(), units.First()) : null; bool fill = (commonTraits == null); // Fragment of the box if (box.IsValid() && zoomBox.IsZoomed()) { // window coordinates of the box LocalCS cs = new LocalCS(box, graphics, fill); box = cs.BoxFromZoomBox(zoomBox); // TODO: With current approach changing the original box (resize, enlarge, etc.) // may produce wierd results because zoomBox is relative to the original box. } // Axes if (box.IsValid()) { Geometry.Unit unit = commonTraits != null ? commonTraits.Unit : Geometry.Unit.None; Drawer.DrawAxes(graphics, box, unit, colors, fill); } // Drawables for (int i = 0; i < count; ++i) { if (drawables[i] != null && drawnFlags[i] == true) { drawables[i].Draw(box, graphics, settings[i], commonTraits); } } // Scales if (box.IsValid()) { Drawer.DrawScales(graphics, box, colors, fill); } // CS info if (commonTraits != null) { SolidBrush brush = new SolidBrush(colors.TextColor); Font font = new Font(new FontFamily(System.Drawing.Text.GenericFontFamilies.SansSerif), 10); string str = Geometry.Name(csystems.First()); if (units.First() != Geometry.Unit.None) { str += '[' + Geometry.Name(units.First()) + ']'; } graphics.DrawString(str, font, brush, 0, 0); } return(box); } return(null); }
public PeriodicDrawableNSphere(LocalCS cs, Geometry.NSphere nsphere, Geometry.Unit unit) { // NOTE: The radius is always in the units of the CS which is technically wrong c_rel = cs.Convert(nsphere.Center); r = cs.ConvertDimensionX(nsphere.Radius); }
public static bool DrawAxes(Graphics graphics, Geometry.Box box, Geometry.Unit unit, Colors colors, bool fill) { if (!box.IsValid()) { return(false); } LocalCS cs = new LocalCS(box, graphics, fill); // NOTE: the coordinates limit of MS GDI+ is 1073741951 so below // avoid passing such coordinates. But instead of checking this // value or similar one check whether or not an axis is range // of an image. // Axes float h = graphics.VisibleClipBounds.Height; float w = graphics.VisibleClipBounds.Width; Pen prime_pen = new Pen(colors.AxisColor, 1); if (unit == Geometry.Unit.None) { // Y axis float x0 = cs.ConvertX(0.0); if (0 <= x0 && x0 <= w) { graphics.DrawLine(prime_pen, x0, 0, x0, h); } // X axis float y0 = cs.ConvertY(0.0); if (0 <= y0 && y0 <= h) { graphics.DrawLine(prime_pen, 0, y0, w, y0); } } else { Pen anti_pen = new Pen(colors.AxisColor, 1); anti_pen.DashStyle = DashStyle.Custom; anti_pen.DashPattern = new float[] { 5, 5 }; double pi = Geometry.StraightAngle(unit); double anti_mer = Geometry.NearestAntimeridian(box.Min[0], -1, unit); double prime_mer = anti_mer + pi; double next_anti_mer = anti_mer + 2 * pi; double next_prime_mer = prime_mer + 2 * pi; float anti_mer_f = cs.ConvertX(anti_mer); float anti_mer_step = cs.ConvertX(next_anti_mer) - anti_mer_f; float prime_mer_f = cs.ConvertX(prime_mer); float prime_mer_step = cs.ConvertX(next_prime_mer) - prime_mer_f; // Antimeridians while (anti_mer_f <= w // NOTE: For bug coordinates anti_mer_step may be 0 which results in infinite loop && Util.Assign(ref anti_mer_f, anti_mer_f + anti_mer_step)) { if (anti_mer_f >= 0) { graphics.DrawLine(anti_pen, anti_mer_f, 0, anti_mer_f, h); } } // Prime meridians bool primeMeridiansDrawn = false; while (prime_mer_f <= w // NOTE: For bug coordinates anti_mer_step may be 0 which results in infinite loop && Util.Assign(ref prime_mer_f, prime_mer_f += prime_mer_step)) { if (prime_mer_f >= 0) { graphics.DrawLine(prime_pen, prime_mer_f, 0, prime_mer_f, h); primeMeridiansDrawn = true; } } // Prime meridian float p = cs.ConvertX(0.0); if (!primeMeridiansDrawn && 0 <= p && p <= w) { graphics.DrawLine(prime_pen, p, 0, p, h); } // Equator float e = cs.ConvertY(0.0); if (0 <= e && e <= h) { graphics.DrawLine(prime_pen, 0, e, w, e); } // North pole float n = cs.ConvertY(pi / 2); if (0 <= n && n <= h) { graphics.DrawLine(anti_pen, 0, n, w, n); } // South pole float s = cs.ConvertY(-pi / 2); if (0 <= s && s <= h) { graphics.DrawLine(anti_pen, 0, s, w, s); } } return(true); }
public static bool IsAntipodal(double distNorm, Geometry.Unit unit) { double pi = Geometry.HalfAngle(unit); return(Math.Abs(Math.Abs(distNorm) - pi) < double.Epsilon * pi); }
private static PointF[] DensifyAndConvert(LocalCS cs, Geometry.Point p0, Geometry.Point p1, double length, Geometry.Unit unit) { double distNorm = Geometry.NormalizedAngleSigned(p1[0] - p0[0], unit); bool intersPole = IsAntipodal(distNorm, unit); double halfPi = Geometry.HalfAngle(unit) / 2; double poleLat = p1[1] - p0[1] >= 0 ? halfPi : -halfPi; int intersPoleIndex = -1; Geometry.Point[] densPoints = Geometry.SphericalDensify(p0, p1, length, unit); PointF[] result = new PointF[densPoints.Length + (intersPole ? 2 : 0)]; int k = 0; for (int j = 0; j < densPoints.Length; ++j, ++k) { double densDistNorm = Geometry.NormalizedAngleSigned(densPoints[j][0] - p0[0], unit); densPoints[j][0] = p0[0] + densDistNorm; if (intersPole && intersPoleIndex == -1 && Math.Abs(densDistNorm) > halfPi) { intersPoleIndex = j; Geometry.Point p = j == 0 ? p0 : densPoints[j - 1]; float poleF = cs.ConvertY(poleLat); result[k++] = new PointF(cs.ConvertX(p[0]), poleF); result[k++] = new PointF(cs.ConvertX(densPoints[j][0]), poleF); } result[k] = cs.Convert(densPoints[j]); } // last segment if (intersPole && intersPoleIndex == -1) { int j = densPoints.Length; intersPoleIndex = j; float poleF = cs.ConvertY(poleLat); result[j] = new PointF(cs.ConvertX(densPoints[j - 1][0]), poleF); result[j + 1] = new PointF(cs.ConvertX(p1[0]), poleF); } return(result); }
public PeriodicDrawableRange(LocalCS cs, Geometry.IRandomAccessRange <Geometry.Point> points, bool closed, Geometry.Unit unit, bool densify) { this.closed = closed; this.containsPole = ContainsPole.No; if (points.Count < 2) { return; } // approx. length of densified segments /*double densLength = Math.Min(cs.InverseConvertDimensionX(20), * cs.InverseConvertDimensionY(20));*/ double densLength = Geometry.FromDegree(5, unit); int count = points.Count + (closed ? 1 : 0); xs_orig = new float[count]; points_rel = new PointF[count]; if (densify) { dens_points_rel = new PointF[points.Count][]; } xs_orig[0] = cs.ConvertX(points[0][0]); points_rel[0] = cs.Convert(points[0]); Geometry.Point p0 = points[0].Clone(); for (int i = 1; i < count; ++i) { Geometry.Point p1 = points[i % points.Count].Clone(); xs_orig[i] = cs.ConvertX(p1[0]); double distNorm = Geometry.NormalizedAngleSigned(p1[0] - p0[0], unit); // [-pi, pi] p1[0] = p0[0] + distNorm; points_rel[i] = cs.Convert(p1); if (dens_points_rel != null) { dens_points_rel[i - 1] = DensifyAndConvert(cs, p0, p1, densLength, unit); } p0 = p1; } if (closed && Math.Abs(points_rel[0].X - points_rel[points.Count].X) > 0.1) { // Check which pole double area = 0; p0 = points[0].Clone(); for (int i = 1; i < count; ++i) { Geometry.Point p1 = points[i % points.Count].Clone(); double distNorm = Geometry.NormalizedAngleSigned(p1[0] - p0[0], unit); // [-pi, pi] p1[0] = p0[0] + distNorm; area += Geometry.SphericalTrapezoidArea(p0, p1, unit); p0 = p1; } int areaSign = Math.Sign(area); int dirSign = Math.Sign(points_rel[points.Count].X - points_rel[0].X); this.containsPole = (areaSign * dirSign >= 0) ? ContainsPole.North : ContainsPole.South; } }
public void DrawPeriodicPoint(LocalCS cs, Geometry.Point point, Geometry.Box box, Geometry.Unit unit, bool drawDots) { PointF p = cs.Convert(point); DrawPoint(p); double pi2 = 2 * Geometry.HalfAngle(unit); Pen pen = drawDots ? this.penDot : this.pen; // draw points on the west double x_tmp = point[0] - pi2; while (x_tmp >= box.Min[0]) { p.X = cs.ConvertX(x_tmp); DrawPoint(p, pen); x_tmp -= pi2; } // draw points on the east x_tmp = point[0] + pi2; while (x_tmp <= box.Max[0]) { p.X = cs.ConvertX(x_tmp); DrawPoint(p, pen); x_tmp += pi2; } }
// ------------------------------------------------- // Util // ------------------------------------------------- private static Geometry.Interval RelativeEnvelopeLon(Geometry.IRandomAccessRange <Geometry.Point> points, bool closed, Geometry.Unit unit) { Geometry.Interval result = null; if (points.Count < 1) { result = new Geometry.Interval(); Geometry.AssignInverse(result); return(result); } double x0 = points[0][0]; result = new Geometry.Interval(x0); int count = points.Count + (closed ? 1 : 0); for (int ii = 1; ii < count; ++ii) { int i = ii % points.Count; double xi = points[i][0]; double distNorm = Geometry.NormalizedAngleSigned(xi - x0, unit); // [-pi, pi] double x1 = x0 + distNorm; result.Expand(x1); x0 = x1; } return(result); }
public void DrawPeriodicPoint(LocalCS cs, Geometry.Point point, Geometry.Box box, Geometry.Unit unit) { PointF p = cs.Convert(point); DrawPoint(p); Pen penDot = (Pen)pen.Clone(); penDot.DashStyle = DashStyle.Dot; double pi2 = 2 * Geometry.HalfAngle(unit); // draw points on the west double x_tmp = point[0] - pi2; while (x_tmp >= box.Min[0]) { p.X = cs.ConvertX(x_tmp); DrawPoint(p, penDot); x_tmp -= pi2; } // draw points on the east x_tmp = point[0] + pi2; while (x_tmp <= box.Max[0]) { p.X = cs.ConvertX(x_tmp); DrawPoint(p, penDot); x_tmp += pi2; } }
public PeriodicDrawableRange(LocalCS cs, Geometry.IRandomAccessRange <Geometry.Point> points, Geometry.Box box, Geometry.Unit unit) { if (points.Count < 2) { return; } double pi = Geometry.HalfAngle(unit); periodf = cs.ConvertDimension(2 * pi); xs_orig = new float[points.Count]; points_rel = new PointF[points.Count]; xs_orig[0] = cs.ConvertX(points[0][0]); points_rel[0] = cs.Convert(points[0]); minf = points_rel[0].X; maxf = points_rel[0].X; double x0 = Geometry.NormalizedAngle(points[0][0], unit); double x0_prev = points[0][0]; for (int i = 1; i < points.Count; ++i) { xs_orig[i] = cs.ConvertX(points[i][0]); double x1 = Geometry.NormalizedAngle(points[i][0], unit); double dist = x1 - x0; // [-2pi, 2pi] double distNorm = Geometry.NormalizedAngle(dist, unit); // [-pi, pi] double x0_curr = x0_prev + distNorm; points_rel[i] = new PointF(cs.ConvertX(x0_curr), cs.ConvertY(points[i][1])); // expand relative box X if (points_rel[i].X < minf) { minf = points_rel[i].X; } if (points_rel[i].X > maxf) { maxf = points_rel[i].X; } x0_prev = x0_curr; x0 = x1; } box_minf = cs.ConvertX(box.Min[0]); box_maxf = cs.ConvertX(box.Max[0]); }
public PeriodicDrawableBox(LocalCS cs, Geometry.IRandomAccessRange <Geometry.Point> points, Geometry.Box box, Geometry.Unit unit) { double pi = Geometry.HalfAngle(unit); periodf = cs.ConvertDimension(2 * pi); xs_orig = new float[points.Count]; points_rel = new PointF[points.Count]; xs_orig[0] = cs.ConvertX(points[0][0]); points_rel[0] = cs.Convert(points[0]); minf = points_rel[0].X; maxf = points_rel[0].X; double x0 = Geometry.NormalizedAngle(points[0][0], unit); for (int i = 1; i < points.Count; ++i) { xs_orig[i] = cs.ConvertX(points[i][0]); double x1 = Geometry.NormalizedAngle(points[i][0], unit); double dist = x1 - x0; // [-2pi, 2pi] double distNorm = Geometry.NormalizedAngle(dist, unit); // [-pi, pi] while (distNorm < 0) { distNorm += 2 * Geometry.HalfAngle(unit); // [0, 2pi] - min is always lesser than max } double x0_curr = points[0][0] + distNorm; // always relative to p0 points_rel[i] = new PointF(cs.ConvertX(x0_curr), cs.ConvertY(points[i][1])); // expand relative box X if (points_rel[i].X < minf) { minf = points_rel[i].X; } if (points_rel[i].X > maxf) { maxf = points_rel[i].X; } } box_minf = cs.ConvertX(box.Min[0]); box_maxf = cs.ConvertX(box.Max[0]); }
public PeriodicDrawableNSphere(LocalCS cs, Geometry.NSphere nsphere, Geometry.Box box, Geometry.Unit unit) { double pi = Geometry.HalfAngle(unit); periodf = cs.ConvertDimension(2 * pi); c_rel = cs.Convert(nsphere.Center); r = cs.ConvertDimension(nsphere.Radius); minf = c_rel.X - r; maxf = c_rel.X + r; box_minf = cs.ConvertX(box.Min[0]); box_maxf = cs.ConvertX(box.Max[0]); }
public static bool DrawAxes(Graphics graphics, Geometry.Box box, Geometry.Unit unit, Colors colors, bool fill) { if (!box.IsValid()) { return(false); } LocalCS cs = new LocalCS(box, graphics, fill); //Geometry.Box viewBox = cs.ViewBox(); // Axes float h = graphics.VisibleClipBounds.Height; float w = graphics.VisibleClipBounds.Width; Pen prime_pen = new Pen(colors.AxisColor, 1); if (unit == Geometry.Unit.None) { // Y axis //if (Geometry.IntersectsX(viewBox, 0.0)) { float x0 = cs.ConvertX(0.0); graphics.DrawLine(prime_pen, x0, 0, x0, h); } // X axis //if (Geometry.IntersectsY(viewBox, 0.0)) { float y0 = cs.ConvertY(0.0); graphics.DrawLine(prime_pen, 0, y0, w, y0); } } else { Pen anti_pen = new Pen(colors.AxisColor, 1); anti_pen.DashStyle = DashStyle.Custom; anti_pen.DashPattern = new float[] { 5, 5 }; double pi = Geometry.HalfAngle(unit); double anti_mer = Geometry.NearestAntimeridian(box.Min[0], -1, unit); double prime_mer = anti_mer + pi; double next_anti_mer = anti_mer + 2 * pi; double next_prime_mer = prime_mer + 2 * pi; float anti_mer_f = cs.ConvertX(anti_mer); float anti_mer_step = cs.ConvertX(next_anti_mer) - anti_mer_f; float prime_mer_f = cs.ConvertX(prime_mer); float prime_mer_step = cs.ConvertX(next_prime_mer) - prime_mer_f; // Antimeridians for (; anti_mer_f <= w; anti_mer_f += anti_mer_step) { if (anti_mer_f >= 0) { graphics.DrawLine(anti_pen, anti_mer_f, 0, anti_mer_f, h); } } // Prime meridians for (; prime_mer_f <= w; prime_mer_f += prime_mer_step) { if (prime_mer_f >= 0) { graphics.DrawLine(prime_pen, prime_mer_f, 0, prime_mer_f, h); } } // Equator float e = cs.ConvertY(0.0); if (0 <= e && e <= h) { graphics.DrawLine(prime_pen, 0, e, w, e); } // North pole float n = cs.ConvertY(pi / 2); if (0 <= n && n <= h) { graphics.DrawLine(anti_pen, 0, n, w, n); } // South pole float s = cs.ConvertY(-pi / 2); if (0 <= s && s <= h) { graphics.DrawLine(anti_pen, 0, s, w, s); } } return(true); }
public void DrawPeriodicPoint(LocalCS cs, Geometry.Point point, Geometry.Box box, Geometry.Unit unit, bool drawDots) { PointF p = cs.Convert(point); DrawPoint(p); double twoPi = Geometry.FullAngle(unit); Pen pen = drawDots ? this.penDot : this.pen; // NOTE: Use AssignChanged becasue for big coordinates subtracting/adding // twoPi doesn't change the value of x_tmp which causes infinite loop float x = Math.Min(Math.Max(p.X, 0.0f), cs.Width); double nPeriodsWest = (point[0] - box.Min[0]) / twoPi; float pixelsWest = x; double nPeriodsEast = (box.Max[0] - point[0]) / twoPi; float pixelsEast = cs.Width - x; if (nPeriodsWest <= pixelsWest / 5) { // draw points on the west double x_tmp = point[0]; while (Util.Assign(ref x_tmp, x_tmp - twoPi) && x_tmp >= box.Min[0]) { p.X = cs.ConvertX(x_tmp); DrawPoint(p, pen); } } if (nPeriodsEast <= pixelsEast / 5) { // draw points on the east double x_tmp = point[0]; while (Util.Assign(ref x_tmp, x_tmp + twoPi) && x_tmp <= box.Max[0]) { p.X = cs.ConvertX(x_tmp); DrawPoint(p, pen); } } }