Exemple #1
0
        bool ZedGraphControl_MouseMoveEvent( ZedGraph.ZedGraphControl sender, MouseEventArgs e )
        {
            if( CurrentGraphForm == null || !peakIntegrationMode.Checked || !CurrentGraphForm.ZedGraphControl.Focused )
                return false;

            if( integratePeaksLine != null && e.Button == MouseButtons.Left )
            {
                double x = CurrentGraphForm.ZedGraphControl.GraphPane.XAxis.Scale.ReverseTransform( (float) e.X );
                double y = CurrentGraphForm.ZedGraphControl.GraphPane.YAxis.Scale.ReverseTransform( (float) e.Y );
                //CurrentGraphForm.ZedGraphControl.GraphPane.GraphObjList.Remove( integratePeaksLine );
                //integratePeaksLine = new ZedGraph.LineItem( integratePeaksLine.Location.X1, integratePeaksLine.Location.Y1, x, y );
                //integratePeaksLine.Location.CoordinateFrame = ZedGraph.CoordType.AxisXYScale;
                //CurrentGraphForm.ZedGraphControl.GraphPane.GraphObjList.Add( integratePeaksLine );
                integratePeaksLine.Points[1].X = Math.Min( CurrentGraphForm.ZedGraphControl.GraphPane.XAxis.Scale.Max, Math.Max( CurrentGraphForm.ZedGraphControl.GraphPane.XAxis.Scale.Min, x ) );
                integratePeaksLine.Points[1].Y = Math.Min( CurrentGraphForm.ZedGraphControl.GraphPane.YAxis.Scale.Max, Math.Max( CurrentGraphForm.ZedGraphControl.GraphPane.YAxis.Scale.Min, y ) );

                if( CurrentGraphForm.ZedGraphControl.GraphPane.CurveList[0].Points is PointList )
                {
                    foreach( ZedGraph.PolyObj obj in integratePeaksAreas )
                        CurrentGraphForm.ZedGraphControl.GraphPane.GraphObjList.Remove( obj );
                    integratePeaksAreas.Clear();

                    PointList pointList = (PointList) CurrentGraphForm.ZedGraphControl.GraphPane.CurveList[0].Points;
                    if( pointList.ScaledCount == 0 )
                        return false;

                    double x1, y1, x2, y2;
                    if( integratePeaksLine.Points[0].X > integratePeaksLine.Points[1].X )
                    {
                        x1 = integratePeaksLine.Points[1].X;
                        y1 = integratePeaksLine.Points[1].Y;
                        x2 = integratePeaksLine.Points[0].X;
                        y2 = integratePeaksLine.Points[0].Y;
                    } else
                    {
                        x1 = integratePeaksLine.Points[0].X;
                        y1 = integratePeaksLine.Points[0].Y;
                        x2 = integratePeaksLine.Points[1].X;
                        y2 = integratePeaksLine.Points[1].Y;
                    }

                    int lowerBoundIndex = pointList.LowerBound( x1 );
                    int upperBoundIndex = pointList.LowerBound( x2 );
                    if( upperBoundIndex < 0 )
                        upperBoundIndex = pointList.ScaledCount - 1;

                    double totalIntegratedArea = 0.0;
                    int totalAreaPoints = 0;
                    int totalAreaCount = 0;

                    // integration line can be in any of these states:

                    // * entirely to the left of the curve:
                    //		- no integration
                    // * entirely to the right of the curve:
                    //		- no integration
                    // * entirely between two consecutive points:
                    //		- integration is entirely interpolated based on data slope
                    // * starts to the left of the curve and ends between two consecutive points:
                    //		- start integration at the X value of the first data point
                    //		- end integration at the line's right X value
                    // * starts between two consecutive points and ends to the right of the curve:
                    //		- start integration at the line's left X value
                    //		- end integration at the X value of the last data point
                    // * starts between two consecutive points and ends between two different consecutive points:
                    //		- start integration at the line's left X value
                    //		- end integration at the line's right X value

                    // * entirely above the curve:
                    //		- no integration
                    // * starts above the curve and ends below the curve:
                    //		- start integration at the first intersection of the line with the curve
                    //		- end integration at the X value where the line ends
                    // * starts below the curve and ends above the curve:
                    //		- start integration at the X value where the line starts
                    //		- end integration at the last intersection of the line with the curve
                    // * entirely below the curve:
                    //		- start and end integration at the X values of the line

                    // * the Y value of the line's start point is less than 0 and the end point's is not:
                    //		- a special area point must be added before the first area's bottom left point
                    //		- add it at the intersection of the line with the X axis
                    // * the Y value of the line's end point is less than 0 and the start point's is not:
                    //		- a special area point must be added after the last area's bottom right point
                    //		- add it at the intersection of the line with the X axis
                    // * the Y values of both the start and end points of the line are less than 0:
                    //		- no special points are necessary

                    if( lowerBoundIndex >= 0 && x2 > x1 )
                    {
                        // calculate the linear function for integration line
                        double integratePeaksLineA = ( y2 - y1 ) / ( x2 - x1 );
                        double integratePeaksLineB = y1 - ( integratePeaksLineA * x1 );

                        // restrict the X range of the integration line to the minimum and maximum X values of the curve
                        // interpolate the Y value of the integration line at those X values
                        double leftInterpolatedX = Math.Max( pointList.ScaledList[0].X, x1 );
                        double leftInterpolatedY = Math.Max( 0, integratePeaksLineA * leftInterpolatedX + integratePeaksLineB );
                        double rightInterpolatedX = Math.Min( pointList.ScaledList[pointList.ScaledCount - 1].X, x2 );
                        double rightInterpolatedY = Math.Max( 0, integratePeaksLineA * rightInterpolatedX + integratePeaksLineB );

                        List<ZedGraph.PointD> areaPoints = new List<ZedGraph.PointD>();
                        //List<List<ZedGraph.PointD>> areaTrapezoids = new List<List<ZedGraph.PointD>>();
                        for( int i = Math.Max( 1, lowerBoundIndex ); i <= upperBoundIndex; ++i )
                        {
                            ZedGraph.PointPair rightPoint = pointList.ScaledList[i];
                            ZedGraph.PointPair leftPoint = pointList.ScaledList[i - 1];

                            // interpolate the Y value of the integration line at the previous and current points' X value
                            double lastPointLineY = integratePeaksLineA * leftPoint.X + integratePeaksLineB;
                            double curPointLineY = integratePeaksLineA * rightPoint.X + integratePeaksLineB;

                            // calculate the linear function between the previous and current points
                            double dataA = ( rightPoint.Y - leftPoint.Y ) / ( rightPoint.X - leftPoint.X );
                            double dataB = rightPoint.Y - ( dataA * rightPoint.X );

                            double leftInterpolatedPointY = dataA * leftInterpolatedX + dataB;
                            double rightInterpolatedPointY = dataA * rightInterpolatedX + dataB;

                            bool leftInterpolatedPointIsAboveLine = ( leftInterpolatedPointY >= leftInterpolatedY );
                            bool rightInterpolatedPointIsAboveLine = ( rightInterpolatedPointY >= rightInterpolatedY );

                            bool leftPointIsAboveLine = ( leftPoint.Y > lastPointLineY );
                            bool rightPointIsAboveLine = ( rightPoint.Y > curPointLineY );

                            bool leftPointIsLowerBound = ( i == 1 || i == lowerBoundIndex );
                            bool rightPointIsUpperBound = ( i == upperBoundIndex );

                            if( !leftInterpolatedPointIsAboveLine && !rightInterpolatedPointIsAboveLine ||
                                !leftPointIsAboveLine && !rightPointIsAboveLine )
                                continue;

                            bool needIntersection = ( leftInterpolatedPointIsAboveLine != rightInterpolatedPointIsAboveLine );

                            bool areaIsEmpty = ( areaPoints.Count == 0 );

                            if( rightPointIsAboveLine || leftPointIsAboveLine )
                            {
                                if( areaIsEmpty ) // start a new area
                                {
                                    if( leftPointIsLowerBound && leftInterpolatedPointIsAboveLine ) // interpolate the point on the curve above the line
                                    {
                                        if( y1 <= 0 && y2 > 0 )
                                        {
                                            double croppedBottomX = -integratePeaksLineB / integratePeaksLineA;
                                            if( croppedBottomX != leftInterpolatedX )
                                                areaPoints.Add( new ZedGraph.PointD( croppedBottomX, 0 ) );
                                        }
                                        areaPoints.Add( new ZedGraph.PointD( leftInterpolatedX, leftInterpolatedY ) ); // bottom left
                                        areaPoints.Add( new ZedGraph.PointD( leftInterpolatedX, leftInterpolatedPointY ) ); // top left

                                    } else if( needIntersection ) // interpolate the intersection of line and curve
                                    {
                                        double intersectX = ( dataB - integratePeaksLineB ) / ( integratePeaksLineA - dataA );
                                        double intersectY = dataA * intersectX + dataB;

                                        areaPoints.Add( new ZedGraph.PointD( intersectX, intersectY ) );
                                    }
                                }

                                if( rightPointIsUpperBound ) // end at the upper bound and add current area to the area list
                                {
                                    if( rightInterpolatedPointIsAboveLine )
                                    {
                                        // add a new point to the current area
                                        //areaPoints.Add( new ZedGraph.PointD( pointList.ScaledList[i].X, pointList.ScaledList[i].Y ) );

                                        areaPoints.Add( new ZedGraph.PointD( rightInterpolatedX, rightInterpolatedPointY ) ); // top right
                                        areaPoints.Add( new ZedGraph.PointD( rightInterpolatedX, rightInterpolatedY ) ); // bottom right
                                        if( y2 <= 0 && y1 > 0 ) // add another point if line extends below X axis
                                        {
                                            double croppedBottomX = -integratePeaksLineB / integratePeaksLineA;
                                            if( croppedBottomX != rightInterpolatedX )
                                                areaPoints.Add( new ZedGraph.PointD( croppedBottomX, 0 ) );
                                        }
                                    } else if( needIntersection ) // interpolate the intersection of line and curve
                                    {
                                        double intersectX = ( dataB - integratePeaksLineB ) / ( integratePeaksLineA - dataA );
                                        double intersectY = dataA * intersectX + dataB;

                                        areaPoints.Add( new ZedGraph.PointD( intersectX, intersectY ) );
                                    }

                                    if( areaPoints.Count == 0 )
                                        continue;

                                    ZedGraph.PolyObj integratePeaksArea = new ZedGraph.PolyObj( areaPoints.ToArray(), Color.Black, Color.Cyan, Color.Cyan );
                                    integratePeaksArea.Location.CoordinateFrame = ZedGraph.CoordType.AxisXYScale;
                                    //integratePeaksArea.IsClosedFigure = true;
                                    areaPoints.Add( areaPoints[0] );
                                    integratePeaksAreas.Add( integratePeaksArea );

                                    double currentIntegratedArea = 0.0;
                                    for( int k, j = 0; j < areaPoints.Count; ++j )
                                    {
                                        k = ( j + 1 ) % areaPoints.Count;
                                        currentIntegratedArea += areaPoints[j].X * areaPoints[k].Y;
                                        currentIntegratedArea -= areaPoints[j].Y * areaPoints[k].X;
                                    }
                                    totalIntegratedArea += Math.Abs( currentIntegratedArea / 2.0 );
                                    totalAreaPoints += areaPoints.Count - 1;
                                    ++totalAreaCount;
                                    areaPoints.Clear();
                                } else
                                {
                                    // add a new top right point to the current area
                                    areaPoints.Add( new ZedGraph.PointD( pointList.ScaledList[i].X, pointList.ScaledList[i].Y ) );
                                }

                            }

                            if( !rightPointIsAboveLine && !rightPointIsUpperBound )// close the current area and add it to the area list
                            {
                                double intersectX = ( dataB - integratePeaksLineB ) / ( integratePeaksLineA - dataA );
                                double intersectY = dataA * intersectX + dataB;

                                areaPoints.Add( new ZedGraph.PointD( intersectX, intersectY ) );

                                if( areaPoints.Count == 0 )
                                    continue;

                                ZedGraph.PolyObj integratePeaksArea = new ZedGraph.PolyObj( areaPoints.ToArray(), Color.Black, Color.Cyan, Color.Cyan );
                                integratePeaksArea.Location.CoordinateFrame = ZedGraph.CoordType.AxisXYScale;
                                //integratePeaksArea.IsClosedFigure = true;
                                areaPoints.Add( areaPoints[0] );
                                integratePeaksAreas.Add( integratePeaksArea );
                                double currentIntegratedArea = 0.0;
                                for( int k, j = 0; j < areaPoints.Count; ++j )
                                {
                                    k = ( j + 1 ) % areaPoints.Count;
                                    currentIntegratedArea += areaPoints[j].X * areaPoints[k].Y;
                                    currentIntegratedArea -= areaPoints[j].Y * areaPoints[k].X;
                                }
                                totalIntegratedArea += Math.Abs( currentIntegratedArea / 2.0 );
                                totalAreaPoints += areaPoints.Count - 1;
                                ++totalAreaCount;
                                areaPoints.Clear();
                            }
                        }

                                /*if( areaPoints.Count > 2 )
                                {
                                    List<ZedGraph.PointD> areaTrapezoid = new List<ZedGraph.PointD>();
                                    areaTrapezoid.Add( areaPoints[areaPoints.Count - 3] ); // top left
                                    areaTrapezoid.Add( areaPoints[areaPoints.Count - 2] ); // top right
                                    areaTrapezoid.Add( areaPoints[areaPoints.Count - 1] ); // bottom right

                                    // bottom left
                                    double bottomLeftY = Math.Max( 0, integratePeaksLineA * areaPoints[areaPoints.Count - 3].X + integratePeaksLineB );
                                    areaTrapezoid.Add( new ZedGraph.PointD( areaPoints[areaPoints.Count - 3].X, bottomLeftY ) );

                                    areaTrapezoids.Add( areaTrapezoid );
                                }*/
                        /*foreach( List<ZedGraph.PointD> trapezoidPoints in areaTrapezoids )
                        {
                            ZedGraph.PolyObj trapezoid = new ZedGraph.PolyObj( trapezoidPoints.ToArray(), Color.Black, Color.Green, Color.Green );
                            trapezoid.Location.CoordinateFrame = ZedGraph.CoordType.AxisXYScale;
                            trapezoid.IsClosedFigure = true;
                            integratePeaksAreas.Add( trapezoid );
                        }*/
                        foreach( ZedGraph.PolyObj obj in integratePeaksAreas )
                            CurrentGraphForm.ZedGraphControl.GraphPane.GraphObjList.Add( obj );
                        //CurrentGraphForm.ZedGraphControl.GraphPane.Title.Text = totalIntegratedArea.ToString("f0") + " " + totalAreaPoints + " " + totalAreaCount;
                        //CurrentGraphForm.ZedGraphControl.GraphPane.Title.IsVisible = true;
                        CurrentGraphForm.CurrentGraphItem.TotalIntegratedArea = totalIntegratedArea;
                        //int currentIndex = scanNumberComboBox.SelectedIndex;
                        //object currentObject = scanNumberComboBox.SelectedItem;
                        //scanNumberComboBox.Items.RemoveAt( currentIndex );
                        //scanNumberComboBox.Items.Insert( currentIndex, currentObject );
                    }
                }
                CurrentGraphForm.ZedGraphControl.Refresh();
                return false;
            }
            return true;
        }
