protected virtual void FillXDerivations(KnotMatrix values)
 {
     for (var j = 0; j < values.Columns; j++)
     {
         FillXDerivations(j, values);
     }
 }
 private static void OriginalKnots(KnotMatrix newKnots,
     KnotMatrix oldKnots)
 {
     for (var i = 0; i < oldKnots.Rows; i++)
     {
         for (var j = 0; j < oldKnots.Columns; j++)
         {
             newKnots[2*i, 2*j] = oldKnots[i, j];
         }
     }
 }
            public override KnotMatrix GenerateKnots(
                SurfaceDimension uDimension, SurfaceDimension vDimension)
            {
                var afvOld = _baseGenerator.GenerateKnots(uDimension/2,
                    vDimension/2);

                var uCountNew = uDimension.KnotCount;
                var vCountNew = vDimension.KnotCount;
                var afvNew = new KnotMatrix(uCountNew, vCountNew);

                FillNewKnots(afvNew, afvOld);

                return afvNew;
            }
        protected virtual void FillXYDerivations(int columnIndex,
            KnotMatrix values,
            double[] lowerDiagonal = null, double[] mainDiagonal = null,
            double[] upperDiagonal = null)
        {
            var unknownsCount = values.Rows - 2;
            if (unknownsCount == 0) return;
            Action<int, double> dset =
                (idx, value) => values[idx, columnIndex].Dxy = value;
            Func<int, double> rget = idx => values[idx, columnIndex].Dy;
            var h = values[1, 0].X - values[0, 0].X;
            var dlast = values[values.Rows - 1, columnIndex].Dxy;
            var dfirst = values[0, columnIndex].Dxy;

            SolveTridiagonal(rget, h, dfirst, dlast, unknownsCount, dset,
                lowerDiagonal, mainDiagonal, upperDiagonal);
        }
 protected override void FillXYDerivations(KnotMatrix values)
 {
     base.FillXYDerivations(0, values,
         LowerDiagonal(values.Rows - 2), MainDiagonal(values.Rows - 2),
         UpperDiagonal(values.Rows - 2));
     base.FillXYDerivations(values.Columns - 1, values,
         LowerDiagonal(values.Rows - 2), MainDiagonal(values.Rows - 2),
         UpperDiagonal(values.Rows - 2));
     base.FillYXDerivations(0, values,
         LowerDiagonal(values.Columns - 2),
         MainDiagonal(values.Columns - 2),
         UpperDiagonal(values.Columns - 2));
     base.FillYXDerivations(values.Rows - 1, values,
         LowerDiagonal(values.Columns - 2),
         MainDiagonal(values.Columns - 2),
         UpperDiagonal(values.Columns - 2));
 }
Ejemplo n.º 6
0
        internal IEnumerable<ISurface> CreateMesh(KnotMatrix knots)
        {
            var uCount_min_1 = knots.Rows - 1;
            var vCount_min_1 = knots.Columns - 1;

            var segments = new List<ISurface>(uCount_min_1*vCount_min_1);

            for (var i = 0; i < uCount_min_1; i++)
            {
                for (var j = 0; j < vCount_min_1; j++)
                {
                    var segment = CreateSegment(i, j, knots);
                    segments.Add(segment);
                }
            }

            return segments;
        }
 protected override void FillXDerivations(KnotMatrix values)
 {
     var h = values[1, 0].X - values[0, 0].X;
     var oneDivH = 1/h;
     var threeDiv4H = 0.75*oneDivH;
     for (var j = 0; j < values.Columns; j++)
     {
         FillXDerivations(j, values);
         for (var i = 1; i < values.Rows - 1; i += 2)
         {
             values[i, j].Dx = threeDiv4H
                               *(values[i + 1, j].Z - values[i - 1, j].Z)
                               - 0.25
                               *(values[i + 1, j].Dx
                                 + values[i - 1, j].Dx);
         }
     }
 }
        public override KnotMatrix GenerateKnots(SurfaceDimension uDimension,
            SurfaceDimension vDimension)
        {
            if (uDimension.KnotCount < 4
                || vDimension.KnotCount < 4)
            {
                return
                    new DirectKnotsGenerator(Function).GenerateKnots(
                        uDimension, vDimension);
            }

            var values = new KnotMatrix(uDimension.KnotCount,
                vDimension.KnotCount);
            InitializeKnots(uDimension, vDimension, values);

            FillXDerivations(values);
            FillXYDerivations(values);
            FillYDerivations(values);
            FillYXDerivations(values);

            return values;
        }
        protected override void FillYDerivations(KnotMatrix values)
        {
            var h = values[0, 1].Y - values[0, 0].Y;
            var oneDivH = 1/h;
            var threeDiv4H = 0.75*oneDivH;
            for (var i = 0; i < values.Rows; i++)
            {
                FillYDerivations(i, values);
                //for (var j = 1; j < values.Columns - 1; j += 2)
                //{
                //    values[i, j].Dy = threeDiv4H * (values[i, j + 1].Z - values[i, j - 1].Z)
                //                      - 0.25 * (values[i, j + 1].Dy + values[i, j - 1].Dy);
                //}
            }

            for (var i = 0; i < values.Rows; i++)
            {
                for (var j = 1; j < values.Columns - 1; j += 2)
                {
                    values[i, j].Dy = threeDiv4H
                                      *(values[i, j + 1].Z - values[i, j - 1].Z)
                                      - 0.25
                                      *(values[i, j + 1].Dy
                                        + values[i, j - 1].Dy);
                }
            }
        }
