public GridRemovalSettingsDialog(NuGenDocument doc)
        {
            this.settings = doc.GridRemovalSettings;
            this.originalImage = doc.OriginalImage;
            this.discretizeSettings = doc.DiscretizeSettings;
            this.transform = doc.Transform;
            this.bgColor = doc.BackgroundColor;
            this.coordSettings = doc.CoordSettings;

            if (doc.ValidAxes)
                this.gridRemovalMesh = doc.GridDisplaySettings;
            else
                this.gridRemovalMesh.initialized = false;

            discretizeSettings.discretizeMethod = DiscretizeMethod.DiscretizeForeground;

            InitializeComponent();
            InitializeDefaults();

            if (!(doc.ValidAxes || doc.ValidScale))
            {
                textBox1.Enabled = false;
                textBox2.Enabled = false;
                checkBox2.Enabled = false;
                checkBox2.Checked = false;
                checkBox3.Enabled = false;
                checkBox3.Checked = false;
            }

            histogram.ValueChanged = this.ValueChanged;

            ValueChanged(true);

            this.MaximumSize = Size;
        }
Exemple #2
0
        //Removes pixels around user defined gridlines
        private void RemoveGridlines(PixelState[,] pixels, NuGenScreenTranslate transform,
                                     CoordSettings coordSettings, GridRemovalSettings gridRemovalSettings, PixelState pxState)
        {
            if (transform.ValidAxes)
            {
                List <GridlineScreen> gridlines;
                gridlines = NuGenGridMesh.MakeGridLines(transform, coordSettings, gridRemovalSettings.gridMesh);

                foreach (GridlineScreen gridline in gridlines)
                {
                    int xStart = gridline.Start.X;
                    int yStart = gridline.Start.Y;
                    int xStop  = gridline.Stop.X;
                    int yStop  = gridline.Stop.Y;

                    if (Math.Abs(xStop - xStart) < Math.Abs(yStop - yStart))
                    {
                        //Vertical lines
                        RemoveGridlineVertical(pixels, xStart, yStart, xStop, yStop, gridRemovalSettings, pxState);
                    }
                    else
                    {
                        //Horizontal lines
                        RemoveGridlineHorizontal(pixels, xStart, yStart, xStop, yStop, gridRemovalSettings, pxState);
                    }
                }
            }
        }
Exemple #3
0
        //Constructs the document and places it in the provided state
        public NuGenDocument(DigitizeState state)
        {
            listeners = new List <NuGenImageListener>();

            pointSets     = new NuGenPointSetCollection();
            segments      = new NuGenSegmentCollection();
            transform     = new NuGenScreenTranslate(this);
            gridDisplay   = new List <GridlineScreen>();
            digitizeState = state;
            matchSet      = new NuGenMatchSet(pointMatchSettings);

            //load all of the settings
            NuGenDefaultSettings rSettings = NuGenDefaultSettings.GetInstance();

            coordSettings      = rSettings.CoordSettings;
            exportSettings     = rSettings.ExportSettings;
            segmentSettings    = rSettings.SegmentSettings;
            pointMatchSettings = rSettings.PointMatchSettings;

            gridRemovalSettings             = rSettings.GridRemovalSettings;
            gridDisplaySettings.initialized = false;
            gridDisplaySettings.gridSetX    = rSettings.GridDisplayGridSetX;
            gridDisplaySettings.gridSetY    = rSettings.GridDisplayGridSetY;

            discretizeSettings  = rSettings.DiscretizeSettings;
            backgroundSelection = rSettings.BackgroundSelection;
        }
        //Converts a graph Coordinate to screen coordinate
        public void XThetaYRToScreen(CoordSettings coordSettings, double xTheta, double yR, out int xScreen, out int yScreen)
        {
            double xScreenD, yScreenD;
            XThetaYRToScreen(coordSettings, xTheta, yR, out xScreenD, out yScreenD);

            xScreen = (int)(xScreenD + 0.5);
            yScreen = (int)(yScreenD + 0.5);
        }
        //Converts a graph Coordinate to screen coordinate
        public void XThetaYRToScreen(CoordSettings coordSettings, double xTheta, double yR, out int xScreen, out int yScreen)
        {
            double xScreenD, yScreenD;

            XThetaYRToScreen(coordSettings, xTheta, yR, out xScreenD, out yScreenD);

            xScreen = (int)(xScreenD + 0.5);
            yScreen = (int)(yScreenD + 0.5);
        }
Exemple #6
0
        // return bounds on the coordinates for just axis, or all, pointsets, and true if
        // there were any coordinates
        public bool AxisSetGraphLimits(CoordSettings coord, NuGenScreenTranslate transform,
                                       ref double xThetaMin, ref double xThetaMax,
                                       ref double yRMin, ref double yRMax)
        {
            UpdateGraphCoordinates(coord, transform);

            // get limits
            return(axesPointSet.PointSetGraphLimits(ref xThetaMin, ref xThetaMax, ref yRMin, ref yRMax));
        }
        public GridSettingsDialog(GridMeshSettings settings, CoordSettings coordSettings)
        {            
            this.settings = settings;
            this.coordSettings = coordSettings;

            InitializeComponent();
            InitializeDefaults();

            this.MaximumSize = Size;
        }
Exemple #8
0
        public CoordinatesDialog(CoordSettings origSettings)
        {
            this.origSettings = origSettings;

            InitializeComponent();

            InitializeDefaults();

            this.MaximumSize = Size;
        }
Exemple #9
0
        public GridSettingsDialog(GridMeshSettings settings, CoordSettings coordSettings)
        {
            this.settings      = settings;
            this.coordSettings = coordSettings;

            InitializeComponent();
            InitializeDefaults();

            this.MaximumSize = Size;
        }
        public CoordinatesDialog(CoordSettings origSettings)
        {
            this.origSettings = origSettings;

            InitializeComponent();

            InitializeDefaults();

            this.MaximumSize = Size;
        }
        //Computes the ax ay bx by values needed in logarithmic to linear conversions
        public int ComputeLogToFromLinear(CoordSettings coordSettings, double[][] r_graph)
        {
            int retVal = ComputeLogToFromLinear(coordSettings.xThetaScale, r_graph[0], out aX, out bX);

            if (retVal != NuGenMath.SUCCESS)
            {
                return(retVal);
            }

            return(ComputeLogToFromLinear(coordSettings.yRScale, r_graph[1], out aY, out bY));
        }
