Exemplo n.º 1
0
            void DrawLines(Geometry.Box box, Graphics graphics, Settings settings, Geometry.Traits traits, double diffX)
            {
                // NOTE: traits == null
                bool fill = true;

                LocalCS cs = new LocalCS(box, graphics, fill);

                //float dx = cs.ConvertDimensionX(diffX);
                //float s = Math.Min(Math.Max(dx, 1.0f), 2.0f);

                Drawer drawer = new Drawer(graphics, settings.color);

                if (points.Count == 1)
                {
                    float x = cs.ConvertX(points[0][0]);
                    float y = cs.ConvertY(points[0][1]);
                    drawer.DrawLine(x, y - 0.5f, x, y + 0.5f);
                }
                else if (points.Count > 1)
                {
                    float xp = cs.ConvertX(points[0][0]);
                    float yp = cs.ConvertY(points[0][1]);
                    for (int i = 1; i < points.Count; ++i)
                    {
                        float x = cs.ConvertX(points[i][0]);
                        float y = cs.ConvertY(points[i][1]);
                        drawer.DrawLine(xp, yp, x, y);
                        xp = x;
                        yp = y;
                    }
                }
            }
Exemplo n.º 2
0
            void DrawBars(Geometry.Box box, Graphics graphics, Settings settings, Geometry.Traits traits)
            {
                // NOTE: traits == null
                bool fill = true;

                LocalCS cs = new LocalCS(box, graphics, fill);

                float y0        = cs.ConvertY(0);
                float x0        = cs.ConvertX(0);
                float x1        = cs.ConvertX(1);
                float dx        = Math.Abs(x1 - x0);
                bool  drawLines = dx < 4;

                double i = 0;

                if (drawLines)
                {
                    float penWidth = dx < 2 ? 1 : 2;
                    Pen   pen      = new Pen(settings.color, penWidth);
                    foreach (double v in values)
                    {
                        float x = cs.ConvertX(i);
                        float y = cs.ConvertY(v);
                        graphics.DrawLine(pen, x, y0, x, y);
                        i += 1;
                    }
                }
                else
                {
                    Drawer drawer = new Drawer(graphics, settings.color);
                    foreach (double v in values)
                    {
                        float x  = cs.ConvertX(i);
                        float y  = cs.ConvertY(v);
                        float t  = Math.Min(y0, y);
                        float h  = Math.Abs(y - y0);
                        float xl = dx / 3.0f;
                        float xw = dx * 2.0f / 3.0f;
                        if (h >= 2)
                        {
                            drawer.DrawRectangle(x - xl, t, xw, h);
                            drawer.FillRectangle(x - xl, t, xw, h);
                        }
                        else
                        {
                            drawer.DrawLine(x - xl, t, x + xl, t);
                        }
                        i += 1;
                    }
                }
            }
Exemplo n.º 3
0
            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];
            }
Exemplo n.º 4
0
            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);
            }
Exemplo n.º 5
0
            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]);
            }
Exemplo n.º 6
0
            void DrawLines(Geometry.Box box, Graphics graphics, Settings settings, Geometry.Traits traits)
            {
                // NOTE: traits == null
                bool fill = true;

                LocalCS cs = new LocalCS(box, graphics, fill);

                //float x0 = cs.ConvertX(0);
                //float x1 = cs.ConvertX(1);
                //float dx = Math.Abs(x1 - x0);
                //float s = Math.Min(Math.Max(dx, 1.0f), 2.0f);

                Drawer drawer = new Drawer(graphics, settings.color);

                if (values.Count == 1)
                {
                    float x = cs.ConvertX(0);
                    float y = cs.ConvertY(values[0]);
                    drawer.DrawLine(x, y - 0.5f, x, y + 0.5f);
                }
                else if (values.Count > 1)
                {
                    double d  = 0;
                    float  xp = cs.ConvertX(d);
                    float  yp = cs.ConvertY(values[0]);
                    d += 1;
                    for (int i = 1; i < values.Count; ++i)
                    {
                        float x = cs.ConvertX(d);
                        float y = cs.ConvertY(values[i]);
                        drawer.DrawLine(xp, yp, x, y);
                        d += 1;
                        xp = x;
                        yp = y;
                    }
                }
            }
Exemplo n.º 7
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]);
            }