using System;
using HermiteInterpolation.MathFunctions;
using HermiteInterpolation.Numerics;

using HermiteInterpolation.SplineKnots;
using HermiteInterpolation.Utils;

namespace HermiteInterpolation.Shapes.SplineInterpolation
{
    public class BiquarticHermiteSurface : BicubicHermiteSurface
    {
        private class BiquarticKnotsGenerator : KnotsGenerator
        {
            private readonly KnotsGenerator _baseGenerator;

            public BiquarticKnotsGenerator(KnotsGenerator baseGenerator)
                : base(baseGenerator.Function)
            {
                _baseGenerator = baseGenerator;
            }

            public override KnotMatrix GenerateKnots(SurfaceDimension uDimension, SurfaceDimension vDimension)
            {
                var afvOld = _baseGenerator.GenerateKnots(uDimension/2, vDimension/2);
                
                var uCountNew = uDimension.KnotCount;
                var vCountNew = vDimension.KnotCount;
                var afvNew = new KnotMatrix(uCountNew, vCountNew);

                FillNewKnots(afvNew, afvOld);

                return afvNew;
            }
      
            private void FillNewKnots(KnotMatrix newKnots,
                KnotMatrix oldKnots)
            {
                // z, dx, dy, dxy initialization
                OriginalKnots(newKnots, oldKnots);
                // z, dx, deltay, deltaxy
                VerticalKnots(newKnots);
                // z, Dx, dy, Dxy
                HorizontalKnots(newKnots);
                // z, Dx, deltay, deltaxy
                InnerKnots(newKnots);
            }

            private void InnerKnots(KnotMatrix newKnots)
            {
                for (int i = 1; i < newKnots.Rows; i += 2)
                {
                    for (int j = 1; j < newKnots.Columns; j += 2)
                    {
                        var u0v0 = newKnots[i - 1,j - 1];
                        var u1v0 = newKnots[i,j - 1];
                        var u2v0 = newKnots[i + 1,j - 1];

                        var u0v1 = newKnots[i - 1,j];
                        var u1v1 = new Knot();
                        var u2v1 = newKnots[i + 1,j];

                        var u0v2 = newKnots[i - 1,j + 1];
                        var u1v2 = newKnots[i,j + 1];
                        var u2v2 = newKnots[i + 1,j + 1];

                        var hx = Math.Abs(u2v0.X - u0v0.X) / 2;
                        var hx4 = hx * 4;
                        var hy = Math.Abs(u0v2.Y - u0v0.Y) / 2;
                        var hy4 = hy * 4;
                        var x = u0v1.X + hx;
                        var y = u1v0.Y + hy;

                        u1v1.X = x;
                        u1v1.Y = y;
                        u1v1.Z = Function.Z(x, y);
                        u1v1.Dx = -(3 * (u0v1.Z - u2v1.Z) + hx * (u0v1.Dx + u2v1.Dx)) /
                                 hx4;
                        u1v1.Dy = -(3 * (u1v0.Z - u1v2.Z) + hx * (u1v0.Dx + u1v2.Dx)) /
                                  hy4;
                        u1v1.Dxy = (u0v0.Dxy + u2v0.Dxy + u0v2.Dxy + u2v2.Dxy +
                                    (3 *
                                     ((u0v0.Dy - u2v0.Dy + u0v2.Dy - u2v2.Dy) / hx +
                                      (u0v0.Dx + u2v0.Dx - u0v2.Dx - u2v2.Dx) / hy +
                                      (3 * (u0v0.Z - u2v0.Z - u0v2.Z + u2v2.Z)) / (hx * hy)))) /
                                   16;
                        newKnots[i,j] = u1v1;
                    }
                }
            }