Exemple #12
0
        private void InitializeThin(CoordSettings coordSettings, NuGenScreenTranslate transform, double thinThickness)
        {
            transform.XBasisScreen(coordSettings, out xBasisXS, out xBasisYS);
            transform.YBasisScreen(coordSettings, out yBasisXS, out yBasisYS);

            // initialize search patterns
            InitializeThinSearch(thinThickness, xBasisXS, yBasisXS, searchPatternPlusX);
            InitializeThinSearch(thinThickness, xBasisYS, yBasisYS, searchPatternPlusY);
            InitializeThinSearch(thinThickness, -xBasisXS, yBasisXS, searchPatternMinusX);
            InitializeThinSearch(thinThickness, xBasisYS, -yBasisYS, searchPatternMinusY);
        }
 //Converts a pair of log coordinates to linear scale
 private void LogToLinear(CoordSettings coordSettings, ref double xTheta, ref double yR)
 {
     if (coordSettings.xThetaScale == Scale.Log)
     {
         xTheta = aX * Math.Exp(bX * xTheta);
     }
     if (coordSettings.yRScale == Scale.Log)
     {
         yR = aY * Math.Exp(bY * yR);
     }
 }
Exemple #14
0
        // apply the transformation to set graph coordinates of the points in the curve and measure pointsets
        public void UpdateGraphCoordinates(CoordSettings coord, NuGenScreenTranslate transform)
        {
            foreach (NuGenPoint point in points)
            {
                double xTheta, yR;
                transform.ScreenToXThetaYR(coord, point.XScreen, point.YScreen, out xTheta, out yR);

                point.XThetaGraph = xTheta;
                point.YRGraph     = yR;
            }
        }
Exemple #15
0
        // for curve pointsets connected as Single Valued Functions, since the graph coordinates
        // of all points are updated, we must reconnect any points that were reordered. remember,
        // a single valued function has only a single value per xTheta value, so the lines cannot overlap
        public void ForceSingleValued(CoordSettings coord, NuGenScreenTranslate transform)
        {
            // quick exit if pointset is a closed contour, which is the case for all axis, scale and
            // measure pointsets. curve pointsets may be either single valued functions, or closed contours
            if (style.lineConnectAs != LineConnectAs.SingleValuedFunction)
            {
                return;
            }

            // quick exit if points are already in order
            if (SingleValued(coord, transform))
            {
                return;
            }

            Comparison <NuGenPoint> comparison = new Comparison <NuGenPoint>(this.XThetaSort);

            // sort the points by xTheta
            points.Sort(comparison);

            // to prevent having to remove N lines and then immediately adding N lines, we only
            // adjust as many lines as necessary
            NuGenPoint pOld   = points[points.Count - 1];
            NuGenPoint pOlder = null;

            foreach (NuGenPoint pNew in points)
            {
                if (pOlder != null)
                {
                    if ((pOlder.NextLine != pNew.PreviousLine) || (pNew.PreviousLine == null))
                    {
                        if (pOlder.NextLine == null)
                        {
                            pOlder.NextLine = pOld.NextLine;
                            pOld.NextLine   = null;
                        }

                        pOlder.NextLine.start.X = pOlder.XScreen;
                        pOlder.NextLine.start.Y = pOlder.YScreen;
                        pOlder.NextLine.end.X   = pNew.XScreen;
                        pOlder.NextLine.end.Y   = pNew.YScreen;

                        pNew.PreviousLine = pOlder.NextLine;
                    }
                }
                else
                {
                    pNew.PreviousLine = null;
                }

                pOlder = pNew;
            }
        }
 private void AdjustMidValuedLogCoords(CoordSettings coordSettings, double[][] r_graph)
 {
     // this function does nothing for linear coordinates. for log coordinates, this
     // function adjusts the middle coordinate since compute_screen_to_graph assumes
     // the coordinates are linear. if the middle log coordinate does not equal the
     // min or max log coordinates, an undesired skew will appear. if two of the axis
     // points share the same log coordinate, the skew will not appear.
     //
     // the only function called after this function that accesses the middle log coordinate
     // will be compute_screen_to_graph
     AdjustMidValuedLogCoord(coordSettings.xThetaScale, ref r_graph[0][0], ref r_graph[0][1], ref r_graph[0][2]);
     AdjustMidValuedLogCoord(coordSettings.yRScale, ref r_graph[1][0], ref r_graph[1][1], ref r_graph[1][2]);
 }
        public void YBasisScreen(CoordSettings coordSettings, out double xScreen, out double yScreen)
        {
            // return basis vector in x direction. do not look at screen increment
            // resulting from graph increment of (0,0) to (1,0), since log scale may
            // be in effect which would crash with a zero
            double xBeforeS, yBeforeS;
            double xAfterS, yAfterS;

            XThetaYRToScreen(coordSettings, 1.0, 1.0, out xBeforeS, out yBeforeS);
            XThetaYRToScreen(coordSettings, 1.0, 10.0, out xAfterS, out yAfterS);
            xScreen = xAfterS - xBeforeS;
            yScreen = yAfterS - yBeforeS;
        }
        private static List<GridlineScreen> MakeGridR(NuGenScreenTranslate transform, CoordSettings coordSettings, GridMeshSettings gridMeshSettings)
        {
            int i;
            int xStartS = 0, yStartS = 0, xStopS = 1, yStopS = 1;
            double rG = gridMeshSettings.startY;
            GridlineScreen gridline;
            List<GridlineScreen> gridlines = new List<GridlineScreen>();
            for (i = 0; i < gridMeshSettings.countY; i++)
            {
                gridline = new GridlineScreen();
                // for polar coordinates we simply piecewise define the elliptical arc until motivated
                // to implement a better drawing algorithm. segments will be evenly spaced in angle
                // some pdf documents describing alternative algorithms are found in the doc directory.
                // it would have been elegant to use QCanvasEllipses but those are axis-aligned.
                double delta = AngleSpacing(coordSettings.thetaUnits);
                bool first = true;
                for (double angle = gridMeshSettings.startX; angle < gridMeshSettings.stopX; angle += delta)
                {
                    transform.XThetaYRToScreen(coordSettings, angle, rG, out xStopS, out yStopS);

                    if (first)
                    {
                        xStartS = xStopS;
                        yStartS = yStopS;
                    }
                    else
                    {
                        if (NuGenMath.VectorMagnitude(xStopS - xStartS, yStopS - yStartS, 0.0) >= pixelSpacing)
                        {
                            gridline.Start.X = xStartS;
                            gridline.Start.Y = yStartS;
                            gridline.Stop.X = xStopS;
                            gridline.Stop.Y = yStopS;
                            gridline.R = true;

                            xStartS = xStopS;
                            yStartS = yStopS;
                        }
                    }

                    first = false;
                }

                if (coordSettings.yRScale == Scale.Linear)
                    rG += gridMeshSettings.stepY;
                else
                    rG *= gridMeshSettings.stepY;
            }

            return gridlines;
        }
