2

We are currently using the Zoom functionality on the PlotCube that uses the mousewheel to zoom in and out of a 2-D image plot (TwoDMode=true). We also use the zoom obtained through the zoom selection rectangle functionality, again provided by ILNumerics library. The problem is that when we magnify/zoom a 2D image enough using the mouse wheel, white patches start to appear on the image (I think this is something to do with the view clipping pane). This does not happen when we zoom in by a large ammount using the zoom selection rectangle functionality.

Is there a fix for this problem? or do we have to implement the mousewheel zoom ourselves (by catching the mousewheel events and changing the limits accordingly).

Here is some sample code, pop it into a basic application (Windows Forms or WPF). The ILPanel instance should be called iLPanel and dock it to the entire main or parent window contents. Call the method "IlPanelOnLoad()" during the window "loaded" event.

private void IlPanelOnLoad()
{
    ilPanel.Scene = PlotImageTest();
    var pc = ilPanel.Scene.First<ILPlotCube>();
    pc.DataScreenRect = new RectangleF(0.15f, 0.10f, 0.80f, 0.70f);

    ilPanel.Scene.Configure();
    ilPanel.Refresh();
}

private ILScene PlotImageTest() 
{
    var scene = new ILScene();

    // the data to show comes from a predefined 
    // example dataset contained in ILNumerics
    ILArray<float> A = ILMath.tosingle(ILSpecialData.terrain["0:240;0:240"]);
    // we fetch to min and max values for tight limits
    float min, max;
    A.GetLimits(out min, out max);

    // Create the surface
    ILSurface surface = new ILSurface(A);
    surface.Wireframe.Visible = false; // for fast rendering
    surface.Markable = false;

    // scene setup: add a plotcube in 2D mode...
    var plotCube = scene.Add(new ILPlotCube(twoDMode: true) {
        // add a surface to the plot cube
        Children = {
            surface
        },
        // configure the datascreen rect. This makes the plotcube 
        // content fill the whole panel area
        DataScreenRect = new RectangleF(0.13f, 0.13f, 0.74f, 0.74f),
        // configure the plot cube limits to show no margins
        Limits = {
            XMin = 0, YMin = 0, ZMin = min,
            XMax = A.S[1] - 1, YMax = A.S[0] - 1, ZMax = max + 1
        }
    });

    return scene;
}
R. Bovill
  • 31
  • 4

1 Answers1

1

Had to create a fix quickly for our own use, here it is:

    private void IlPanelOnLoad()
    {
        ...

        var plotCube = GetPlotCube();
        if (plotCube != null)
        {
            plotCube.MouseWheel += OnPlotCubeMouseWheelEvent;
        }
    }


    #region MouseWheel Zoom

    const float scaleFactor = 0.05f;  // 5% scaling, Adjust this to get faster/slower scaling
    const float WHEEL_DELTA = 120.0f; // One mouse wheel notch

    void OnPlotCubeMouseWheelEvent(object sender, ILMouseEventArgs mea)
    {
        if (mea.Clicks == 0) // Only when no buttons pressed at the same time
        {
            var plotCube = sender as ILPlotCube;
            if (plotCube != null)
            {
                // + or - a scaleFactor change per wheel mouse notch
                float zoomFactor = 1 - ((float)mea.Delta) / WHEEL_DELTA * scaleFactor;
                ILLimits ilLimits = plotCube.Limits;
                ApplyScaleFactor(zoomFactor, ilLimits);
                ilPanel.Refresh();
            }
        }
        mea.Cancel = true; // Stop mouse wheel event default behaviour
    }

    private void ApplyScaleFactor(float zoomFactor, ILLimits ilLimits)
    {
        // delta here is nothing to do with wheel mouse delta
        float delta = ilLimits.WidthF * zoomFactor / 2f;
        ilLimits.XMin = ilLimits.CenterF.X - delta;
        ilLimits.XMax = ilLimits.CenterF.X + delta;
        delta = ilLimits.HeightF * zoomFactor / 2f;
        ilLimits.YMin = ilLimits.CenterF.Y - delta;
        ilLimits.YMax = ilLimits.CenterF.Y + delta;
    }

    private void ApplyScaleFactorHasWhitePatches(float zoomFactor, ILLimits ilLimits)
    {
        ilLimits.Update(ilLimits.CenterF, zoomFactor);
    }

    #endregion MouseWheel Zoom

We pickup the PlotCube mousewheel event and process it ourselves. To stop the default behaviour we set the mouse event "Cancel" flag. If you use the ILLimits "Update" method to get the scaling you will get the current behaviour, see the "ApplyScaleFactorHasWhitePatches()" method. I think it is caused by the fact that the scaling scales the limits in the Z axis as well. Our solution just scales the limits in the X and Y axes. Perhaps, as a fix within the ILNumerics source code they could check if the 2D flag is set and not scale the Z axis limits if it is.

R. Bovill
  • 31
  • 4