/// <summary> /// Populates matrix by applying basis function to control points and filling a matrix [B 0; 0 B]; /// </summary> /// <param name="ControlPoints"></param> /// <param name="BasisFunction"></param> /// <returns></returns> public static double[,] CreateBetaMatrixWithLinear(GridVector2[] ControlPoints, BasisFunctionDelegate BasisFunction) { if (ControlPoints == null) throw new ArgumentNullException(); int NumPts = ControlPoints.Length; double[,] BetaMatrix = new double[NumPts+3, NumPts+3]; for (int iRow = 3; iRow < NumPts + 3; iRow++) { int iPointA = iRow - 3; for (int iCol = iPointA+1; iCol < NumPts; iCol++) { int iPointB = iCol; double dist = GridVector2.Distance(ControlPoints[iPointA], ControlPoints[iPointB]); double value = BasisFunction(dist); BetaMatrix[iRow, iCol] = value; BetaMatrix[iCol+3, iRow-3] = value; } BetaMatrix[iRow, NumPts] = ControlPoints[iPointA].Y; BetaMatrix[iRow, NumPts + 1] = ControlPoints[iPointA].X; BetaMatrix[iRow, NumPts + 2] = 1; } for (int iCol = 0; iCol < NumPts; iCol++) { BetaMatrix[0, iCol] = ControlPoints[iCol].X; BetaMatrix[1, iCol] = ControlPoints[iCol].Y; BetaMatrix[2, iCol] = 1; } /* int BetaMatrixDim = NumPts+3; double[,] FinalBetaMatrix = new double[BetaMatrixDim * 2, BetaMatrixDim * 2]; for(int iRow = 0; iRow < BetaMatrixDim;iRow++) { Array.Copy(BetaMatrix, iRow * BetaMatrixDim, FinalBetaMatrix, (iRow * BetaMatrixDim * 2), BetaMatrixDim); Array.Copy(BetaMatrix, iRow * BetaMatrixDim, FinalBetaMatrix, ((iRow + BetaMatrixDim) * BetaMatrixDim * 2)+ BetaMatrixDim, BetaMatrixDim); } return FinalBetaMatrix; */ return BetaMatrix; }
public static GridVector2 Transform(GridVector2 Point, double[] Weights, GridVector2[] ControlPoints, BasisFunctionDelegate BasisFunction) { if (ControlPoints == null || Weights == null || BasisFunction == null) throw new ArgumentNullException(); int nPoints = ControlPoints.Length; double[] distances = new double[nPoints]; double[] functionValues = new double[nPoints]; double WeightSumX = 0; double WeightSumY = 0; for (int i = 0; i < distances.Length; i++) { double dist = GridVector2.Distance(ControlPoints[i], Point); double funcVal = BasisFunction(dist); distances[i] = dist; functionValues[i] = funcVal; WeightSumX = WeightSumX + (Weights[i] * funcVal); WeightSumY = WeightSumY + (Weights[i + 3 + nPoints] * funcVal); } double X = WeightSumX + (Point.Y * Weights[nPoints]) + (Point.X * Weights[nPoints + 1]) + Weights[nPoints + 2]; double Y = WeightSumY + (Point.Y * Weights[nPoints + 3 + nPoints]) + (Point.X * Weights[nPoints + nPoints + 3 + 1]) + Weights[nPoints + nPoints + 3 + 2]; return new GridVector2(X, Y); }
public static double[] CalculateRBFWeights(GridVector2[] MappedPoints, GridVector2[] ControlPoints, BasisFunctionDelegate BasisFunction) { if (MappedPoints == null || ControlPoints == null) throw new ArgumentNullException(); Debug.Assert(MappedPoints.Length == ControlPoints.Length); double[,] BetaMatrix = CreateBetaMatrixWithLinear(MappedPoints, BasisFunction); double[] SolutionMatrix_X = CreateSolutionMatrix_X_WithLinear(ControlPoints); double[] SolutionMatrix_Y = CreateSolutionMatrix_Y_WithLinear(ControlPoints); double[] WeightsX = GridMatrix.LinSolve(BetaMatrix, SolutionMatrix_X); double[] WeightsY = GridMatrix.LinSolve(BetaMatrix, SolutionMatrix_Y); double[] Weights = new double[WeightsX.Length + WeightsY.Length]; Array.Copy(WeightsX, Weights, WeightsX.Length); Array.Copy(WeightsY, 0, Weights, WeightsX.Length, WeightsY.Length); return Weights; }