Exemple #19
0
        //Removes thin lines which are parallel to the user defined axes
        private void RemoveThinLines(PixelState[,] pixels, CoordSettings coordSettings, NuGenScreenTranslate transform,
                                     double thinThickness, PixelState pixelStateRemovedPass1, PixelState pixelStateRemovedPass2)
        {
            if (transform.ValidAxes)
            {
                InitializeThin(coordSettings, transform, thinThickness);

                // first pass erases the gridMeshSettings lines, except for the junctions
                EraseThinPixels(pixels, thinThickness, pixelStateRemovedPass1);

                // second pass erases the gridMeshSettings line junctions, which are little islands of on-pixels
                EraseThinPixels(pixels, thinThickness, pixelStateRemovedPass2);
            }
        }
Exemple #20
0
        // apply the transformation to set graph coordinates of the points in the curves and
        // measures. if the operation could cause points to be reordered to keep a curve
        // single-valued then the optional update list should be used
        public void UpdateGraphCoordinates(CoordSettings coord, NuGenScreenTranslate transform)
        {
            // apply transformation
            foreach (NuGenPointSet pointSet in curveList)
            {
                pointSet.UpdateGraphCoordinates(coord, transform);
                pointSet.ForceSingleValued(coord, transform);
            }

            foreach (NuGenPointSet pointSet in measureList)
            {
                pointSet.UpdateGraphCoordinates(coord, transform);
            }
        }
Exemple #21
0
        public ExportSettingsDialog(ExportSettings settings, NuGenDocument doc, List <string> includedCurves, List <string> excludedCurves)
        {
            this.settings       = settings;
            this.includedCurves = includedCurves;
            this.excludedCurves = excludedCurves;
            this.pointsets      = doc.PointSets;

            this.coordSettings = doc.CoordSettings;
            this.gridSettings  = doc.GridDisplaySettings;

            InitializeComponent();
            InitializeDefaults();

            this.MaximumSize = Size;
        }
        public ExportSettingsDialog(ExportSettings settings, NuGenDocument doc, List<string> includedCurves, List<string> excludedCurves)
        {
            this.settings = settings;
            this.includedCurves = includedCurves;
            this.excludedCurves = excludedCurves;
            this.pointsets = doc.PointSets;

            this.coordSettings = doc.CoordSettings;
            this.gridSettings = doc.GridDisplaySettings;

            InitializeComponent();
            InitializeDefaults();

            this.MaximumSize = Size;
        }
Exemple #23
0
        // export the curves into a text stream
        public void ExportToFile(Stream str, CoordSettings coord, GridMeshSettings grid,
                                 ExportSettings xport)
        {
            int xPrecision, yPrecision;

            SelectXYPrecisionsForExport(coord, out xPrecision, out yPrecision);

            if (xport.layout == ExportLayout.AllCurvesOnEachLine)
            {
                ExportToStreamAllCurvesTogether(str, coord, grid, xport, xPrecision, yPrecision);
            }
            else
            {
                ExportToStreamEachCurveSeparately(str, coord, grid, xport, xPrecision, yPrecision);
            }
        }
Exemple #24
0
        /*
         * All the following methods work in a similar way.
         *
         * The GUI/Dialogs directory contains all dialogs which take a settings
         * object and stores it.  The user manipulates GUI widgets which update
         * these settings in the dialog's state.  On the condition that the user
         * presses the OK the settings from the dialog are stored into the active
         * document's setting.  Settings are persisted between saved documents,
         * the serialization of documents saves their settings as well as the point
         * data.
         *
         */

        public void Coordinates_Click(object sender, System.EventArgs args)
        {
            CoordinatesDialog dlg = new CoordinatesDialog(ActiveDocument.CoordSettings);

            if (dlg.ShowDialog() == DialogResult.OK)
            {
                CoordSettings newSettings = ActiveDocument.CoordSettings;

                newSettings.frame       = dlg.Frame;
                newSettings.thetaUnits  = dlg.Units;
                newSettings.xThetaScale = dlg.XThetaScale;
                newSettings.yRScale     = dlg.YRScale;

                ActiveDocument.CoordSettings = newSettings;
            }
        }
Exemple #25
0
        //Exports all of the curve data to the given stream with each curve having its own line
        private void ExportToStreamEachCurveSeparately(Stream str, CoordSettings coord, GridMeshSettings grid,
                                                       ExportSettings xport, int xPrecision, int yPrecision)
        {
            // list of x values in ascending order
            List <double> xUsed = AscendingXValuesList(coord, grid, xport, xPrecision);

            StreamWriter writer = new StreamWriter(str);

            foreach (NuGenPointSet pointset in curveList)
            {
                if (pointset.Export)
                {
                    if (xport.header != ExportHeader.HeaderNone)
                    {
                        writer.Write(ExportHeaderPrefix(coord, xport));
                        writer.Write(xport.GetDelimiter());
                        writer.Write(pointset.ExportCurveHeader(xport));
                        writer.Write("\n");
                    }

                    if (xport.pointsSelection == ExportPointsSelection.XYFromAllCurves)
                    {
                        writer.Write(pointset.ExportCurveAll(xport, xPrecision, yPrecision));
                    }
                    else
                    {
                        bool useInterpolation = true;

                        foreach (double itrX in xUsed)
                        {
                            writer.Write(Math.Round(itrX, xPrecision));
                            writer.Write(xport.GetDelimiter());
                            writer.Write(pointset.ExportCurvePoint(itrX, coord, useInterpolation, yPrecision));
                            writer.Write("\n");
                        }

                        if (xport.header == ExportHeader.HeaderGnuplot)
                        {
                            writer.Write("\n\n");
                        }
                    }
                }
            }

            writer.Flush();
            writer.Close();
        }
        public void XThetaYRToScreen(CoordSettings coordSettings, double xTheta, double yR, out double xScreen, out double yScreen)
        {            
            if (ValidAxes || ValidScale)
            {
                LinearToLog(coordSettings, ref xTheta, ref yR);

                double xGraph, yGraph;
                ConvertToCartesian(NuGenMath.mmUnitize(coordSettings), xTheta, yR, out xGraph, out yGraph);

                GraphToScreen(xGraph, yGraph, out xScreen, out yScreen);
            }
            else
            {
                xScreen = xTheta;
                yScreen = yR;
            }
        }
        public void XThetaYRToScreen(CoordSettings coordSettings, double xTheta, double yR, out double xScreen, out double yScreen)
        {
            if (ValidAxes || ValidScale)
            {
                LinearToLog(coordSettings, ref xTheta, ref yR);

                double xGraph, yGraph;
                ConvertToCartesian(NuGenMath.mmUnitize(coordSettings), xTheta, yR, out xGraph, out yGraph);

                GraphToScreen(xGraph, yGraph, out xScreen, out yScreen);
            }
            else
            {
                xScreen = xTheta;
                yScreen = yR;
            }
        }