            private void HorizontalKnots(KnotMatrix newKnots)
            {
                for (int i = 1; i < newKnots.Rows; i += 2)
                {
                    for (int j = 0; j < newKnots.Columns; j += 2)
                    {

                        var u0 = newKnots[i - 1,j];
                        var u1 = new Knot();
                        // finished
                        var u2 = newKnots[i + 1,j];

                        var hx = Math.Abs(u2.X - u0.X) / 2;
                        var hx4 = hx * 4;
                        var x = u0.X + hx;
                        var y = u0.Y;

                        u1.X = x;
                        u1.Y = y;
                        u1.Z = Function.Z(x, y);

                        u1.Dy = Function.Dy(x, y);
                        u1.Dx = -(3 * (u0.Z - u2.Z) + hx * (u0.Dx + u2.Dx)) /
                                hx4;
                        u1.Dxy = -(3 * (u0.Dy - u2.Dy) + hx * (u0.Dxy + u2.Dxy)) /
                                 hx4;
                        // finished
                        newKnots[i,j] = u1;
                    }
                }
            }

            private void VerticalKnots(KnotMatrix newKnots)
            {

                for (int i = 0; i < newKnots.Rows; i += 2)
                {
                    for (int j = 1; j < newKnots.Columns; j += 2)
                    {

                        var v0 = newKnots[i,j - 1];
                        var v1 = new Knot();
                        // finished
                        var v2 = newKnots[i,j + 1];

                        var hy = Math.Abs(v2.Y - v0.Y) / 2;
                        var hy4 = hy * 4;
                        var x = v0.X;
                        var y = v0.Y + hy;

                        v1.X = x;
                        v1.Y = y;
                        v1.Z = Function.Z(x, y);
                        v1.Dx = Function.Dx(x, y);
                        v1.Dy = -(3 * (v0.Z - v2.Z) + hy * (v0.Dy + v2.Dy)) /
                                hy4;
                        v1.Dxy = -(3 * (v0.Dx - v2.Dx) + hy * (v0.Dxy + v2.Dxy)) /
                                 hy4;
                        // finished
                        newKnots[i,j] = v1;
                    }
                }
            }

            private static void OriginalKnots(KnotMatrix newKnots, KnotMatrix oldKnots)
            {
                for (var i = 0; i < oldKnots.Rows; i++)
                {
                    for (var j = 0; j < oldKnots.Columns; j++)
                    {
                        newKnots[2 * i,2 * j] = oldKnots[i,j];
                    }
                }
            }
        }


        public BiquarticHermiteSurface(SurfaceDimension uDimension, SurfaceDimension vDimension, MathExpression mathExpression, Derivation derivation = Derivation.Zero) : this(uDimension, vDimension, InterpolativeMathFunction.FromExpression(mathExpression), derivation)
        {
        }

        public BiquarticHermiteSurface(SurfaceDimension uDimension, SurfaceDimension vDimension, InterpolativeMathFunction interpolativeMathFunction, Derivation derivation = Derivation.Zero) : this(uDimension, vDimension, new  DirectKnotsGenerator(interpolativeMathFunction), derivation)
        {
        }

