Пример #1
0
        public BCurve(int degree, Vector[] controlPoints, BasisFunction basisFunction)
        {
            if (controlPoints.Length + degree + 1 != basisFunction.GetNKnots())
                throw new Exception("Number of control points + 1 + degree != n_knots");

            _mDegree = degree;
            _mControlPoints = controlPoints;
            _mBasis = basisFunction;
            _mDimension = _mControlPoints[0].VectorDimension();
        }
Пример #2
0
        public Vector Evaluate(double u)
        {
            var result = new Vector(_mDimension);

            for (var i = 0; i < _mControlPoints.Length; i++)
            {
                var temp1 = _mControlPoints[i];
                var coeff = _mBasis.Evaluate(i, _mDegree, u);

                if (TolerantUtilities.EqualWithinTol(coeff, 0.0))
                    continue;

                var temp2 = Vector.ScalarProduct(coeff, temp1);

                result = result+temp2;
            }

            return result;
        }
Пример #3
0
        private static void CentripetalMethod_calculateInterpolationParameters(
            Vector[] interpolationPoints, ref double[] interpolationParameters)
        {
            // NOTE: interpolationParameters is equal to null(ArgumentNullException)

            // The first element is always 0.0;
            var parameters = new List<double> {0.0};

            var nPoints = interpolationPoints.Length;

            // Calculate chord length:
            double[] chordLengthCache = null;
            var chordLength = CentripetalMethod_getChordLength(interpolationPoints, ref chordLengthCache);

            for (var k = 1; k < nPoints - 1; k++)
            {
                // First term:
                var firstTerm = parameters[k - 1];

                // use cache:
                var secondTerm = chordLengthCache[k - 1] / chordLength;

                // Set new parameter:
                var param = firstTerm + secondTerm;

                // Save:
                parameters.Add(param);
            }

            // last parameter is always 1.0;
            // Minus tolerance as a work around for a problem...
            parameters.Add(1.0 - new TolerantUtilities().GetTolerance());

            // Store parameters:
            interpolationParameters = parameters.ToArray();
        }
Пример #4
0
        public static void CentripetalMethod_createSplineByInterpolation(
            int degree, Vector[] interpolationPoints, ref BCurve result)
        {
            // NOTE: result is equal to null(ArgumentNullException)

            // Calculate interpolation parameters:
            double[] interpolationParameters = null;
            CentripetalMethod_calculateInterpolationParameters(interpolationPoints, ref interpolationParameters);

            // Calculate knots:
            double[] knots = null;
            CentripetalMethod_calculateKnots(degree, interpolationParameters, ref knots);

            // Create basis function:
            var basis = new BasisFunction(knots);

            // Number of control points:
            var nControlPoints = interpolationPoints.Length;

            // Create set of linearly independent equations:
            var matrixElements = new double[nControlPoints][];

            for (var i = 0; i < nControlPoints; i++)
            {
                matrixElements[i] = new double[nControlPoints];

                for (var j = 0; j < nControlPoints; j++)
                    matrixElements[i][j] = basis.Evaluate(j, degree, interpolationParameters[i]);
            }

            // Create matrix:
            var matrix = new BGeomMatrix(matrixElements);

            var dimension = interpolationPoints[0].VectorDimension();

            // Solve using Gaussian Elimination:
            var rhs = new Vector(nControlPoints);
            var controlPoints = new Vector[nControlPoints];

            for (var i = 0; i < dimension; i++)
            {
                // Fill the elements of the rhs:
                for (var j = 0; j < nControlPoints; j++)
                    rhs.Elements[j] = interpolationPoints[j].Elements[i];

                double[] gaussResult = null;

                LinearAlgebra.GaussianElimination(matrix, rhs, ref gaussResult);

                // Fill the control points
                for (var k = 0; k < nControlPoints; k++)
                {
                    if ( i == 0)
                        controlPoints[k] = new Vector(dimension);

                    controlPoints[k].Elements[i] = gaussResult[k];
                }
            }

            // Create spline:
            result = new BCurve(degree, controlPoints, basis);
        }
Пример #5
0
        private static double CentripetalMethod_getChordLength(Vector[] interpolationPoints, ref double[] cache)
        {
            // NOTE: cache is equal to null(ArgumentNullException)

            var cacheList = new List<double>();
            var length = 0.0;

            for (var i = 1; i < interpolationPoints.Length; i++)
            {
                // Q_k - Q_k-1
                var vecDiff = interpolationPoints[i] - interpolationPoints[i-1];

                // Size of this vector:
                var vecSize = vecDiff.GetLength();

                // Sqrt of this size:
                vecSize = Math.Sqrt(vecSize);

                // Store this in cache list:
                cacheList.Add(vecSize);

                // Add to length:
                length += vecSize;
            }

            cache = cacheList.ToArray();

            return length;
        }