Exemple #28
0
        // return list of x values in ascending order
        private List <double> AscendingXValuesList(CoordSettings coord,
                                                   GridMeshSettings grid, ExportSettings xport, int xPrecision)
        {
            List <double> dList = new List <double>();

            switch (xport.pointsSelection)
            {
            case ExportPointsSelection.XFromAllCurves:
            case ExportPointsSelection.XYFromAllCurves:
            {
                foreach (NuGenPointSet pointset in curveList)
                {
                    pointset.MergeUniqueXValues(dList, xPrecision);
                }
            }
            break;

            case ExportPointsSelection.XFromFirstCurve:
                // for simplicity for the user and in code, we use x values from the
                // first curve, not the first exported curve according to the export flags
                (curveList.ToArray().GetValue(0) as NuGenPointSet).MergeUniqueXValues(dList, xPrecision);
                break;

            case ExportPointsSelection.XFromGridLines:
            {
                double x = grid.startX;
                for (int i = 0; i < grid.countX; i++)
                {
                    dList.Add(x);

                    if (coord.xThetaScale == Scale.Linear)
                    {
                        x += grid.stepX;
                    }
                    else
                    {
                        x *= grid.stepX;
                    }
                }
            }
            break;
            }

            return(dList);
        }
Exemple #29
0
        // curves can be exported together in multiple columns, or one after the other in the same column
        private void ExportToStreamAllCurvesTogether(Stream str, CoordSettings coord, GridMeshSettings grid,
                                                     ExportSettings xport, int xPrecision, int yPrecision)
        {
            // list of x values in ascending order
            List <double> xUsed = AscendingXValuesList(coord, grid, xport, xPrecision);

            StreamWriter writer = new StreamWriter(str);

            if (xport.header != ExportHeader.HeaderNone)
            {
                // header
                writer.Write(ExportHeaderPrefix(coord, xport));
                foreach (NuGenPointSet pointset in curveList)
                {
                    if (pointset.Export)
                    {
                        writer.Write(xport.GetDelimiter());
                        writer.Write(pointset.ExportCurveHeader(xport));
                    }
                }
                writer.Write("\n");
            }

            // if only allowing raw data, then forgo interpolation
            bool useInterpolation = (xport.pointsSelection != ExportPointsSelection.XYFromAllCurves);

            foreach (double itrX in xUsed)
            {
                writer.Write(Math.Round(itrX, xPrecision).ToString());
                foreach (NuGenPointSet pointset in curveList)
                {
                    if (pointset.Export)
                    {
                        writer.Write(xport.GetDelimiter());
                        writer.Write(pointset.ExportCurvePoint(itrX, coord, useInterpolation, yPrecision));
                    }
                }

                writer.Write("\n");
            }

            writer.Flush();
            writer.Close();
        }
 //Converts a pair of graph coordinates to log scale
 private void LinearToLog(CoordSettings coordSettings, ref double xTheta, ref double yR)
 {
     if (coordSettings.xThetaScale == Scale.Log)
     {
         if (aY == 0 || bY == 0)
         {
             throw new InvalidOperationException("Values were equal to zero");
         }
         xTheta = Math.Log(xTheta / aX) / bX;
     }
     if (coordSettings.yRScale == Scale.Log)
     {
         if (aY == 0 || bY == 0)
         {
             throw new InvalidOperationException("Values were equal to zero");
         }
         yR = Math.Log(yR / aY) / bY;
     }
 }
        //Converts a screen coordinate pair to a graph coordinate pair
        public void ScreenToXThetaYR(CoordSettings coordSettings, double xScreen, double yScreen, out double xTheta, out double yR)
        {
            if (ValidAxes || ValidScale)
            {
                double xGraph, yGraph;
                ScreenToGraph(xScreen, yScreen, out xGraph, out yGraph);

                ConvertFromCartesian(NuGenMath.mmUnitize(coordSettings), xGraph, yGraph, out xTheta, out yR);

                LogToLinear(coordSettings, ref xTheta, ref yR);
            }
            else
            {
                // until transform is defined just use identity matrix. this branch is only defined when trying
                // to connect points with lines, and the transform is not currently defined
                xTheta = xScreen;
                yR     = yScreen;
            }
        }
Exemple #32
0
        // true if pointset is single valued
        private bool SingleValued(CoordSettings coord, NuGenScreenTranslate transform)
        {
            bool   first = true;
            double xThetaLast = 0.0, xTheta, yR;

            foreach (NuGenPoint point in points)
            {
                transform.ScreenToXThetaYR(coord, point.XScreen, point.YScreen, out xTheta, out yR);

                if (!first && (xTheta < xThetaLast))
                {
                    return(false);
                }

                xThetaLast = xTheta;
                first      = false;
            }

            return(true);
        }
Exemple #33
0
        // first part of each header has optional gnuplot delimiter, and 'x' or 'theta'
        private string ExportHeaderPrefix(CoordSettings coord, ExportSettings xport)
        {
            string prefix = "";

            if (xport.header == ExportHeader.HeaderGnuplot)
            {
                prefix += "#";
            }

            if (coord.frame == ReferenceFrame.Cartesian)
            {
                prefix += "x";
            }
            else
            {
                prefix += "theta";
            }

            return(prefix);
        }