        public BiquarticHermiteSurface(SurfaceDimension uDimension, SurfaceDimension vDimension, KnotsGenerator knotsGenerator, Derivation derivation = Derivation.Zero) : base(uDimension, vDimension, new BiquarticKnotsGenerator(knotsGenerator), derivation)
        {
        }
    }
}
            private void VerticalKnots(KnotMatrix newKnots)
            {
                for (var i = 0; i < newKnots.Rows; i += 2)
                {
                    for (var j = 1; j < newKnots.Columns; j += 2)
                    {
                        var v0 = newKnots[i, j - 1];
                        var v1 = new Knot();
                        // finished
                        var v2 = newKnots[i, j + 1];

                        var hy = Math.Abs(v2.Y - v0.Y)/2;
                        var hy4 = hy*4;
                        var x = v0.X;
                        var y = v0.Y + hy;

                        v1.X = x;
                        v1.Y = y;
                        v1.Z = Function.Z(x, y);
                        v1.Dx = Function.Dx(x, y);
                        v1.Dy = -(3*(v0.Z - v2.Z) + hy*(v0.Dy + v2.Dy))/
                                hy4;
                        v1.Dxy = -(3*(v0.Dx - v2.Dx) + hy*(v0.Dxy + v2.Dxy))/
                                 hy4;
                        // finished
                        newKnots[i, j] = v1;
                    }
                }
            }
Ejemplo n.º 12
0
 protected virtual void FillXYDerivations(KnotMatrix values)
 {
     FillXYDerivations(0, values);
     FillXYDerivations(values.Columns - 1, values);
 }
 private void FillNewKnots(KnotMatrix newKnots,
     KnotMatrix oldKnots)
 {
     // z, dx, dy, dxy initialization
     OriginalKnots(newKnots, oldKnots);
     // z, dx, deltay, deltaxy
     VerticalKnots(newKnots);
     // z, Dx, dy, Dxy
     HorizontalKnots(newKnots);
     // z, Dx, deltay, deltaxy
     InnerKnots(newKnots);
 }
Ejemplo n.º 14
0
        protected virtual void InitializeKnots(SurfaceDimension uDimension,
            SurfaceDimension vDimension, KnotMatrix values)
        {
            var uSize = Math.Abs(uDimension.Max - uDimension.Min)
                        /(uDimension.KnotCount - 1);
            var vSize = Math.Abs(vDimension.Max - vDimension.Min)
                        /(vDimension.KnotCount - 1);
            var u = uDimension.Min;

            for (var i = 0; i < uDimension.KnotCount; i++, u += uSize)
            {
                var v = vDimension.Min;
                for (var j = 0; j < vDimension.KnotCount; j++, v += vSize)
                {
                    var z = Function.Z.SafeCall(u, v);
                    values[i, j] = new Knot(u, v, z);
                }
            }
            // Init Dx
            var uKnotCountMin1 = uDimension.KnotCount - 1;
            for (var j = 0; j < vDimension.KnotCount; j++)
            {
                values[0, j].Dx = Function.Dx.SafeCall(values[0, j].X,
                    values[0, j].Y);
                values[uKnotCountMin1, j].Dx =
                    Function.Dx.SafeCall(values[uKnotCountMin1, j].X,
                        values[uKnotCountMin1, j].Y);
            }
            // Init Dy
            var vKnotCountMin1 = vDimension.KnotCount - 1;
            for (var i = 0; i < uDimension.KnotCount; i++)
            {
                values[i, 0].Dy = Function.Dy.SafeCall(values[i, 0].X,
                    values[i, 0].Y);
                values[i, vKnotCountMin1].Dy =
                    Function.Dy.SafeCall(values[i, vKnotCountMin1].X,
                        values[i, vKnotCountMin1].Y);
            }
            // Init Dxy
            values[0, 0].Dxy = Function.Dxy.SafeCall(values[0, 0].X,
                values[0, 0].Y);
            values[uKnotCountMin1, 0].Dxy =
                Function.Dxy.SafeCall(values[uKnotCountMin1, 0].X,
                    values[uKnotCountMin1, 0].Y);
            values[0, vKnotCountMin1].Dxy =
                Function.Dxy.SafeCall(values[0, vKnotCountMin1].X,
                    values[0, vKnotCountMin1].Y);
            values[uKnotCountMin1, vKnotCountMin1].Dxy =
                Function.Dxy.SafeCall(values[uKnotCountMin1, vKnotCountMin1].X,
                    values[uKnotCountMin1, vKnotCountMin1].Y);
        }