Exemplo n.º 8
0
            void DrawPoints(Geometry.Box box, Graphics graphics, Settings settings, Geometry.Traits traits, double diffX)
            {
                // NOTE: traits == null
                bool fill = true;

                LocalCS cs = new LocalCS(box, graphics, fill);

                float dx      = cs.ConvertDimensionX(diffX);
                float s       = Math.Min(Math.Max(dx * 2.0f, 2.0f), 5.0f);
                bool  drawPts = dx < 1;

                Drawer drawer = new Drawer(graphics, settings.color);

                for (int i = 0; i < points.Count; ++i)
                {
                    float x = cs.ConvertX(points[i][0]);
                    float y = cs.ConvertY(points[i][1]);
                    drawer.DrawPoint(x, y, s);
                }
            }
Exemplo n.º 9
0
            void DrawPoints(Geometry.Box box, Graphics graphics, Settings settings, Geometry.Traits traits)
            {
                // NOTE: traits == null
                bool fill = true;

                LocalCS cs = new LocalCS(box, graphics, fill);

                float x0 = cs.ConvertX(0);
                float x1 = cs.ConvertX(1);
                float dx = Math.Abs(x1 - x0);
                float s  = Math.Min(Math.Max(dx * 2.0f, 2.0f), 5.0f);

                double i      = 0;
                Drawer drawer = new Drawer(graphics, settings.color);

                foreach (double v in values)
                {
                    float x = cs.ConvertX(i);
                    float y = cs.ConvertY(v);
                    drawer.DrawPoint(x, y, s);
                    i += 1;
                }
            }
Exemplo n.º 10
0
        public static bool DrawScales(Graphics graphics, Geometry.Box box, Colors colors, bool fill)
        {
            if (!box.IsValid())
            {
                return(false);
            }

            LocalCS cs = new LocalCS(box, graphics, fill);

            // Aabb
            float min_x = cs.ConvertX(box.Min[0]);
            float min_y = cs.ConvertY(box.Min[1]);
            float max_x = cs.ConvertX(box.Max[0]);
            float max_y = cs.ConvertY(box.Max[1]);

            // pen for lines
            Pen   penAabb   = new Pen(colors.AabbColor, 1);
            float maxHeight = 20.0f;
            // font and brush for text
            Font       font      = new Font(new FontFamily(System.Drawing.Text.GenericFontFamilies.SansSerif), maxHeight / 2.0f);
            SolidBrush brushText = new SolidBrush(colors.TextColor);

            // Scales
            {
                float wWidth  = graphics.VisibleClipBounds.Width;
                float wHeight = graphics.VisibleClipBounds.Height;
                // In CS coordinates
                double mi_x   = cs.InverseConvertX(0);
                double mi_y   = cs.InverseConvertY(wHeight);
                double ma_x   = cs.InverseConvertX(wWidth);
                double ma_y   = cs.InverseConvertY(0);
                double mima_x = ma_x - mi_x;
                double mima_y = ma_y - mi_y;
                // Esstimate numbers of strings for both axes
                double esst_x   = Math.Abs(mima_x) < 10 ? mima_x / 10 : mima_x;
                float  wStrNumX = wWidth / StringWidth(graphics, font, esst_x) / 1.25f;
                float  wStrNumH = wHeight / StringWidth(graphics, font, 1.0) / 2.0f;
                // Find closest power of 10 lesser than the width and height
                double pd_x = AbsOuterPow10(mima_x / wStrNumX);
                double pd_y = AbsOuterPow10(mima_y / wStrNumH);
                // Find starting x and y values being the first lesser whole
                // values of the same magnitude, per axis
                double x = ScaleStart(mi_x, pd_x);
                double y = ScaleStart(mi_y, pd_y);
                // Make sure the scale starts outside the view
                if (x > mi_x)
                {
                    x -= pd_x;
                }
                if (y > mi_y)
                {
                    y -= pd_y;
                }
                // Create the string output pattern, e.g. 0.00 for previously calculated step
                string xStrFormat  = StringFormat(pd_x);
                string yStrFormat  = StringFormat(pd_y);
                float  wd_x        = cs.ConvertDimensionX(pd_x);
                int    smallScaleX = SmallScaleSegments(wd_x, 10);
                float  wd_x_step   = wd_x / smallScaleX;
                float  wd_x_limit  = wd_x - wd_x_step / 2;
                float  wd_y        = cs.ConvertDimensionY(pd_y);
                int    smallScaleY = SmallScaleSegments(wd_y, 10);
                float  wd_y_step   = wd_y / smallScaleY;
                float  wd_y_limit  = wd_y - wd_y_step / 2;
                // Draw horizontal scale
                double limit_x = ma_x + pd_x * 1.001;
                for (; x < limit_x; x += pd_x)
                {
                    float wx = cs.ConvertX(x);
                    // scale
                    graphics.DrawLine(penAabb, wx, wHeight, wx, wHeight - 5);
                    // value
                    string xStr     = Util.ToString(x, xStrFormat);
                    SizeF  xStrSize = graphics.MeasureString(xStr, font);
                    float  xStrLeft = wx - xStrSize.Width / 2;
                    float  xStrTop  = wHeight - 5 - xStrSize.Height;
                    graphics.DrawString(xStr, font, brushText, xStrLeft, xStrTop);
                    // small scale
                    for (float wsx = wx + wd_x_step; wsx < wx + wd_x_limit; wsx += wd_x_step)
                    {
                        graphics.DrawLine(penAabb, wsx, wHeight, wsx, wHeight - 3);
                    }
                }
                // Draw vertical scale
                double limit_y = ma_y + pd_y * 1.001;
                for (; y < limit_y; y += pd_y)
                {
                    float wy = cs.ConvertY(y);
                    // scale
                    graphics.DrawLine(penAabb, wWidth, wy, wWidth - 5, wy);
                    // value
                    string yStr     = Util.ToString(y, yStrFormat);
                    SizeF  yStrSize = graphics.MeasureString(yStr, font);
                    float  yStrLeft = wWidth - 5 - yStrSize.Width;
                    float  yStrTop  = wy - yStrSize.Height / 2;
                    graphics.DrawString(yStr, font, brushText, yStrLeft, yStrTop);
                    // small scale
                    for (float wsy = wy - wd_y_step; wsy > wy - wd_y_limit; wsy -= wd_y_step)
                    {
                        graphics.DrawLine(penAabb, wWidth, wsy, wWidth - 3, wsy);
                    }
                }
            }

            return(true);
        }