Exemple #2
0
        private void DesenhaPerfil()
        {
            zedPerfil.GraphPane.CurveList.Clear();
            zedPerfil.GraphPane.GraphObjList.Clear();


            double h = (double)numH.Value;

            double[] sols = AreaPerimeter.Solve(lstProfile, h);

            if (sols.Length % 2 == 0)
            {
                double[] start       = new double[sols.Length >> 1];
                double[] stop        = new double[sols.Length >> 1];
                double   totalLength = 0;
                for (int k = 0; k < sols.Length; k += 2)
                {
                    start[k >> 1] = sols[k];
                    stop[k >> 1]  = sols[k + 1];
                    totalLength  += sols[k + 1] - sols[k];

                    double[] xx = new double[] { sols[k], sols[k + 1] };
                    double[] yy = new double[] { h, h };
                    //ZedGraph.LineItem li3 = zedPerfil.GraphPane.AddCurve(k == 0 ? "Nível de água" : "", xx, yy, Color.LightBlue, ZedGraph.SymbolType.None);
                    ZedGraph.LineItem li3 = zedPerfil.GraphPane.AddCurve(k == 0 ? "Water level" : "", xx, yy, Color.LightBlue, ZedGraph.SymbolType.None);
                    li3.Line.Width = 3;
                }

                double p2;
                double area = AreaPerimeter.GetArea(lstProfile, h, start, stop, out p2);

                lblArea.Text    = Math.Round(area, 3).ToString();
                lblPerim.Text   = Math.Round(p2, 3).ToString();
                lblSurfLen.Text = Math.Round(totalLength, 3).ToString();
            }



            #region Graficos
            double[] x = lstProfile.Keys.ToArray();
            double[] y = lstProfile.Values.ToArray();

            ZedGraph.LineItem li = zedPerfil.GraphPane.AddCurve("", x, y, Color.SandyBrown);
            li.Line.Width = 3;


            double[] xNivel = new double[] { 10, 20 };
            double[] yNivel = new double[] { -1, -1 };
            //ZedGraph.LineItem li2 = zedPerfil.GraphPane.AddCurve("", xNivel, yNivel, Color.LightBlue); //, ZedGraph.SymbolType.None);
            //li2.Line.Fill = new ZedGraph.Fill(Color.Blue, Color.Blue, 45F);

            List <ZedGraph.PointD> lstPt = new List <ZedGraph.PointD>();
            lstPt.Add(new ZedGraph.PointD(2, -1));
            lstPt.Add(new ZedGraph.PointD(8, -1));
            lstPt.Add(new ZedGraph.PointD(9, -3));
            lstPt.Add(new ZedGraph.PointD(0, -3.5));

            ZedGraph.PolyObj pObj = new ZedGraph.PolyObj(lstPt.ToArray(), Color.LightBlue, Color.Blue, Color.Blue);
            //zedPerfil.GraphPane.GraphObjList.Add(pObj);

            zedPerfil.AxisChange();
            zedPerfil.Refresh();
            #endregion
        }