Ejemplo n.º 15
0
        protected virtual void FillYXDerivations(int rowIndex, KnotMatrix values,
            double[] lowerDiagonal = null, double[] mainDiagonal = null,
            double[] upperDiagonal = null)
        {
            var unknownsCount = values.Columns - 2;
            if (unknownsCount == 0) return;
            Action<int, double> dset =
                (idx, value) => values[rowIndex, idx].Dxy = value;
            Func<int, double> rget = idx => values[rowIndex, idx].Dx;
            var h = values[0, 1].Y - values[0, 0].Y;
            var dfirst = values[rowIndex, 0].Dxy;
            var dlast = values[rowIndex, values.Columns - 1].Dxy;

            SolveTridiagonal(rget, h, dfirst, dlast, unknownsCount, dset,
                lowerDiagonal, mainDiagonal, upperDiagonal);
        }
Ejemplo n.º 16
0
 protected virtual void FillYXDerivations(KnotMatrix values)
 {
     for (var i = 0; i < values.Rows; i++)
     {
         FillYXDerivations(i, values);
     }
 }
            private void InnerKnots(KnotMatrix newKnots)
            {
                for (var i = 1; i < newKnots.Rows; i += 2)
                {
                    for (var j = 1; j < newKnots.Columns; j += 2)
                    {
                        var u0v0 = newKnots[i - 1, j - 1];
                        var u1v0 = newKnots[i, j - 1];
                        var u2v0 = newKnots[i + 1, j - 1];

                        var u0v1 = newKnots[i - 1, j];
                        var u1v1 = new Knot();
                        var u2v1 = newKnots[i + 1, j];

                        var u0v2 = newKnots[i - 1, j + 1];
                        var u1v2 = newKnots[i, j + 1];
                        var u2v2 = newKnots[i + 1, j + 1];

                        var hx = Math.Abs(u2v0.X - u0v0.X)/2;
                        var hx4 = hx*4;
                        var hy = Math.Abs(u0v2.Y - u0v0.Y)/2;
                        var hy4 = hy*4;
                        var x = u0v1.X + hx;
                        var y = u1v0.Y + hy;

                        u1v1.X = x;
                        u1v1.Y = y;
                        u1v1.Z = Function.Z(x, y);
                        u1v1.Dx =
                            -(3*(u0v1.Z - u2v1.Z) + hx*(u0v1.Dx + u2v1.Dx))/
                            hx4;
                        u1v1.Dy =
                            -(3*(u1v0.Z - u1v2.Z) + hx*(u1v0.Dx + u1v2.Dx))/
                            hy4;
                        u1v1.Dxy = (u0v0.Dxy + u2v0.Dxy + u0v2.Dxy + u2v2.Dxy +
                                    (3*
                                     ((u0v0.Dy - u2v0.Dy + u0v2.Dy - u2v2.Dy)/hx
                                      +
                                      (u0v0.Dx + u2v0.Dx - u0v2.Dx - u2v2.Dx)/hy
                                      +
                                      (3*(u0v0.Z - u2v0.Z - u0v2.Z + u2v2.Z))
                                      /(hx*hy))))/
                                   16;
                        newKnots[i, j] = u1v1;
                    }
                }
            }
