public Rational_BSpline_Surface(double[] Parameters, TransformationMatrix _R = null, int _ParameterId = -1) { R = _R; ParameterId = _ParameterId; K1 = (int)Parameters[1]; K2 = (int)Parameters[2]; M1 = (int)Parameters[3]; M2 = (int)Parameters[4]; PROP1 = (int)Parameters[5]; PROP2 = (int)Parameters[6]; PROP3 = (int)Parameters[7]; PROP4 = (int)Parameters[8]; PROP5 = (int)Parameters[9]; int N1 = 1 + K1 - M1; int N2 = 1 + K2 - M2; int A = N1 + 2 * M1; int B = N2 + 2 * M2; int C = (1 + K1) * (1 + K2); S = new double[N1 + 2 * M1 + 1]; Array.Copy(Parameters, 10, S, 0, S.Length); T = new double[N2 + 2 * M2 + 1]; Array.Copy(Parameters, 11 + A, T, 0, T.Length); W = new double[(K1 + 1) * (K2 + 1)]; X = new double[W.Length]; Y = new double[X.Length]; Z = new double[Y.Length]; Array.Copy(Parameters, 12 + A + B, W, 0, W.Length); var PTS = new double[3 * X.Length]; Array.Copy(Parameters, 12 + A + B + C, PTS, 0, PTS.Length); for (int i = 0; i < X.Length; i++) { X[i] = PTS[3 * i]; Y[i] = PTS[3 * i + 1]; Z[i] = PTS[3 * i + 2]; } U0 = Parameters[12 + A + B + 4 * C]; U1 = Parameters[13 + A + B + 4 * C]; V0 = Parameters[14 + A + B + 4 * C]; V1 = Parameters[15 + A + B + 4 * C]; Bi = new BSpline_Basis_Function(S, M1 + 1); Bj = new BSpline_Basis_Function(T, M2 + 1); }
static private void TestBasisFunction() { // Unit Test Case Taken from Example 3.3 pp 58 An Introduction to NURBS by Rogers // Calculate the five third order basis functions for the following knot vector // [X] = [0 0 0 1 1 3 3 3] var KnotVector1 = new double[] { 0, 0, 0, 1, 1, 3, 3, 3 }; var N = new BSpline_Basis_Function(KnotVector1, 3); var TestVals = new double[] { 0, 0.5, 1, 2, 2.9 }; for (int i = 0; i < TestVals.Length; i++) { if (TestVals[i] >= 0 && TestVals[i] < 1) { Approx_Assert(N.Polys[0].Evaluate(TestVals[i]), Math.Pow(1.0 - TestVals[i], 2)); Approx_Assert(N.Polys[1].Evaluate(TestVals[i]), 2.0 * TestVals[i] * (1.0 - TestVals[i])); Approx_Assert(N.Polys[2].Evaluate(TestVals[i]), TestVals[i] * TestVals[i]); Approx_Assert(N.Polys[3].Evaluate(TestVals[i]), 0); Approx_Assert(N.Polys[4].Evaluate(TestVals[i]), 0); } else if (TestVals[i] >= 1 && TestVals[i] < 3) { Approx_Assert(N.Polys[0].Evaluate(TestVals[i]), 0); Approx_Assert(N.Polys[1].Evaluate(TestVals[i]), 0); Approx_Assert(N.Polys[2].Evaluate(TestVals[i]), (Math.Pow(3.0 - TestVals[i], 2) / 4.0)); Approx_Assert(N.Polys[3].Evaluate(TestVals[i]), ((3 - TestVals[i]) * (TestVals[i] - 1.0) / 2.0)); Approx_Assert(N.Polys[4].Evaluate(TestVals[i]), (Math.Pow(TestVals[i] - 1.0, 2) / 4.0)); } } // we must also do checksums to see that they add up to 1 for (int i = 0; i < TestVals.Length; i++) { double CheckSum = 0; for (int j = 0; j < 5; j++) { CheckSum += N.Polys[j].Evaluate(TestVals[i]); } Approx_Assert(CheckSum, 1.0); } }
public Rational_BSpline_Curve(double[] Parameters, TransformationMatrix _R = null, int _ParameterId = -1) { R = _R; ParameterId = _ParameterId; K = (int)Parameters[1]; M = (int)Parameters[2]; PROP1 = (int)Parameters[3]; PROP2 = (int)Parameters[4]; PROP3 = (int)Parameters[5]; PROP4 = (int)Parameters[6]; int N = 1 + K - M; int A = N + 2 * M; T = new double[A + 1]; Array.Copy(Parameters, 7, T, 0, T.Length); W = new double[K + 1]; Array.Copy(Parameters, 8 + A, W, 0, W.Length); var PTS = new double[(K + 1) * 3]; Array.Copy(Parameters, 8 + A + K, PTS, 0, PTS.Length); X = new double[K + 1]; Y = new double[K + 1]; Z = new double[K + 1]; int id = 0; for (int i = 0; i < PTS.Length; i += 3) { X[id] = PTS[i]; Y[id] = PTS[i + 1]; Z[id] = PTS[i + 2]; id++; } V0 = Parameters[12 + A + 4 * K]; V1 = Parameters[13 + A + 4 * K]; XNORM = Parameters[14 + A + 4 * K]; YNORM = Parameters[15 + A + 4 * K]; ZNORM = Parameters[16 + A + 4 * K]; // using the Cox-de Boor formula to calculate the basis functions B = new BSpline_Basis_Function(T, M + 1); }