Пример #1
0
        public void GetMxR(int startInd, int endInd, int channel)
        {
            // MxR -> Max Rate
            // MxR Needs the Vpp points, so we calculate those first

            // Do Vpp
            Vector2[] pointsIn    = new Vector2[endInd - startInd];
            Vector2[] pointsInRem = new Vector2[endInd - startInd];
            for (int i = 0; i < endInd - startInd; i++)
            {
                pointsIn[i]    = workingData[i + startInd, channel];
                pointsInRem[i] = workingData[i + startInd, channel];
            }

            // Get points on convex hull using Andrew's monotone chain algorithm
            int n = pointsIn.Length;
            int k = 0;
            int mid;

            Vector2[] H = new Vector2[2 * n];

            //var sortedP = pointsIn.OrderBy(p => p.X).ThenBy(p => p.Y);
            //pointsIn = sortedP.ToArray();
            Vec2Compare comp = new Vec2Compare();   // I think this is faster than the LINQ above

            Array.Sort(pointsIn, comp);

            // Lower Hull
            for (int i = 0; i < n; ++i)
            {
                while (k >= 2 && Cross(H[k - 2], H[k - 1], pointsIn[i]) <= 0)
                {
                    k--;
                }
                H[k++] = pointsIn[i];
            }
            mid = k;    // Remeber upper from lower hull
            // Upper Hull
            for (int i = n - 2, t = k + 1; i >= 0; i--)
            {
                while (k >= t && Cross(H[k - 2], H[k - 1], pointsIn[i]) <= 0)
                {
                    k--;
                }
                H[k++] = pointsIn[i];
            }
            if (k > 1)
            {
                Vector2[] trimmed = new Vector2[k - 1];
                for (int i = 0; i < k - 1; i++)
                {
                    trimmed[i] = H[i];
                }
                H = trimmed;
            }
            convexHull = new int[H.Length];
            for (int i = 0; i < H.Length; i++)
            {
                convexHull[i] = startInd + Array.IndexOf(pointsInRem, H[i]);
            }

            // Brute force the points on the convex hull (for now)
            // There are O(n) ways of doing this, but it shouldn't matter much
            Vector2 tempPoint1 = new Vector2(), tempPoint2 = new Vector2();
            double  biggestDist = -1.0;

            for (int i = 0; i < H.GetLength(0) - 1; i++)
            {
                for (int j = i + 1; j < H.GetLength(0); j++)
                {
                    double d = DistSquared(H[i], H[j]);
                    if (d > biggestDist)
                    {
                        biggestDist = d;
                        tempPoint1  = H[i];
                        tempPoint2  = H[j];
                    }
                }
            }

            measureInd1      = startInd + Array.IndexOf(pointsInRem, tempPoint1);
            measureInd2      = startInd + Array.IndexOf(pointsInRem, tempPoint2);
            measureAmplitude = Math.Sqrt(biggestDist);

            // Vpp points found, and amplitude calculated!
            // Now we can do the MxR part

            // MxR angle calculation
            int index1 = Math.Min(measureInd1, measureInd2) - startInd;
            int index2 = Math.Max(measureInd1, measureInd2) - startInd;

            const double TOL = 2.5; // This value taken from ADAPT's MxR algorithm
            int          tail = index1, bestHead = index1 + 1, bestTail = index1;
            double       angle      = GetECAngle(pointsInRem[tail], pointsInRem[index1 + 1]);
            double       lastAngle  = angle;
            double       bestLength = DistSquared(pointsInRem[tail], pointsInRem[index1 + 1]);

            for (int i = index1 + 1; i < index2; i++)
            {
                angle = GetECAngle(pointsInRem[i], pointsInRem[i + 1]);
                if (Math.Abs(angle - lastAngle) > TOL)
                {
                    if (DistSquared(pointsInRem[i], pointsInRem[tail]) > bestLength)
                    {
                        bestTail   = tail;
                        bestLength = DistSquared(pointsInRem[i], pointsInRem[tail]);
                        bestHead   = i;
                    }
                    tail = i;
                }
                lastAngle = angle;
            }
            measurementPhase = GetECAngle(pointsInRem[bestTail], pointsInRem[bestHead]);
            mxRInd1          = bestHead + startInd;
            mxRInd2          = bestTail + startInd;
            measurementType  = "MxR";
        }