Ejemplo n.º 18
0
 protected abstract ISurface CreateSegment(int uIdx, int vIdx,
     KnotMatrix knots);
        private double[] RightSideCross(KnotMatrix knots, int i, double dfirst,
            double dlast,
            int unknownsCount)
        {
            var even = unknownsCount%2 == 0;
            var equationsCount = even ? unknownsCount/2 - 1 : unknownsCount/2;
            var eta = even ? -4 : 1;
            var rs = new double[equationsCount];
            var oneDiv7 = 1/7;
            var hx = knots[1, 0].X - knots[0, 0].X;
            var hy = knots[0, 1].Y - knots[0, 0].Y;
            var oneDivHx = 1d/hx;
            var oneDivHy = 1d/hy;
            var threeDivHx = 3/hx;
            var threeDivHy = 3/hy;
            var threeDiv7hx = oneDiv7*threeDivHx;
            var threeDiv7hy = oneDiv7*threeDivHy;
            var threeDiv7hxhy = threeDiv7hy/hy;

            var columns = knots.Columns;

            var iMin1 = i - 1;
            var iMin2 = i - 2;

            for (int k = 0, j = 4; k < equationsCount - 1; k++, j += 2)
            {
                rs[k] = oneDiv7
                        *(knots[iMin2, j + 2].Dxy + knots[iMin2, j - 2].Dxy)
                        - 2*knots[iMin1, j].Dxy
                        + threeDiv7hx
                        *(knots[iMin1, j + 2].Dy + knots[iMin1, j - 2].Dy) +
                        threeDiv7hy
                        *(-knots[iMin2, j + 2].X + knots[iMin2, j - 2].X)
                        + 3*threeDivHx*(knots[i, j + 2].Dy + knots[i, j - 2].Dy)
                        +
                        3*threeDiv7hxhy
                        *(-knots[iMin2, j + 2].Z + knots[iMin2, j - 2].Z)
                        + 4*threeDiv7hx
                        *(-knots[iMin1, j + 2].Dy - knots[iMin1, j - 2].Dy) +
                        4*threeDiv7hy
                        *(knots[iMin2, j + 1].X - knots[iMin2, j - 1].X)
                        + threeDiv7hy*(knots[i, j + 2].Dx + knots[i, j - 2].Dx)
                        +
                        9*threeDiv7hxhy*(-knots[i, j + 2].Z + knots[i, j - 2].Z)
                        -
                        12*threeDiv7hxhy*
                        (knots[iMin1, j + 2].Z - knots[iMin1, j - 2].Z
                         + knots[iMin2, j + 1].Z - knots[iMin2, j - 1].Z)
                        - 6*oneDivHx*knots[iMin2, j].Dy
                        + 12*oneDivHy*(knots[i, j + 1].Dx + knots[i, j - 1].Dx)
                        +
                        36*threeDiv7hxhy*(knots[i, j + 1].Z + knots[i, j - 1].Z)
                        - 18*oneDivHx*knots[i, j].Dy
                        + 48*threeDiv7hxhy
                        *(-knots[iMin1, j + 1].Z + knots[iMin1, j - 1].Z) +
                        24*oneDivHx*knots[iMin1, j].Z;
            }
            rs[0] -= dfirst;
            rs[equationsCount - 1] = oneDiv7
                                     *(knots[iMin2, columns - 1].Dxy
                                       + knots[iMin2, columns - 5].Dxy) -
                                     2*knots[iMin1, columns - 3].Dxy
                                     + threeDiv7hx
                                     *(knots[iMin1, columns - 1].Dy
                                       + knots[iMin1, columns - 5].Dy) +
                                     threeDiv7hy
                                     *(-knots[iMin2, columns - 1].X
                                       + knots[iMin2, columns - 5].X)
                                     + 3*threeDivHx
                                     *(knots[i, columns - 1].Dy
                                       + knots[i, columns - 5].Dy) +
                                     3*threeDiv7hxhy
                                     *(-knots[iMin2, columns - 1].Z
                                       + knots[iMin2, columns - 5].Z)
                                     +
                                     4*threeDiv7hx
                                     *(-knots[iMin1, columns - 1].Dy
                                       - knots[iMin1, columns - 5].Dy) +
                                     4*threeDiv7hy
                                     *(knots[iMin2, columns - 2].X
                                       - knots[iMin2, columns - 4].X)
                                     + threeDiv7hy
                                     *(knots[i, columns - 1].Dx
                                       + knots[i, columns - 5].Dx) +
                                     9*threeDiv7hxhy
                                     *(-knots[i, columns - 1].Z
                                       + knots[i, columns - 5].Z)
                                     -
                                     12*threeDiv7hxhy*
                                     (knots[iMin1, columns - 1].Z
                                      - knots[iMin1, columns - 5].Z +
                                      knots[iMin2, columns - 2].Z
                                      - knots[iMin2, columns - 4].Z)
                                     - 6*oneDivHx*knots[iMin2, columns - 3].Dy +
                                     12*oneDivHy
                                     *(knots[i, columns - 2].Dx
                                       + knots[i, columns - 4].Dx) +
                                     36*threeDiv7hxhy
                                     *(knots[i, columns - 2].Z
                                       + knots[i, columns - 4].Z)
                                     - 18*oneDivHx*knots[i, columns - 3].Dy +
                                     48*threeDiv7hxhy
                                     *(-knots[iMin1, columns - 2].Z
                                       + knots[iMin1, columns - 4].Z) +
                                     24*oneDivHx*knots[iMin1, columns - 3].Z
                                     - eta*dlast;
            return rs;
        }
        protected override void FillYXDerivations(int rowIndex,
            KnotMatrix values,
            double[] lowerDiagonal = null, double[] mainDiagonal = null,
            double[] upperDiagonal = null)
        {
            var unknownsCount = values.Columns - 2;
            if (unknownsCount == 0) return;
            var h = values[0, 1].Y - values[0, 0].Y;
            var dfirst = values[rowIndex, 0].Dxy;
            var dlast = values[rowIndex, values.Columns - 1].Dxy;
            lowerDiagonal = lowerDiagonal ?? LowerDiagonal(unknownsCount);
            mainDiagonal = mainDiagonal ?? MainDiagonal(unknownsCount);
            upperDiagonal = upperDiagonal ?? UpperDiagonal(unknownsCount);
            var result = RightSideCross(values, rowIndex, dfirst, dlast,
                unknownsCount);
            LinearSystems.SolveTridiagonalSystem(lowerDiagonal, mainDiagonal,
                upperDiagonal, result);

            for (var i = 0; i < result.Length; i++)
            {
                values[rowIndex, 2*i + 1].Dxy = result[i];
            }
        }
        protected override void FillYXDerivations(KnotMatrix values)
        {
            for (var i = 2; i < values.Rows - 1; i += 2)
            {
                FillYXDerivations(i, values);
            }

            var oneDiv16 = 1d/16d;
            var threeDiv16 = oneDiv16*3;
            var hx = values[1, 0].X - values[0, 0].X;
            var hy = values[0, 1].Y - values[0, 0].Y;
            var oneDivHx = 1d/hx;
            var oneDivHy = 1d/hy;

            for (var i = 1; i < values.Rows - 1; i += 2)
            {
                for (var j = 1; j < values.Columns - 1; j += 2)
                {
                    values[i, j].Dxy = oneDiv16*
                                       (values[i + 1, j + 1].Dxy
                                        + values[i + 1, j - 1].Dxy
                                        + values[i - 1, j + 1].Dxy +
                                        values[i - 1, j - 1].Dxy)
                                       -
                                       threeDiv16*oneDivHy*
                                       (values[i + 1, j + 1].Dx
                                        + values[i + 1, j - 1].Dx
                                        + values[i - 1, j + 1].Dx +
                                        values[i - 1, j - 1].Dx)
                                       -
                                       threeDiv16*oneDivHx*
                                       (values[i + 1, j + 1].Dy
                                        + values[i + 1, j - 1].Dy
                                        + values[i - 1, j + 1].Dy +
                                        values[i - 1, j - 1].Dy)
                                       +
                                       3*threeDiv16*oneDivHx*oneDivHy*
                                       (values[i + 1, j + 1].Dy
                                        - values[i + 1, j - 1].Dy
                                        - values[i - 1, j + 1].Dy*
                                        values[i - 1, j - 1].Dy);
                }
            }

            for (var j = 2; j < values.Columns - 2; j += 2)
            {
                values[1, j].Dxy = 0.75*oneDivHy
                                   *(values[1, j + 1].Dx - values[1, j - 1].Dx)
                                   - 0.25
                                   *(values[1, j + 1].Dxy - values[1, j - 1].Dxy);
            }

            for (var i = 2; i < values.Rows - 2; i += 2)
            {
                for (var j = 2; j < values.Columns - 2; j += 2)
                {
                    values[i + 1, j].Dxy = 0.75*oneDivHy
                                           *(values[i + 1, j + 1].Dx
                                             - values[i + 1, j - 1].Dx)
                                           - 0.25
                                           *(values[i + 1, j + 1].Dxy
                                             - values[i + 1, j - 1].Dxy);
                }
                for (var j = 1; j < values.Columns - 2; j += 2)
                {
                    values[i, j].Dxy = 0.75*oneDivHy
                                       *(values[i, j + 1].Dx
                                         - values[i, j - 1].Dx)
                                       - 0.25
                                       *(values[i, j + 1].Dxy
                                         - values[i, j - 1].Dxy);
                }
            }
        }