Exemplo n.º 11
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);
        }
Exemplo n.º 12
0
            public void Draw(Geometry.Box box, Graphics graphics, Settings settings, Geometry.Traits traits)
            {
                LocalCS cs     = new LocalCS(box, graphics);
                Drawer  drawer = new Drawer(graphics, settings.color);

                double width  = Dim(0);
                double height = Dim(1);
                float  rw     = cs.ConvertDimensionX(Math.Abs(width));
                float  rh     = cs.ConvertDimensionY(Math.Abs(height));

                if (traits.Unit == Geometry.Unit.None)
                {
                    float rx = cs.ConvertX(Math.Min(Min[0], Max[0]));
                    float ry = cs.ConvertY(Math.Max(Min[1], Max[1]));

                    if (rw == 0 && rh == 0)
                    {
                        drawer.DrawPoint(rx, ry);
                    }
                    else if (rw == 0 || rh == 0)
                    {
                        drawer.DrawLine(rx, ry, rx + rw, ry + rh);
                    }
                    else
                    {
                        drawer.DrawRectangle(rx, ry, rw, rh);

                        bool isInvalid = width < 0 || height < 0;
                        if (!isInvalid)
                        {
                            drawer.FillRectangle(rx, ry, rw, rh);
                        }
                        else
                        {
                            drawer.DrawLine(rx, ry, rx + rw, ry + rh);
                            drawer.DrawLine(rx + rw, ry, rx, ry + rh);
                        }
                    }
                }
                else // Radian, Degree
                {
                    if (rw == 0 && rh == 0)
                    {
                        drawer.DrawPeriodicPoint(cs, Min, box, traits.Unit, settings.showDots);
                    }
                    else if (rw == 0 || rh == 0)
                    {
                        Geometry.Segment           seg      = new Geometry.Segment(Min, Max);
                        Drawer.PeriodicDrawableBox pd       = new Drawer.PeriodicDrawableBox(cs, seg, traits.Unit);
                        Geometry.Interval          interval = RelativeEnvelopeLon(seg, false, traits.Unit);
                        drawer.DrawPeriodic(cs, box, interval, traits.Unit, pd, false, false, settings.showDots);
                    }
                    else
                    {
                        Geometry.Ring ring = new Geometry.Ring();
                        ring.Add(new Geometry.Point(Min[0], Min[1]));
                        ring.Add(new Geometry.Point(Max[0], Min[1]));
                        ring.Add(new Geometry.Point(Max[0], Max[1]));
                        ring.Add(new Geometry.Point(Min[0], Max[1]));
                        Drawer.PeriodicDrawableBox pd       = new Drawer.PeriodicDrawableBox(cs, ring, traits.Unit);
                        Geometry.Interval          interval = RelativeEnvelopeLon(ring, true, traits.Unit);
                        drawer.DrawPeriodic(cs, box, interval, traits.Unit, pd, true, false, settings.showDots);
                    }
                }
            }