Exemple #34
0
        public bool PointSetGraphLimits(CoordSettings coord, NuGenScreenTranslate transform,
                                        ref double xThetaMin, ref double xThetaMax,
                                        ref double yRMin, ref double yRMax)
        {
            // update and get axis limits
            bool first = AxisSetGraphLimits(coord, transform, ref xThetaMin, ref xThetaMax, ref yRMin, ref yRMax);

            SinglePointSetGraphLimits(scalePointSet, ref first, ref xThetaMin, ref xThetaMax, ref yRMin, ref yRMax);

            foreach (NuGenPointSet pointset in curveList)
            {
                SinglePointSetGraphLimits(pointset, ref first, ref xThetaMin, ref xThetaMax, ref yRMin, ref yRMax);
            }

            foreach (NuGenPointSet pointset in measureList)
            {
                SinglePointSetGraphLimits(pointset, ref first, ref xThetaMin, ref xThetaMax, ref yRMin, ref yRMax);
            }

            return(!first);
        }
        //Makes gridlines from the given translation
        public static List<GridlineScreen> MakeGridLines(NuGenScreenTranslate transform, CoordSettings coordSettings, GridMeshSettings gridMeshSettings)
        {
            List<GridlineScreen> list = new List<GridlineScreen>();
            if (transform.ValidAxes)
            {
                if (coordSettings.frame == ReferenceFrame.Cartesian)
                {
                    list.AddRange(MakeGridX(transform, coordSettings, gridMeshSettings));
                    list.AddRange(MakeGridY(transform, coordSettings, gridMeshSettings));
                    return list;
                }
                else
                {
                    list.AddRange(MakeGridTheta(transform, coordSettings, gridMeshSettings));
                    list.AddRange(MakeGridR(transform, coordSettings, gridMeshSettings));
                    return list;
                }
            }

            return list;
        }
Exemple #36
0
        public GridRemovalSettingsDialog(NuGenDocument doc)
        {
            this.settings           = doc.GridRemovalSettings;
            this.originalImage      = doc.OriginalImage;
            this.discretizeSettings = doc.DiscretizeSettings;
            this.transform          = doc.Transform;
            this.bgColor            = doc.BackgroundColor;
            this.coordSettings      = doc.CoordSettings;

            if (doc.ValidAxes)
            {
                this.gridRemovalMesh = doc.GridDisplaySettings;
            }
            else
            {
                this.gridRemovalMesh.initialized = false;
            }

            discretizeSettings.discretizeMethod = DiscretizeMethod.DiscretizeForeground;

            InitializeComponent();
            InitializeDefaults();

            if (!(doc.ValidAxes || doc.ValidScale))
            {
                textBox1.Enabled  = false;
                textBox2.Enabled  = false;
                checkBox2.Enabled = false;
                checkBox2.Checked = false;
                checkBox3.Enabled = false;
                checkBox3.Checked = false;
            }

            histogram.ValueChanged = this.ValueChanged;

            ValueChanged(true);

            this.MaximumSize = Size;
        }
        //Remove gridlines and reconnect gaps
        public void RemoveAndConnect(NuGenScreenTranslate transform, CoordSettings coordSettings, GridRemovalSettings gridRemovalSettings, Color bgColor)
        {
            int width = bmp.Width;
            int height = bmp.Height;

            PixelState[,] pixels = InitializePixels();

            // 1) Color removal
            if (gridRemovalSettings.removeColor)
            {
                RemoveColor(pixels, gridRemovalSettings, PixelState.PixelOnRemovedStage1);
            }


            // 2) Remove pixels around gridlines
            if (gridRemovalSettings.removeGridlines && gridRemovalSettings.gridDistance > 0.0)
            {
                RemoveGridlines(pixels, transform, coordSettings, gridRemovalSettings, PixelState.PixelOnRemovedStage2);
            }

            // 3) Remove thin lines parallel to the axes
            if (gridRemovalSettings.removeThinLines && gridRemovalSettings.thinThickness > 0.0)
            {
                RemoveThinLines(pixels, coordSettings, transform, gridRemovalSettings.thinThickness,
                    PixelState.PixelOnRemovedStage3, PixelState.PixelOnRemovedStage4);
            }

            // Reconnect the gaps created from the prior steps
            if (gridRemovalSettings.gapSeparation > 0.0)
            {
                ConnectNeuronsAcrossGaps(pixels, gridRemovalSettings.gapSeparation);
            }

            //Write the image
            SavePixels(pixels, bgColor);

            //Save the image
            discretize.SetImage(bmp);
        }
Exemple #38
0
        //Remove gridlines and reconnect gaps
        public void RemoveAndConnect(NuGenScreenTranslate transform, CoordSettings coordSettings, GridRemovalSettings gridRemovalSettings, Color bgColor)
        {
            int width  = bmp.Width;
            int height = bmp.Height;

            PixelState[,] pixels = InitializePixels();

            // 1) Color removal
            if (gridRemovalSettings.removeColor)
            {
                RemoveColor(pixels, gridRemovalSettings, PixelState.PixelOnRemovedStage1);
            }


            // 2) Remove pixels around gridlines
            if (gridRemovalSettings.removeGridlines && gridRemovalSettings.gridDistance > 0.0)
            {
                RemoveGridlines(pixels, transform, coordSettings, gridRemovalSettings, PixelState.PixelOnRemovedStage2);
            }

            // 3) Remove thin lines parallel to the axes
            if (gridRemovalSettings.removeThinLines && gridRemovalSettings.thinThickness > 0.0)
            {
                RemoveThinLines(pixels, coordSettings, transform, gridRemovalSettings.thinThickness,
                                PixelState.PixelOnRemovedStage3, PixelState.PixelOnRemovedStage4);
            }

            // Reconnect the gaps created from the prior steps
            if (gridRemovalSettings.gapSeparation > 0.0)
            {
                ConnectNeuronsAcrossGaps(pixels, gridRemovalSettings.gapSeparation);
            }

            //Write the image
            SavePixels(pixels, bgColor);

            //Save the image
            discretize.SetImage(bmp);
        }
