コード例 #1
0
ファイル: Rectangle.cs プロジェクト: harmanpa/csv-compare
        /// <summary>
        ///  Remove points and add intersection points in case of backward order
        /// </summary>
        /// <param name="X">x values of curve</param>
        /// <param name="Y">y values of curve</param>
        /// <param name="lower">if true, algorithm for lower tube curve is used;<para>
        /// if false, algorithm for upper tube curve is used</para></param>
        /// <return>Number of loops, that are removed.</return>
        private static int removeLoop(List<double> X, List<double> Y, bool lower)
        {
            // Visualization of working of removeLoop
            bool visualize = false;

            List<double> XLoops = new List<double>(X);
            List<double> YLoops = new List<double>(Y);
            int j = 1;
            int countLoops = 0;

            #if GUI
            // Visualization
            if (visualize)
            {
                ChartControl chartControl = new ChartControl(600, Int32.MaxValue, true);
                chartControl.AddLine("Tube curve with loop", X, Y, Color.FromKnownColor(KnownColor.Cyan));
                Application.Run(chartControl);
            }
            #endif
            while (j < X.Count - 2)
            {
                // Find backward segment (j, j + 1)
                if (X[j + 1] < X[j])
                {
                    countLoops++;

                    // ----------------------------------------------------------------------------------------------------
                    // 1. Find i,k, such that i <= j < j + 1 <= k - 1 and segment (i - 1, i) intersect segment (k - 1, k)
                    // ----------------------------------------------------------------------------------------------------

                    int i, k, iPrevious;
                    double y;
                    // for calculation and adding of intersection point
                    bool addPoint = true;
                    double ix = 0;
                    double iy = 0;

                    i = j;
                    iPrevious = i;
                    // Find initial value for i = i_s, such that X[i_s - 1] <= X[j + 1] < X[i_s]
                    // it holds: i element of interval (i_s, j)
                    while (X[j + 1] < X[i - 1]) // X[j + 1] < X[i - 1] => (i - 1 > 0 && Y[i - 2] <= Y[i - 1]) (in case of lower)
                        i--;

                    // initial value for k
                    k = j + 1;
                    y = Y[i - 1]; // X[i - 1] <= X[j + 1] == X[k] < X[i] && in case of lower: y == Y[i - 1] <= Y[i] <= Y[j] == Y[j + 1] == Y[k]

                    // Find k
                    while (((lower && y < Y[k]) || (!lower && Y[k] < y)) && k + 1 < Y.Count)// y < Y[k] => k < X.Count
                    {
                        iPrevious = i;
                        k++;
                        while (X[i] < X[k] && i < j)
                            i++;
                        // it holds X[i - 1] < X[k] <= X[i], particularly X[i] != X[i - 1]
                        // linear interpolation of (x, y) = (X[k], y) on segment (i - 1, i)
                        y = (Y[i] - Y[i - 1]) / (X[i] - X[i - 1]) * (X[k] - X[i - 1]) + Y[i - 1];
                    }
                    // k located: intersection point is on segment (k - 1, k)
                    // i approximately located: intersection point is on polygonal line (iPrevoius - 1, i)
                    // Regular case
                    if (iPrevious > 1)
                        i = iPrevious - 1;
                    // Special case handling: assure, that i - 1 >= 0
                    else
                        i = iPrevious;
                    if (X[k] != X[k - 1])
                        // linear interpolation of (x, y) = (X[i], y) on segment (k - 1, k)
                        y = (Y[k] - Y[k - 1]) / (X[k] - X[k - 1]) * (X[i] - X[k - 1]) + Y[k - 1];
                    // it holds Y[i] = Y[iPrevious - 1] < Y[k - 1]
                    // Find i
                    while ((X[k] != X[k - 1] && ((lower && Y[i] < y) || (!lower && y < Y[i]))) || (X[k] == X[k - 1] && X[i] < X[k]))
                    {
                        i++;
                        if (X[k] != X[k - 1])
                            // linear interpolation of (x, y) = (X[i], y) on segment (k - 1, k)
                            y = (Y[k] - Y[k - 1]) / (X[k] - X[k - 1]) * (X[i] - X[k - 1]) + Y[k - 1];
                    }
                    // ----------------------------------------------------------------------------------------------------
                    // 2. Calculate intersection point (ix, iy) of segments (i - 1, i) and (k - 1, k)
                    // ----------------------------------------------------------------------------------------------------
                    double a1 = 0;
                    double a2 = 0;

                    // both branches vertical
                    if (X[i] == X[i - 1] && X[k] == X[k - 1])
                    {
                        // add no point; check if case occur: slopes have different signs
                        addPoint = false;
                    }
                    // case i-branch vertical
                    else if (X[i] == X[i - 1])
                    {
                        ix = X[i];
                        iy = Y[k - 1] + ((X[i] - X[k - 1]) * (Y[k] - Y[k - 1])) / (X[k] - X[k - 1]);
                    }
                    // case k-branch vertical
                    else if (X[k] == X[k - 1])
                    {
                        ix = X[k];
                        iy = Y[i - 1] + ((X[k] - X[i - 1]) * (Y[i] - Y[i - 1])) / (X[i] - X[i - 1]);
                    }
                    // common case
                    else
                    {
                        a1 = (Y[i] - Y[i - 1]) / (X[i] - X[i - 1]); // slope of segment (i - 1, i)
                        a2 = (Y[k] - Y[k - 1]) / (X[k] - X[k - 1]); // slope of segment (k - 1, k)
                        // common case: no equal slopes
                        if (a1 != a2)
                        {
                            ix = (a1 * X[i - 1] - a2 * X[k - 1] - Y[i - 1] + Y[k - 1]) / (a1 - a2);

                            if (Math.Abs(a1) > Math.Abs(a2))
                                // calculate y on segment (k - 1, k)
                                iy = a2 * (ix - X[k - 1]) + Y[k - 1];
                            else
                                // calculate y on segment (i - 1, i)
                                iy = a1 * (ix - X[i - 1]) + Y[i - 1];
                        }
                        else
                            // case equal slopes: add no point
                            addPoint = false;
                    }
                    // ----------------------------------------------------------------------------------------------------
                    // 3. Delete points i until (including) k - 1
                    // ----------------------------------------------------------------------------------------------------
                    int count = k - i;
                    X.RemoveRange(i, count);
                    Y.RemoveRange(i, count);
                    // ----------------------------------------------------------------------------------------------------
                    // 4. Add intersection point
                    // ----------------------------------------------------------------------------------------------------
                    // add intersection point, if it isn`t already there
                    if (addPoint && (X[i] != ix || Y[i] != iy))
                    {
                        X.Insert(i, ix);
                        Y.Insert(i, iy);
                    }
                    // ----------------------------------------------------------------------------------------------------
                    // 5. set j = i
                    // ----------------------------------------------------------------------------------------------------
                    j = i;
                    // ----------------------------------------------------------------------------------------------------
                    // 6. Delete points that are doubled
                    // ----------------------------------------------------------------------------------------------------
                    if (X[i - 1] == X[i] && Y[i - 1] == Y[i])
                    {
                        X.RemoveAt(i);
                        Y.RemoveAt(i);
                        j = i - 1;
                    }
                }
                j++;
            }
            #if GUI
            // Visualization
            if (visualize)
            {
                ChartControl control = new ChartControl(500, Int32.MaxValue, true);
                control.AddLine("Tube curve with loop", XLoops, YLoops, Color.FromKnownColor(KnownColor.Cyan));
                control.AddLine("Tube curve without loop", X, Y, Color.FromKnownColor(KnownColor.Red));
                Application.Run(control);
            }
            #endif
            return countLoops;
        }