using System;
using System.Collections.Generic;
using HermiteInterpolation.MathFunctions;
using HermiteInterpolation.Numerics;

using HermiteInterpolation.Primitives;
using HermiteInterpolation.SplineKnots;
using MathNet.Numerics.LinearAlgebra;
using Microsoft.Xna.Framework;

namespace HermiteInterpolation.Shapes.SplineInterpolation
{
    public class BicubicHermiteSurface :Spline
    {

        public BicubicHermiteSurface(SurfaceDimension uDimension, SurfaceDimension vDimension, MathExpression mathExpression, Derivation derivation = Derivation.Zero) : base(uDimension, vDimension, mathExpression, derivation)
        {
        }

        public BicubicHermiteSurface(SurfaceDimension uDimension, SurfaceDimension vDimension, InterpolativeMathFunction interpolativeMathFunction, Derivation derivation = Derivation.Zero) : base(uDimension, vDimension, interpolativeMathFunction, derivation)
        {
        }

        public BicubicHermiteSurface(SurfaceDimension uDimension, SurfaceDimension vDimension, KnotsGenerator knotsGenerator, Derivation derivation = Derivation.Zero) : base(uDimension, vDimension, knotsGenerator, derivation)
        {
        }

        protected delegate Vector<double> BasisVector(double t, double t0, double t1);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="uIdx"></param>
        /// <param name="vIdx"></param>
        /// <param name="knots"></param>
        /// <returns></returns>
        protected override ISurface CreateSegment(int uIdx, int vIdx, KnotMatrix knots)
        {
            
            var u0 = knots[uIdx,vIdx].X;
            var u1 = knots[uIdx+1,vIdx].X;
            var v0 = knots[uIdx,vIdx].Y;
            var v1 = knots[uIdx,vIdx+1].Y;
            var meshDensity = Constants.MeshDensity;
            var uKnotsDistance = Math.Abs(u1-u0);           
            var xCount = Math.Ceiling(uKnotsDistance/meshDensity);       
            var yKnotDistance =  Math.Abs(v1 - v0);
            var yCount = Math.Ceiling(yKnotDistance / meshDensity);          
            var verticesCount = (int)((++xCount) * (++yCount));

            var segmentMeshVertices = new VertexPositionNormalColor[verticesCount];
            var basisCalculator = new BicubicBasis(knots,Derivation);//BasisFactory.CreateBasis(Surface.Type);
            
            var phi = basisCalculator.Matrix(uIdx, vIdx);
            var k = 0;
            var x = (float) u0 ;
            for (var i = 0; i < xCount; i++,x += meshDensity)
            {
                x = x < u1 ? x : (float)u1;
                var lambda1 = basisCalculator.Vector(x, u0, u1);
                var basis = phi.LeftMultiply(lambda1);       
                var y = (float) v0;
                for (var j = 0; j < yCount; j++,y += meshDensity)
                {
                    y = y < v1 ? y : (float)v1;
                    var lambda2 = basisCalculator.Vector(y, v0, v1);
                    var zv = basis.PointwiseMultiply(lambda2);
                    var z = (float) zv.Sum();
                    z = MathHelper.Clamp(z, -Constants.MaxSceneZDifference, Constants.MaxSceneZDifference);   
                    segmentMeshVertices[k++] = new VertexPositionNormalColor(new Vector3(x, y, z), DefaultNormal,
                        DefaultColor);
                  
                }
               
            }
           
            return new SimpleSurface(segmentMeshVertices, (int)xCount, (int)yCount);
          
        }
    }
}
Ejemplo n.º 23
0
 public BiquarticBasis(KnotMatrix knots, Derivation derivation)
     : base(knots, derivation)
 {
 }
            private void HorizontalKnots(KnotMatrix newKnots)
            {
                for (var i = 1; i < newKnots.Rows; i += 2)
                {
                    for (var j = 0; j < newKnots.Columns; j += 2)
                    {
                        var u0 = newKnots[i - 1, j];
                        var u1 = new Knot();
                        // finished
                        var u2 = newKnots[i + 1, j];

                        var hx = Math.Abs(u2.X - u0.X)/2;
                        var hx4 = hx*4;
                        var x = u0.X + hx;
                        var y = u0.Y;

                        u1.X = x;
                        u1.Y = y;
                        u1.Z = Function.Z(x, y);

                        u1.Dy = Function.Dy(x, y);
                        u1.Dx = -(3*(u0.Z - u2.Z) + hx*(u0.Dx + u2.Dx))/
                                hx4;
                        u1.Dxy = -(3*(u0.Dy - u2.Dy) + hx*(u0.Dxy + u2.Dxy))/
                                 hx4;
                        // finished
                        newKnots[i, j] = u1;
                    }
                }
            }