Пример #6
0
        public static void GaussianElimination(BGeomMatrix matrix, Vector rhs, ref double[] results)
        {
            // Create augmented matrix
            var augmentedElements = new List<List<double>>();

            for (var i = 0; i < matrix.GetNRows(); i++)
            {
                augmentedElements.Add(new List<double>());

                for (var j = 0; j < matrix.GetNColumns(); j++)
                    augmentedElements[i].Add(matrix.GetElement(i, j));

                augmentedElements[i].Add(rhs.Elements[i]);
            }

            // Create new matrix:
            var augmentedMatrix = new BGeomMatrix(augmentedElements);

            // Divide first row by the first element:
            var pivot = augmentedMatrix.GetElement(0, 0);

            if (TolerantUtilities.EqualWithinTol(pivot, 0.0))
                throw new Exception("Cannot solve this type of matrix yet");

            var row1 = augmentedMatrix.GetRow(0);

            row1.ScalarProduct(1.0 / pivot);

            // Now replace:
            augmentedMatrix.ReplaceRow(0, row1);

            var nRows = augmentedMatrix.GetNRows();

            // Now enter loop
            for (var i = 1; i < nRows; i++)
            {
                for (var j = 0; j < i; j++)
                {
                    // get the jth row and multiply it with the ith row coefficient:
                    row1 = augmentedMatrix.GetRow(j);

                    // get coefficient:
                    var coefficient = augmentedMatrix.GetElement(i, j);

                    // Multiply:
                    row1.ScalarProduct(coefficient);

                    // Get the ith row:
                    var row2 = augmentedMatrix.GetRow(i);

                    // Subtract:
                    var rowSubs = row2 - row1;

                    // Make the first non-zero coeff 1.0:
                    coefficient = rowSubs.Elements[j+1];
                    rowSubs.ScalarProduct(1.0 / coefficient);

                    // Replace
                    augmentedMatrix.ReplaceRow(i, rowSubs);
                }
            }

            // Now back substitution
            var backSubs = new double[nRows];

            // Fill in the last element:
            backSubs[nRows - 1] = augmentedMatrix.GetElement(nRows-1, nRows);

            // Starting from before last, start filling up:
            for (var i = nRows - 2; i >= 0; i--)
            {
                // Get all the factors on the rhs:
                var rhsFactors = 0.0;

                for (var j = nRows - 1; j > i; j--)
                    rhsFactors += augmentedMatrix.GetElement(i, j)*backSubs[j];

                // Now subtract:
                backSubs[i] = augmentedMatrix.GetElement(i, nRows) - rhsFactors;
            }

            results = backSubs;
        }
Пример #7
0
        public void ReplaceRow(int row, Vector vec)
        {
            // Check dimensions:
            if (_mColumns != vec.VectorDimension())
                throw new Exception("wrong dimension");

            for (var i = 0; i < _mColumns; i++)
                SetElement(row, i, vec.Elements[i]);
        }
Пример #8
0
        public void Subtract(Vector v2)
        {
            // Check dimensions
            if (_nElements != v2.VectorDimension())
                throw new Exception("Wrong dimensions");

            for (var i = 0; i < _nElements; i++)
                Elements[i] = Elements[i] - v2.Elements[i];
        }
Пример #9
0
        public double DotProduct(Vector v2)
        {
            // Check dimensions
            if (_nElements != v2.VectorDimension())
                throw new Exception("Wrong dimension");

            var result = 0.0;

            for (var i = 0; i < _nElements; i++)
                result += Elements[i]*v2.Elements[i];

            return result;
        }
Пример #10
0
        public static Vector Subtract(Vector v1, Vector v2)
        {
            // Check dimensions:
            if (v1.VectorDimension() != v2.VectorDimension())
                throw new Exception("Wrong dimensions");

            var resultElements = new double[v1.VectorDimension()];

            for (var i = 0; i < v1.VectorDimension(); i++)
                resultElements[i] = v1.Elements[i] - v2.Elements[i];

            return new Vector(resultElements);
        }
Пример #11
0
        /// <summary>
        /// Scalar product double a * Vector v1
        /// </summary>
        /// <param name="a"></param>
        /// <param name="v1"></param>
        /// <returns></returns>
        public static Vector ScalarProduct(double a, Vector v1)
        {
            var resultElements = new List<double>();

            // Multiply each element of v1 with a
            for (var i = 0; i < v1.VectorDimension(); i++)
                resultElements.Add(a*v1.Elements[i]);

            return new Vector(resultElements);
        }
Пример #12
0
        private void button1_Click(object sender, EventArgs e)
        {
            var knots = new List<double>
            {
                0.0,
                0.0,
                0.0,
                1.0,
                2.0,
                3.0,
                4.0,
                4.0,
                5.0,
                5.0,
                5.0
            };

            var controlPoints = new List<Vector>
            {
                new Vector(new[] {0.0, 0.0}),
                new Vector(new[] {1.0, 1.0}),
                new Vector(new[] {2.0, 0.0}),
                new Vector(new[] {3.0, -1.0}),
                new Vector(new[] {4.0, 0.0}),
                new Vector(new[] {5.0, 1.0}),
                new Vector(new[] {6.0, 0.0}),
                new Vector(new[] {7.0, -1.0})
            };

            var basis = new BasisFunction(knots);
            var curve = new BCurve(2, controlPoints, basis);

            _sessionCurve = curve;

            curve.Evaluate(2.5);

            // Testing gaussian elimination:
            var matrixElements = new List<List<double>>
            {
                new List<double>
                {
                    1,
                    -3,
                    1
                },

                new List<double>
                {
                    2,
                    -8,
                    8
                },

                new List<double>
                {
                    -6,
                    3,
                    -15
                }
            };

            var rhs = new Vector(new double[] { 4, -2, 9 });
            var matrix = new BGeomMatrix(matrixElements);

            double[] results = null;

            LinearAlgebra.GaussianElimination(matrix, rhs, ref results);

            // make straight line with points:
            var straightLine0 = new List<Vector>();

            for (var i = 0; i < 5; i++)
                straightLine0.Add(new Vector(new[] { i, i % 2.0 }));

            // Interpolate straight line
            var straightLine1 = new BCurve();

            GeomUtils.CentripetalMethod_createSplineByInterpolation(3, straightLine0.ToArray(), ref straightLine1);

            _sessionCurve = straightLine1;
        }