コード例 #2
0
        /// <summary>
        ///  Remove points and add intersection points in case of backward order
        /// </summary>
        /// <param name="X">x values of curve</param>
        /// <param name="Y">y values of curve</param>
        /// <param name="lower">if true, algorithm for lower tube curve is used;<para>
        /// if false, algorithm for upper tube curve is used</para></param>
        /// <return>Number of loops, that are removed.</return>
        private static int removeLoop(List <double> X, List <double> Y, bool lower)
        {
            // Visualization of working of removeLoop
            bool          visualize  = false;
            List <double> XLoops     = new List <double>(X);
            List <double> YLoops     = new List <double>(Y);
            int           j          = 1;
            int           countLoops = 0;

#if GUI
            // Visualization
            if (visualize)
            {
                ChartControl chartControl = new ChartControl(600, Int32.MaxValue, true);
                chartControl.AddLine("Tube curve with loop", X, Y, Color.FromKnownColor(KnownColor.Cyan));
                Application.Run(chartControl);
            }
#endif
            while (j < X.Count - 2)
            {
                // Find backward segment (j, j + 1)
                if (X[j + 1] < X[j])
                {
                    countLoops++;

                    // ----------------------------------------------------------------------------------------------------
                    // 1. Find i,k, such that i <= j < j + 1 <= k - 1 and segment (i - 1, i) intersect segment (k - 1, k)
                    // ----------------------------------------------------------------------------------------------------

                    int    i, k, iPrevious;
                    double y;
                    // for calculation and adding of intersection point
                    bool   addPoint = true;
                    double ix       = 0;
                    double iy       = 0;
                    int    kMax;

                    i         = j;
                    iPrevious = i;
                    // Find initial value for i = i_s, such that X[i_s - 1] <= X[j + 1] < X[i_s]
                    // it holds: i element of interval (i_s, j)
                    while (X[j + 1] < X[i - 1]) // X[j + 1] < X[i - 1] => (i - 1 > 0 && Y[i - 2] <= Y[i - 1]) (in case of lower)
                    {
                        i--;
                    }

                    // j + 1 < k <= kMax
                    kMax = j + 1;
                    while (X[kMax] < X[j] && kMax < Y.Count - 1)
                    {
                        kMax++;
                    }

                    // initial value for k
                    k = j + 1;
                    y = Y[i - 1]; // X[i - 1] <= X[j + 1] == X[k] < X[i] && in case of lower: y == Y[i - 1] <= Y[i] <= Y[j] == Y[j + 1] == Y[k]

                    // Find k
                    while (((lower && y < Y[k]) || (!lower && Y[k] < y)) && k < kMax)// y < Y[k] => k < X.Count
                    {
                        iPrevious = i;
                        k++;
                        //while ((X[i] < X[k] || (X[i] == X[k] && Y[i] < Y[k])) && i < j)
                        while ((X[i] < X[k] || (lower && X[i] == X[k] && Y[i] < Y[k] && !(k + 1 < X.Count && X[k] == X[k + 1] && Y[k + 1] < Y[k])) || (!lower && X[i] == X[k] && Y[i] > Y[k] && !(k + 1 < X.Count && X[k] == X[k + 1] && Y[k + 1] > Y[k]))) && i < j)
                        {
                            i++;
                        }
                        // it holds X[i - 1] < X[k] <= X[i], particularly X[i] != X[i - 1]
                        // for i < j and X[i - 1] < X[k] it holds X[i - 1] < X[k] <= X[i], particularly X[i] != X[i - 1]
                        // linear interpolation of (x, y) = (X[k], y) on segment (i - 1, i)
                        if (X[i] - X[i - 1] != 0)
                        {
                            y = (Y[i] - Y[i - 1]) / (X[i] - X[i - 1]) * (X[k] - X[i - 1]) + Y[i - 1];
                        }
                        else
                        {
                            y = Y[i];
                        }
                    }
                    // k located: intersection point is on segment (k - 1, k)
                    // i approximately located: intersection point is on polygonal line (iPrevoius - 1, i)
                    // Regular case
                    if (iPrevious > 1)
                    {
                        i = iPrevious - 1;
                    }
                    // Special case handling: assure, that i - 1 >= 0
                    else
                    {
                        i = iPrevious;
                    }
                    if (X[k] != X[k - 1])
                    {
                        // linear interpolation of (x, y) = (X[i], y) on segment (k - 1, k)
                        y = (Y[k] - Y[k - 1]) / (X[k] - X[k - 1]) * (X[i] - X[k - 1]) + Y[k - 1];
                    }
                    // it holds Y[i] = Y[iPrevious - 1] < Y[k - 1]
                    // Find i
                    while ((X[k] != X[k - 1] && ((lower && Y[i] < y) || (!lower && y < Y[i]))) || (X[k] == X[k - 1] && X[i] < X[k]))
                    {
                        i++;
                        if (X[k] != X[k - 1])
                        {
                            // linear interpolation of (x, y) = (X[i], y) on segment (k - 1, k)
                            y = (Y[k] - Y[k - 1]) / (X[k] - X[k - 1]) * (X[i] - X[k - 1]) + Y[k - 1];
                        }
                    }
                    // ----------------------------------------------------------------------------------------------------
                    // 2. Calculate intersection point (ix, iy) of segments (i - 1, i) and (k - 1, k)
                    // ----------------------------------------------------------------------------------------------------
                    double a1 = 0;
                    double a2 = 0;

                    // both branches vertical
                    if (X[i] == X[i - 1] && X[k] == X[k - 1])
                    {
                        // add no point; check if case occur: slopes have different signs
                        addPoint = false;
                    }
                    // case i-branch vertical
                    else if (X[i] == X[i - 1])
                    {
                        ix = X[i];
                        iy = Y[k - 1] + ((X[i] - X[k - 1]) * (Y[k] - Y[k - 1])) / (X[k] - X[k - 1]);
                    }
                    // case k-branch vertical
                    else if (X[k] == X[k - 1])
                    {
                        ix = X[k];
                        iy = Y[i - 1] + ((X[k] - X[i - 1]) * (Y[i] - Y[i - 1])) / (X[i] - X[i - 1]);
                    }
                    // common case
                    else
                    {
                        a1 = (Y[i] - Y[i - 1]) / (X[i] - X[i - 1]); // slope of segment (i - 1, i)
                        a2 = (Y[k] - Y[k - 1]) / (X[k] - X[k - 1]); // slope of segment (k - 1, k)
                        // common case: no equal slopes
                        if (a1 != a2)
                        {
                            ix = (a1 * X[i - 1] - a2 * X[k - 1] - Y[i - 1] + Y[k - 1]) / (a1 - a2);

                            if (Math.Abs(a1) > Math.Abs(a2))
                            {
                                // calculate y on segment (k - 1, k)
                                iy = a2 * (ix - X[k - 1]) + Y[k - 1];
                            }
                            else
                            {
                                // calculate y on segment (i - 1, i)
                                iy = a1 * (ix - X[i - 1]) + Y[i - 1];
                            }
                        }
                        else
                        {
                            // case equal slopes: add no point
                            addPoint = false;
                        }
                    }
                    // ----------------------------------------------------------------------------------------------------
                    // 3. Delete points i until (including) k - 1
                    // ----------------------------------------------------------------------------------------------------
                    int count = k - i;
                    X.RemoveRange(i, count);
                    Y.RemoveRange(i, count);
                    // ----------------------------------------------------------------------------------------------------
                    // 4. Add intersection point
                    // ----------------------------------------------------------------------------------------------------
                    // add intersection point, if it isn`t already there
                    if (addPoint && (X[i] != ix || Y[i] != iy))
                    {
                        X.Insert(i, ix);
                        Y.Insert(i, iy);
                    }
                    // ----------------------------------------------------------------------------------------------------
                    // 5. set j = i
                    // ----------------------------------------------------------------------------------------------------
                    j = i;
                    // ----------------------------------------------------------------------------------------------------
                    // 6. Delete points that are doubled
                    // ----------------------------------------------------------------------------------------------------
                    if (X[i - 1] == X[i] && Y[i - 1] == Y[i])
                    {
                        X.RemoveAt(i);
                        Y.RemoveAt(i);
                        j = i - 1;
                    }
                }
                j++;
            }
#if GUI
            // Visualization
            if (visualize)
            {
                ChartControl control = new ChartControl(500, Int32.MaxValue, true);
                control.AddLine("Tube curve with loop", XLoops, YLoops, Color.FromKnownColor(KnownColor.Cyan));
                control.AddLine("Tube curve without loop", X, Y, Color.FromKnownColor(KnownColor.Red));
                Application.Run(control);
            }
#endif
            return(countLoops);
        }