Exemplo n.º 13
0
        public static bool DrawAabb(Graphics graphics, Geometry.Box box, Geometry.Traits traits, Colors colors)
        {
            if (!box.IsValid())
            {
                return(false);
            }

            LocalCS cs = new LocalCS(box, graphics);

            // Axes
            float h         = graphics.VisibleClipBounds.Height;
            float w         = graphics.VisibleClipBounds.Width;
            Pen   prime_pen = new Pen(colors.AxisColor, 1);

            if (traits.Unit == Geometry.Unit.None)
            {
                // Y axis
                float x0 = cs.ConvertX(0.0);
                graphics.DrawLine(prime_pen, x0, 0, x0, h);
                // X axis
                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(traits.Unit);
                double anti_mer       = Geometry.NearestAntimeridian(box.Min[0], -1, traits.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);
                }
            }

            // Aabb
            float min_x = cs.ConvertX(box.Min[0]);
            float min_y = cs.ConvertY(box.Min[1]);
            float max_x = cs.ConvertX(box.Max[0]);
            float max_y = cs.ConvertY(box.Max[1]);

            Pen penAabb = new Pen(colors.AabbColor, 1);

            graphics.DrawLine(penAabb, min_x - 1, min_y, min_x + 5, min_y);
            graphics.DrawLine(penAabb, min_x, min_y - 5, min_x, min_y + 1);
            graphics.DrawLine(penAabb, max_x - 5, max_y, max_x + 1, max_y);
            graphics.DrawLine(penAabb, max_x, max_y - 1, max_x, max_y + 5);

            // Aabb's coordinates
            float maxHeight = 20.0f;// Math.Min(Math.Max(graphics.VisibleClipBounds.Height - min_y, 0.0f), 20.0f);

            if (maxHeight > 1)
            {
                string       min_x_str  = box.Min[0].ToString("0.00", System.Globalization.CultureInfo.InvariantCulture);
                string       min_y_str  = box.Min[1].ToString("0.00", System.Globalization.CultureInfo.InvariantCulture);
                string       max_x_str  = box.Max[0].ToString("0.00", System.Globalization.CultureInfo.InvariantCulture);
                string       max_y_str  = box.Max[1].ToString("0.00", System.Globalization.CultureInfo.InvariantCulture);
                Font         font       = new Font(new FontFamily(System.Drawing.Text.GenericFontFamilies.SansSerif), maxHeight / 2.0f);
                StringFormat drawFormat = new StringFormat();
                drawFormat.Alignment = StringAlignment.Center;
                string     minStr      = "(" + min_x_str + " " + min_y_str + ")";
                string     maxStr      = "(" + max_x_str + " " + max_y_str + ")";
                SizeF      minSize     = graphics.MeasureString(minStr, font);
                SizeF      maxSize     = graphics.MeasureString(maxStr, font);
                RectangleF drawRectMin = new RectangleF(Math.Max(min_x - minSize.Width, 0.0f),
                                                        Math.Min(min_y + 2, graphics.VisibleClipBounds.Height - maxSize.Height),
                                                        minSize.Width,
                                                        minSize.Height);
                RectangleF drawRectMax = new RectangleF(Math.Min(max_x, graphics.VisibleClipBounds.Width - maxSize.Width),
                                                        Math.Max(max_y - maxHeight, 0.0f),
                                                        maxSize.Width,
                                                        maxSize.Height);
                SolidBrush brushText = new SolidBrush(colors.TextColor);
                graphics.DrawString(minStr, font, brushText, drawRectMin, drawFormat);
                graphics.DrawString(maxStr, font, brushText, drawRectMax, drawFormat);
            }

            return(true);
        }
Exemplo n.º 14
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);

            // 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);
        }