Пример #2
0
        public void GetVpp(int startInd, int endInd, int channel)
        {
            Vector2[] pointsIn    = new Vector2[endInd - startInd];
            Vector2[] pointsInRem = new Vector2[endInd - startInd];
            for (int i = 0; i < endInd - startInd; i++)
            {
                pointsIn[i]    = workingData[i + startInd, channel];
                pointsInRem[i] = workingData[i + startInd, channel];
            }

            //==========
            // Fast Vpp
            //==========

            // Get points on convex hull using Andrew's monotone chain algorithm
            int n = pointsIn.Length;
            int k = 0;
            int mid;

            Vector2[] H = new Vector2[2 * n];

            //var sortedP = pointsIn.OrderBy(p => p.X).ThenBy(p => p.Y);
            //pointsIn = sortedP.ToArray();
            Vec2Compare comp = new Vec2Compare();   // I think this is faster than the LINQ above

            Array.Sort(pointsIn, comp);

            // Lower Hull
            for (int i = 0; i < n; ++i)
            {
                while (k >= 2 && Cross(H[k - 2], H[k - 1], pointsIn[i]) <= 0)
                {
                    k--;
                }
                H[k++] = pointsIn[i];
            }
            mid = k;    // Remember upper from lower hull (would be used in rotating caliper's algo.)
            // Upper Hull
            for (int i = n - 2, t = k + 1; i >= 0; i--)
            {
                while (k >= t && Cross(H[k - 2], H[k - 1], pointsIn[i]) <= 0)
                {
                    k--;
                }
                H[k++] = pointsIn[i];
            }
            if (k > 1)
            {
                Vector2[] trimmed = new Vector2[k - 1];
                for (int i = 0; i < k - 1; i++)
                {
                    trimmed[i] = H[i];
                }
                H = trimmed;
            }
            convexHull = new int[H.Length];
            for (int i = 0; i < H.Length; i++)
            {
                convexHull[i] = startInd + Array.IndexOf(pointsInRem, H[i]);
            }

            // Brute force the points on the convex hull (for now)
            // There are O(n) ways of doing this, but it shouldn't matter much
            Vector2 tempPoint1 = new Vector2(), tempPoint2 = new Vector2();
            double  biggestDist = -1.0;

            for (int i = 0; i < H.GetLength(0) - 1; i++)
            {
                for (int j = i + 1; j < H.GetLength(0); j++)
                {
                    double d = DistSquared(H[i], H[j]);
                    if (d > biggestDist)
                    {
                        biggestDist = d;
                        tempPoint1  = H[i];
                        tempPoint2  = H[j];
                    }
                }
            }
            //measurePoint1 = tempPoint1;
            //measurePoint2 = tempPoint2;
            measureInd1      = startInd + Array.IndexOf(pointsInRem, tempPoint1);
            measureInd2      = startInd + Array.IndexOf(pointsInRem, tempPoint2);
            measureAmplitude = Math.Sqrt(biggestDist);
            if (measureInd1 < measureInd2)
            {
                measurementPhase = GetECAngle(tempPoint1, tempPoint2);
            }
            else
            {
                measurementPhase = GetECAngle(tempPoint2, tempPoint1);
            }
            measurementType = "Vpp";
            // Find the maximum distance with the rotating calipers algorithm
            //double longest = 0;
            //int index1 = -1, index2 = -1;
            //int bot = 0;
            //int top = H.Length - 1;
            //
            //// First set of points
            //double ds = DistSquared(H[bot], H[top]);
            //longest = ds;
            //index1 = bot;
            //index2 = top;
            //
            //while (bot < mid || top >= mid)
            //{
            //    if (bot == mid)
            //        top--;
            //    else if (top == mid + 1)
            //        bot++;
            //    else if (
            //        (H[bot + 1].Y - H[bot].Y) * (H[top].X - H[top - 1].X) >
            //        (H[bot + 1].X - H[bot].X) * (H[top].Y - H[top - 1].Y))
            //        bot++;
            //    else
            //        top--;
            //
            //    ds = DistSquared(H[bot], H[top]);
            //    if (ds > longest)
            //    {
            //        longest = ds;
            //        index1 = bot;
            //        index2 = top;
            //    }
            //}

            //measurePoint1 = H[index1];
            //measurePoint2 = H[index2];
            //return new MeasurementResult {
            //    MeasurementType = "Vpp",
            //    Amplitude = longest
            //};
        }