Beispiel #1
0
        // 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);
        }
        private void imageGrid_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            System.Windows.Point point = e.GetPosition(imageGrid);

            m_mouseVLine.X1         = point.X;
            m_mouseVLine.Y1         = 0;
            m_mouseVLine.X2         = point.X;
            m_mouseVLine.Y2         = image.ActualHeight;
            m_mouseVLine.Visibility = Visibility.Visible;
            m_mouseHLine.X1         = 0;
            m_mouseHLine.Y1         = point.Y;
            m_mouseHLine.X2         = image.ActualWidth;
            m_mouseHLine.Y2         = point.Y;
            m_mouseHLine.Visibility = Visibility.Visible;
            if (m_currentBox != null && m_currentBox.IsValid())
            {
                if (m_currentLocalCS == null)
                {
                    m_currentLocalCS = new LocalCS(m_currentBox, (float)image.ActualWidth, (float)image.ActualHeight);
                }
                else
                {
                    m_currentLocalCS.Reset(m_currentBox, (float)image.ActualWidth, (float)image.ActualHeight);
                }
                m_mouseTxt.Text = "(" + Util.ToString(m_currentLocalCS.InverseConvertX(point.X))
                                  + " " + Util.ToString(m_currentLocalCS.InverseConvertY(point.Y))
                                  + ")";
                Canvas.SetLeft(m_mouseTxt, point.X + 2);
                Canvas.SetTop(m_mouseTxt, point.Y + 2);
                m_mouseTxt.Visibility = Visibility.Visible;
            }
            else
            {
                m_mouseTxt.Visibility = Visibility.Hidden;
            }

            if (m_mouseDown)
            {
                if (m_pointDown[0] != point.X || m_pointDown[1] != point.Y)
                {
                    double ox = m_pointDown[0];
                    double oy = m_pointDown[1];
                    double x  = Math.Min(Math.Max(point.X, 0), image.ActualWidth);
                    double y  = Math.Min(Math.Max(point.Y, 0), image.ActualHeight);
                    double w  = Math.Abs(x - ox);
                    double h  = Math.Abs(y - oy);

                    double prop  = h / w;
                    double iProp = image.ActualHeight / image.ActualWidth;
                    if (prop < iProp)
                    {
                        h = iProp * w;
                    }
                    else if (prop > iProp)
                    {
                        w = h / iProp;
                    }

                    double l = ox;
                    double t = oy;

                    if (ox <= x)
                    {
                        if (ox + w > image.ActualWidth)
                        {
                            w = image.ActualWidth - ox;
                            h = iProp * w;
                        }
                    }
                    else
                    {
                        if (ox - w < 0)
                        {
                            w = ox;
                            h = iProp * w;
                        }
                        l = ox - w;
                    }

                    if (oy <= y)
                    {
                        if (oy + h > image.ActualHeight)
                        {
                            h = image.ActualHeight - oy;
                            w = h / iProp;
                        }
                    }
                    else
                    {
                        if (oy - h < 0)
                        {
                            h = oy;
                            w = h / iProp;
                        }
                        t = oy - h;
                    }

                    if (w > 0 && h > 0)
                    {
                        Canvas.SetLeft(m_selectionRect, l);
                        Canvas.SetTop(m_selectionRect, t);
                        m_selectionRect.Width  = w;
                        m_selectionRect.Height = h;

                        m_selectionRect.Visibility = Visibility.Visible;
                    }
                }
            }
        }
        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);
        }
        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);
        }
Beispiel #5
0
        // 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);
        }
Beispiel #6
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);
        }
Beispiel #7
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);
        }
Beispiel #8
0
        private void imageGrid_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            System.Windows.Point point = e.GetPosition(imageGrid);

            m_mouseVLine.X1         = point.X;
            m_mouseVLine.Y1         = 0;
            m_mouseVLine.X2         = point.X;
            m_mouseVLine.Y2         = image.ActualHeight;
            m_mouseVLine.Visibility = Visibility.Visible;
            m_mouseHLine.X1         = 0;
            m_mouseHLine.Y1         = point.Y;
            m_mouseHLine.X2         = image.ActualWidth;
            m_mouseHLine.Y2         = point.Y;
            m_mouseHLine.Visibility = Visibility.Visible;
            if (m_currentBox != null && m_currentBox.IsValid())
            {
                // TODO: pass correct fill parameter later when point plot is implemented
                bool fill = true;
                if (m_currentLocalCS == null)
                {
                    m_currentLocalCS = new LocalCS(m_currentBox, (float)image.ActualWidth, (float)image.ActualHeight, fill);
                }
                else
                {
                    m_currentLocalCS.Reset(m_currentBox, (float)image.ActualWidth, (float)image.ActualHeight, fill);
                }
                m_mouseTxt.Text = "(" + Util.ToString(m_currentLocalCS.InverseConvertX(point.X))
                                  + " " + Util.ToString(m_currentLocalCS.InverseConvertY(point.Y))
                                  + ")";
                Canvas.SetLeft(m_mouseTxt, point.X + 2);
                Canvas.SetTop(m_mouseTxt, point.Y + 2);
                m_mouseTxt.Visibility = Visibility.Visible;
            }
            else
            {
                m_mouseTxt.Visibility = Visibility.Hidden;
            }

            if (m_mouseDown)
            {
                if (m_pointDown[0] != point.X || m_pointDown[1] != point.Y)
                {
                    double originx = m_pointDown[0];
                    double originy = m_pointDown[1];
                    double x       = Math.Min(Math.Max(point.X, 0), image.ActualWidth);
                    double y       = Math.Min(Math.Max(point.Y, 0), image.ActualHeight);
                    double width   = Math.Abs(x - originx);
                    double height  = Math.Abs(y - originy);

                    if (originx > x)
                    {
                        originx -= width;
                    }
                    if (originy > y)
                    {
                        originy -= height;
                    }

                    Canvas.SetLeft(m_selectionRect, originx);
                    m_selectionRect.Width = width;
                    Canvas.SetTop(m_selectionRect, originy);
                    m_selectionRect.Height = height;

                    m_selectionRect.Visibility = Visibility.Visible;
                }
            }
        }