Exemple #39
0
 //Gets the angular units from a coordinate space
 public static MMUnits mmUnitize(CoordSettings coord)
 {
     if (coord.frame == ReferenceFrame.Cartesian)
     {
         return(MMUnits.mmCartesian);
     }
     else
     {
         // polar coordinates
         if (coord.thetaUnits == ThetaUnits.ThetaDegrees)
         {
             return(MMUnits.mmDegrees);
         }
         else if (coord.thetaUnits == ThetaUnits.ThetaGradians)
         {
             return(MMUnits.mmGradians);
         }
         else
         {
             return(MMUnits.mmRadians);
         }
     }
 }
        private static List<GridlineScreen> MakeGridTheta(NuGenScreenTranslate transform, CoordSettings coordSettings, GridMeshSettings gridMeshSettings)
        {
            int i;
            int xStartS, yStartS, xStopS, yStopS;
            double thetaG = gridMeshSettings.startX;
            GridlineScreen gridline;
            List<GridlineScreen> gridlines = new List<GridlineScreen>();
            for (i = 0; i < gridMeshSettings.countX; i++)
            {
                transform.XThetaYRToScreen(coordSettings, thetaG, gridMeshSettings.startY, out xStartS, out yStartS);
                transform.XThetaYRToScreen(coordSettings, thetaG, gridMeshSettings.stopY, out xStopS, out yStopS);

                gridline.Start.X = xStartS;
                gridline.Start.Y = yStartS;
                gridline.Stop.X = xStopS;
                gridline.Stop.Y = yStopS;
                gridline.R = false;

                thetaG += gridMeshSettings.stepX;
                gridlines.Add(gridline); //Maybe not?
            }

            return gridlines;
        }
 private void AdjustMidValuedLogCoords(CoordSettings coordSettings, double[][] r_graph)
 {
     // this function does nothing for linear coordinates. for log coordinates, this
     // function adjusts the middle coordinate since compute_screen_to_graph assumes
     // the coordinates are linear. if the middle log coordinate does not equal the
     // min or max log coordinates, an undesired skew will appear. if two of the axis
     // points share the same log coordinate, the skew will not appear.
     //
     // the only function called after this function that accesses the middle log coordinate
     // will be compute_screen_to_graph
     AdjustMidValuedLogCoord(coordSettings.xThetaScale, ref r_graph[0][0], ref r_graph[0][1], ref r_graph[0][2]);
     AdjustMidValuedLogCoord(coordSettings.yRScale, ref r_graph[1][0], ref r_graph[1][1], ref r_graph[1][2]);
 }
        // for curve pointsets connected as Single Valued Functions, since the graph coordinates
        // of all points are updated, we must reconnect any points that were reordered. remember,
        // a single valued function has only a single value per xTheta value, so the lines cannot overlap
        public void ForceSingleValued(CoordSettings coord, NuGenScreenTranslate transform)
        {
            // quick exit if pointset is a closed contour, which is the case for all axis, scale and
            // measure pointsets. curve pointsets may be either single valued functions, or closed contours
            if (style.lineConnectAs != LineConnectAs.SingleValuedFunction)
                return;

            // quick exit if points are already in order
            if (SingleValued(coord, transform))
                return;

            Comparison<NuGenPoint> comparison = new Comparison<NuGenPoint>(this.XThetaSort);                

            // sort the points by xTheta
            points.Sort(comparison);

            // to prevent having to remove N lines and then immediately adding N lines, we only
            // adjust as many lines as necessary
            NuGenPoint pOld = points[points.Count - 1];
            NuGenPoint pOlder = null;

            foreach (NuGenPoint pNew in points)
            {
                if (pOlder != null)
                {
                    if ((pOlder.NextLine != pNew.PreviousLine) || (pNew.PreviousLine == null))
                    {
                        if (pOlder.NextLine == null)
                        {
                            pOlder.NextLine = pOld.NextLine;
                            pOld.NextLine = null;
                        }

                        pOlder.NextLine.start.X = pOlder.XScreen;
                        pOlder.NextLine.start.Y = pOlder.YScreen;
                        pOlder.NextLine.end.X = pNew.XScreen;
                        pOlder.NextLine.end.Y = pNew.YScreen;

                        pNew.PreviousLine = pOlder.NextLine;
                    }
                }
                else
                {
                    pNew.PreviousLine = null;
                }

                pOlder = pNew;
            }
        }
 //Converts a pair of graph coordinates to log scale
 private void LinearToLog(CoordSettings coordSettings, ref double xTheta, ref double yR)
 {
     if (coordSettings.xThetaScale == Scale.Log)
     {
         if(aY == 0 || bY == 0)
             throw new InvalidOperationException("Values were equal to zero");
         xTheta = Math.Log(xTheta / aX) / bX;
     }
     if (coordSettings.yRScale == Scale.Log)
     {
         if(aY == 0 || bY == 0)
             throw new InvalidOperationException("Values were equal to zero");
         yR = Math.Log(yR / aY) / bY;
     }
 }
 //Converts a pair of log coordinates to linear scale
 private void LogToLinear(CoordSettings coordSettings, ref double xTheta, ref double yR)
 {
     if(coordSettings.xThetaScale == Scale.Log)
         xTheta = aX * Math.Exp(bX * xTheta);
     if(coordSettings.yRScale == Scale.Log)
         yR = aY * Math.Exp(bY * yR);
 }
        // apply the transformation to set graph coordinates of the points in the curve and measure pointsets
        public void UpdateGraphCoordinates(CoordSettings coord, NuGenScreenTranslate transform)
        {
            foreach (NuGenPoint point in points)
            {
                double xTheta, yR;
                transform.ScreenToXThetaYR(coord, point.XScreen, point.YScreen, out xTheta, out yR);

                point.XThetaGraph = xTheta;
                point.YRGraph = yR;
            }
        }
        // given an x value, return the corresponding y value, interpolating if necessary
        public string ExportCurvePoint(double x, CoordSettings coord, bool useInterpolation, int yPrecision)
        {
            string yNew = ""; // initial empty value might be returned if interpolation is disabled
  
              if (Points.Count == 0)
                return yNew;
                
              if (!useInterpolation)
              {
                // x value has to exactly match one of the points in this curve
                foreach(NuGenPoint p in Points)
                {
                  if (x == p.XThetaGraph)
                    return Math.Round(p.YRGraph, yPrecision).ToString();
                }

                return yNew;
              }

              if (Points.Count == 1)
              {
                  foreach(NuGenPoint p in Points)
                  {
                      return Math.Round(p.YRGraph, yPrecision).ToString();
                  }
              }

            IEnumerator<NuGenPoint> lEnum = Points.GetEnumerator();
            IEnumerator<NuGenPoint> rEnum = Points.GetEnumerator();
            rEnum.MoveNext();
            rEnum.MoveNext();
            lEnum.MoveNext();

            NuGenPoint pLeft = lEnum.Current;
            NuGenPoint pRight = rEnum.Current;

            while (x > rEnum.Current.XThetaGraph)
            {
                rEnum.MoveNext();
                lEnum.MoveNext();

                if (rEnum.Current != null)
                {
                    pLeft = lEnum.Current;
                    pRight = rEnum.Current;
                }
                else
                    break;
            }

              double leftPointX = pLeft.XThetaGraph;
              double rightPointX = pRight.XThetaGraph;
              double leftPointY = pLeft.YRGraph;
              double rightPointY = pRight.YRGraph;

              if (AdjustForLogScale(coord.xThetaScale, ref leftPointX) &&
                    AdjustForLogScale(coord.xThetaScale, ref rightPointX) &&
                    AdjustForLogScale(coord.xThetaScale, ref x) &&
                    AdjustForLogScale(coord.yRScale, ref leftPointY) &&
                    AdjustForLogScale(coord.yRScale, ref rightPointY))
              { 
                double denominator = rightPointX - leftPointX;
                if (denominator < NuGenDefaultSettings.GetInstance().DoubleMin)
                  yNew = Math.Round(leftPointX, yPrecision).ToString();
                else
                {
                  // if x value is between the points this is an interpolation (0<s<1), otherwise an extrapolation
                  double s = (x - leftPointX) / denominator;

                  // interpolate or extrapolate
                  double otherPoint = (1.0 - s) * leftPointY + s * rightPointY;

                  // adjust for log scale
                  if (coord.yRScale == Scale.Log)
                    otherPoint = Math.Pow((double) 10.0, otherPoint);
                    
                  yNew = Math.Round(otherPoint, yPrecision).ToString();
                }
              }

              return yNew;
        }
 public void YBasisScreen(CoordSettings coordSettings, out double xScreen, out double yScreen)
 {
     // return basis vector in x direction. do not look at screen increment
     // resulting from graph increment of (0,0) to (1,0), since log scale may
     // be in effect which would crash with a zero
     double xBeforeS, yBeforeS;
     double xAfterS, yAfterS;
     XThetaYRToScreen(coordSettings, 1.0, 1.0, out xBeforeS, out yBeforeS);
     XThetaYRToScreen(coordSettings, 1.0, 10.0, out xAfterS, out yAfterS);
     xScreen = xAfterS - xBeforeS;
     yScreen = yAfterS - yBeforeS;
 }
        private void InitializeThin(CoordSettings coordSettings, NuGenScreenTranslate transform, double thinThickness)
        {
            transform.XBasisScreen(coordSettings, out xBasisXS, out xBasisYS);
            transform.YBasisScreen(coordSettings, out yBasisXS, out yBasisYS);

            // initialize search patterns
            InitializeThinSearch(thinThickness, xBasisXS, yBasisXS, searchPatternPlusX);
            InitializeThinSearch(thinThickness, xBasisYS, yBasisYS, searchPatternPlusY);
            InitializeThinSearch(thinThickness, -xBasisXS, yBasisXS, searchPatternMinusX);
            InitializeThinSearch(thinThickness, xBasisYS, -yBasisYS, searchPatternMinusY);
        }
        //Removes pixels around user defined gridlines
        private void RemoveGridlines(PixelState[,] pixels, NuGenScreenTranslate transform,
            CoordSettings coordSettings, GridRemovalSettings gridRemovalSettings, PixelState pxState)
        {
            if (transform.ValidAxes)
            {
                List<GridlineScreen> gridlines;
                gridlines = NuGenGridMesh.MakeGridLines(transform, coordSettings, gridRemovalSettings.gridMesh);

                foreach (GridlineScreen gridline in gridlines)
                {
                    int xStart = gridline.Start.X;
                    int yStart = gridline.Start.Y;
                    int xStop = gridline.Stop.X;
                    int yStop = gridline.Stop.Y;

                    if (Math.Abs(xStop - xStart) < Math.Abs(yStop - yStart))
                    {
                        //Vertical lines
                        RemoveGridlineVertical(pixels, xStart, yStart, xStop, yStop, gridRemovalSettings, pxState);
                    }
                    else
                    {
                        //Horizontal lines
                        RemoveGridlineHorizontal(pixels, xStart, yStart, xStop, yStop, gridRemovalSettings, pxState);
                    }
                }
            }
        }
        //Removes thin lines which are parallel to the user defined axes
        private void RemoveThinLines(PixelState[,] pixels, CoordSettings coordSettings, NuGenScreenTranslate transform,
                double thinThickness, PixelState pixelStateRemovedPass1, PixelState pixelStateRemovedPass2)
        {
            if (transform.ValidAxes)
            {
                InitializeThin(coordSettings, transform, thinThickness);

                // first pass erases the gridMeshSettings lines, except for the junctions
                EraseThinPixels(pixels, thinThickness, pixelStateRemovedPass1);

                // second pass erases the gridMeshSettings line junctions, which are little islands of on-pixels
                EraseThinPixels(pixels, thinThickness, pixelStateRemovedPass2);
            }
        }
        //Converts a screen coordinate pair to a graph coordinate pair
        public void ScreenToXThetaYR(CoordSettings coordSettings, double xScreen, double yScreen, out double xTheta, out double yR)
        {
            if (ValidAxes || ValidScale)
            {
                double xGraph, yGraph;
                ScreenToGraph(xScreen, yScreen, out xGraph, out yGraph);

                ConvertFromCartesian(NuGenMath.mmUnitize(coordSettings), xGraph, yGraph, out xTheta, out yR);

                LogToLinear(coordSettings, ref xTheta, ref yR);
            }
            else
            {
                // until transform is defined just use identity matrix. this branch is only defined when trying
                // to connect points with lines, and the transform is not currently defined
                xTheta = xScreen;
                yR = yScreen;
            }
        }
        //Computes the graph area based on the scale bar definition
        public int ComputeScaleTransformation(CoordSettings coordSettings, NuGenPointSet pointSet)
        {
            double[][] r_graph = { new double[3], new double[3], new double[3] };
            double[,] r_screen = new double[3, 3];

            List<NuGenPoint> points = pointSet.Points;

            scalePointCount = 0;
            validScale = false;

            foreach (NuGenPoint point in points)
            {
                if (scalePointCount == 2)
                    throw new InvalidOperationException("Can not define more scale bar points");

                if (point.GraphCoordsAreDefined())
                {
                    double xGraph, yGraph;
                    ConvertToCartesian(NuGenMath.mmUnitize(coordSettings), point.XThetaGraph, point.YRGraph,
                        out xGraph, out yGraph);

                    r_graph[0][scalePointCount] = xGraph;
                    r_graph[1][scalePointCount] = yGraph;
                    r_graph[2][scalePointCount] = 1.0;

                    r_screen[0, scalePointCount] = point.XScreen;
                    r_screen[1, scalePointCount] = point.YScreen;
                    r_screen[2, scalePointCount] = 1.0;

                    scalePointCount++;
                }
            }

            if (scalePointCount == 2)
            {
                // create virtual third point along a virtual axis which is just orthogonal to the virtual
                // axis between the other two points. assumes all points are in same z-value (which is 1.0) plane
                double[] axis1 = new double[3];
                double[] axis2 = new double[3];
                double[] z = { 0.0, 0.0, 1.0 };

                axis1[0] = r_graph[0][1] - r_graph[0][0];
                axis1[1] = r_graph[1][1] - r_graph[1][0];
                axis1[2] = r_graph[2][1] - r_graph[2][0];

                NuGenMath.VectorCrossProduct(z, axis1, axis2);

                r_graph[0][2] = r_graph[0][0] + axis2[0];
                r_graph[1][2] = r_graph[1][0] + axis2[1];
                r_graph[2][2] = 1.0;

                axis1[0] = r_screen[0, 1] - r_screen[0, 0];
                axis1[1] = r_screen[1, 1] - r_screen[1, 0];
                axis1[2] = r_screen[2, 1] - r_screen[2, 0];

                NuGenMath.VectorCrossProduct(z, axis1, axis2);

                r_screen[0, 2] = r_screen[0, 0] + axis2[0];
                r_screen[1, 2] = r_screen[1, 0] + axis2[1];
                r_screen[2, 2] = 1.0;

                int rtnS2G = NuGenMath.ScreenToGraph(r_graph, r_screen,
                  screenToGraph, graphToScreen);

                // log to linear transformation is not allowed when using scale bar since it would
                // be such an extremely rare special case that its benefit would be minimal, especially
                // since it would only confuse the majority of users who would not be expecting it

                validScale = (rtnS2G == NuGenMath.SUCCESS);

                switch (rtnS2G)
                {
                    case NuGenMath.SUCCESS:
                        return NuGenMath.SUCCESS;                        
                    case NuGenMath.BAD_GRAPH_COORDINATES:
                        return NuGenMath.BAD_GRAPH_COORDINATES;                  
                    case NuGenMath.BAD_SCREEN_COORDINATES:
                        return NuGenMath.BAD_SCREEN_COORDINATES;                   
                }
            }

            return NuGenMath.SUCCESS;
        }
        // true if pointset is single valued
        private bool SingleValued(CoordSettings coord, NuGenScreenTranslate transform)
        {
            bool first = true;
            double xThetaLast = 0.0, xTheta, yR;
            foreach(NuGenPoint point in points)
            {
                transform.ScreenToXThetaYR(coord, point.XScreen, point.YScreen, out xTheta, out yR);

                if (!first && (xTheta < xThetaLast))
                    return false;

                xThetaLast = xTheta;
                first = false;
            }

            return true;
        }
        //Computes the ax ay bx by values needed in logarithmic to linear conversions
        public int ComputeLogToFromLinear(CoordSettings coordSettings, double[][] r_graph)
        {
            int retVal = ComputeLogToFromLinear(coordSettings.xThetaScale, r_graph[0], out aX, out bX);

            if (retVal != NuGenMath.SUCCESS)
                return retVal;            

            return ComputeLogToFromLinear(coordSettings.yRScale, r_graph[1], out aY, out bY);
        }
        private static List<GridlineScreen> MakeGridX(NuGenScreenTranslate transform, CoordSettings coordSettings, GridMeshSettings gridMeshSettings)
        {
            int i;
            int xStartS, yStartS, xStopS, yStopS;
            double xG = gridMeshSettings.startX;
            GridlineScreen gridline;
            List<GridlineScreen> gridlines = new List<GridlineScreen>();
            for (i = 0; i < gridMeshSettings.countX; i++)
            {
                gridline = new GridlineScreen();
                transform.XThetaYRToScreen(coordSettings, xG, gridMeshSettings.startY, out xStartS, out yStartS);
                transform.XThetaYRToScreen(coordSettings, xG, gridMeshSettings.stopY, out xStopS, out yStopS);

                gridline.Start.X = xStartS;
                gridline.Start.Y = yStartS;
                gridline.Stop.X = xStopS;
                gridline.Stop.Y = yStopS;
                gridline.R = false;

                gridlines.Add(gridline);

                if (coordSettings.xThetaScale == Scale.Linear)
                    xG += gridMeshSettings.stepX;
                else
                    xG *= gridMeshSettings.stepX;
            }

            return gridlines;
        }
        //Computes the graph area based on the defined axis points, returns a value corresponding
        // to the result of the calculation
        public int ComputeAxesTransformation(CoordSettings coordSettings, NuGenPointSet pointSet)
        {
            double[][] r_graph = { new double[3], new double[3], new double[3] };
            double[,] r_screen = new double[3,3];

            List<NuGenPoint> points = pointSet.Points;

            axisPointCount = 0;
            validAxes = false;

            foreach(NuGenPoint p in points)
            {
                if(axisPointCount == 3)
                    throw new InvalidOperationException("We have three axis points, can not compute more");

                if(p.GraphCoordsAreDefined())
                {
                    double xGraph, yGraph;
                    ConvertToCartesian(NuGenMath.mmUnitize(coordSettings), p.XThetaGraph, p.YRGraph, out xGraph, out yGraph);

                    r_graph[0][axisPointCount] = xGraph;
                    r_graph[1][axisPointCount] = yGraph;
                    r_graph[2][axisPointCount] = 1.0;

                    r_screen[0, axisPointCount] = p.XScreen;
                    r_screen[1, axisPointCount] = p.YScreen;
                    r_screen[2, axisPointCount] = 1.0;

                    axisPointCount++;
                }
            }

            if(axisPointCount == 3)
            {
                AdjustMidValuedLogCoords(coordSettings, r_graph);

                int rtnS2G = NuGenMath.ScreenToGraph(r_graph, r_screen, screenToGraph, graphToScreen);                

                validAxes = false;

                if(rtnS2G == NuGenMath.SUCCESS)
                {
                    int rtnL2L = ComputeLogToFromLinear(coordSettings, r_graph);

                    switch(rtnL2L)
                    {
                        case NuGenMath.SUCCESS:
                            break;
                        case NuGenMath.NONPOSITIVE_COORDINATE:
                            return NuGenMath.NONPOSITIVE_COORDINATE;
                        case NuGenMath.NO_SPREAD:
                            return NuGenMath.NO_SPREAD;
                    }
                }

                validAxes = (rtnS2G == NuGenMath.SUCCESS);

                switch (rtnS2G)
                {
                    case NuGenMath.SUCCESS:
                        return NuGenMath.SUCCESS;
                    case NuGenMath.BAD_GRAPH_COORDINATES:
                        return NuGenMath.BAD_GRAPH_COORDINATES;
                    case NuGenMath.BAD_SCREEN_COORDINATES:
                        return NuGenMath.BAD_SCREEN_COORDINATES;
                }
            }

            return NuGenMath.SUCCESS;
        }