示例#1
0
    private Envelope GetEnvelope(LinearFunction[] functions, EnvelopeKind kind)
    {
        Envelope envelope = null;

        if (functions != null && functions.Length > 0)
        {
            int firstFunctionIndex, lastFunctionIndex, functionsIterationStep;
            //While looking for upper envelope we will go from first to last function
            if (kind == EnvelopeKind.Upper)
            {
                firstFunctionIndex     = 0;
                lastFunctionIndex      = functions.Length - 1;
                functionsIterationStep = 1;
            }
            //While looking for lower envelope we will go from last to first function
            else
            {
                firstFunctionIndex     = functions.Length - 1;
                lastFunctionIndex      = 0;
                functionsIterationStep = -1;
            }

            List <LinearFunction>       lines  = new List <LinearFunction>();
            List <CartesianCoordinates> points = new List <CartesianCoordinates>();

            //We set the first line in the envelope
            LinearFunction previousLine = functions[firstFunctionIndex];
            lines.Add(previousLine);

            //And calculate "theoretical" furthest to left point
            points.Add(new CartesianCoordinates(_leftBorder, previousLine.Evaluate(_leftBorder)));

            //We will look for intersection points between the functions
            for (int i = firstFunctionIndex + functionsIterationStep; (kind == EnvelopeKind.Upper && i <= lastFunctionIndex) || (kind == EnvelopeKind.Lower && i >= lastFunctionIndex); i += functionsIterationStep)
            {
                LinearFunction currentLine = functions[i];
                //Because we have taken intercept into consideration while sorting we can skip parallel lines
                if (currentLine.Slope != previousLine.Slope)
                {
                    //We add an intersection between previous and current line to the points collection
                    points.Add(previousLine.Intersect(currentLine).Value);

                    //If the latest intersection point lies before any of the previous one, we need to update those intersections to find the actual last intersection
                    int lastIntersectionIndex = points.Count - 1;
                    while (points[lastIntersectionIndex].X < points[lastIntersectionIndex - 1].X)
                    {
                        //Calculate the intersection between current on previous line
                        points[lastIntersectionIndex - 1] = lines[lastIntersectionIndex - 2].Intersect(currentLine).Value;

                        //Remove the no longer valid intersection and line
                        points.RemoveAt(lastIntersectionIndex);
                        lines.RemoveAt(lastIntersectionIndex - 1);

                        lastIntersectionIndex--;
                    }

                    //We add current line to the lines collection
                    previousLine = currentLine;
                    lines.Add(previousLine);
                }
            }

            //We calculate "theoretical" furthest to right point
            points.Add(new CartesianCoordinates(_rightBorder, previousLine.Evaluate(_rightBorder)));

            envelope = new Envelope(lines.ToArray(), points.ToArray());
        }

        return(envelope);
    }
        public void ReturnTheSameValue(double value)
        {
            var result = linearFunction.Evaluate(value);

            Assert.Equal(result, value);
        }