示例#1
0
        public static NurbsPoint DeBoorSurface(
            List <List <NurbsPoint> > controlNet,
            decimal u,
            decimal[] knotU,
            decimal v,
            decimal[] knotV)
        {
            var cPointsU = controlNet.First();
            var cPointsV = controlNet.Transpose().First();

            var p = knotU.Length - cPointsU.Count - 1;
            var q = knotV.Length - cPointsV.Count - 1;

            u = Math.Round(u, 21);
            v = Math.Round(v, 21);

            var magic = 0;

            switch (u)
            {
            case 0:
                magic += 1;
                break;

            case 1:
                magic += 3;
                break;

            default:
                magic += 2;
                break;
            }

            switch (v)
            {
            case 0:
                magic += 0;
                break;

            case 1:
                magic += 6;
                break;

            default:
                magic += 3;
                break;
            }

            switch (magic)
            {
            case 1:
                return(controlNet.First().First());

            case 2:
                return(NurbsLogic.DeBoor(p, controlNet.First(), u, knotU));

            case 3:
                return(controlNet.First().Last());

            case 4:
                return(NurbsLogic.DeBoor(q, controlNet.Transpose().First(), v, knotV));

            case 5:
                break;

            case 6:
                return(NurbsLogic.DeBoor(q, controlNet.Transpose().Last(), v, knotV));

            case 7:
                return(controlNet.Last().First());

            case 8:
                return(NurbsLogic.DeBoor(p, controlNet.Last(), u, knotU));

            case 9:
                return(controlNet.Last().Last());

            default:
                break;
            }

            var c = NurbsLogic.FindSpan(u, knotU);
            var d = NurbsLogic.FindSpan(v, knotV);

            var s = NurbsLogic.CheckMultiplicity(knotU, u);
            var t = NurbsLogic.CheckMultiplicity(knotV, v);

            NurbsPoint point;

            if (u.GreaterThanOrEqualTo(knotU[c]) && u.LessThan(knotU[c + 1]) && v.GreaterThanOrEqualTo(knotV[d]) && v.LessThan(knotV[d + 1]))
            {
                var P = new NurbsPoint[c - s + 1, d - t + 1];
                var Q = new NurbsPoint[c - s + 1];

                for (var i = 0; i < P.GetLength(0); i++)
                {
                    for (var j = 0; j < P.GetLength(1); j++)
                    {
                        P[i, j] = controlNet[j][i];
                    }
                }

                for (var i = 0; i < P.GetLength(0); i++)
                {
                    var Pi = new List <NurbsPoint>();
                    for (var j = 0; j < P.GetLength(1); j++)
                    {
                        Pi.Add(P[i, j]);
                    }

                    Q[i] = NurbsLogic.DeBoor(q, Pi, v, knotV);
                }

                point = NurbsLogic.DeBoor(p, Q.ToList(), u, knotU);
            }
            else
            {
                // ReSharper disable once UnthrowableException
                throw new IndexOutOfRangeException("u not in [u_c, u_c+1) or v not in [u_d, u_d+1)");
            }

            return(point);
        }
示例#2
0
        public static NurbsPoint DeBoor(int p, List <NurbsPoint> controlPoints, decimal u, decimal[] knotVector)
        {
            if (u.AlmostEquals(0M))
            {
                return(controlPoints.First());
            }

            if (u.AlmostEquals(1M))
            {
                return(controlPoints.Last());
            }

            var k = FindSpan(u, knotVector);
            var s = NurbsLogic.CheckMultiplicity(knotVector, u);

            NurbsPoint point;

            if (u.GreaterThanOrEqualTo(knotVector[k]) && u.LessThan(knotVector[k + 1]))
            {
                var h = p - s;

                if (h == 0)
                {
                    return(controlPoints[k - s]);
                }

                var points = new List <Point4D> [h + 1];
                points[0] = controlPoints.ToPoint4DList();

                for (var r = 1; r <= h; r++)
                {
                    /*points[r] = new List<Point4D>(k - s + 1);
                     * for (var i = 0; i <= k - s + 1; i++)
                     * {
                     *  points[r].Add(new Point4D(-1, -1, -1, -1));
                     * }*/

                    points[r] = controlPoints.ToPoint4DList();

                    for (var i = k - p + r; i <= k - s; i++)
                    {
                        if (points[r - 1][i - 1] == null || points[r - 1][i] == null)
                        {
                            continue;
                        }

                        // ReSharper disable once InconsistentNaming
                        var a_ir = (double)((u - knotVector[i]) / (knotVector[i + p - r + 1] - knotVector[i]));

                        var x      = ((1 - a_ir) * points[r - 1][i - 1].X) + (a_ir * points[r - 1][i].X);
                        var y      = ((1 - a_ir) * points[r - 1][i - 1].Y) + (a_ir * points[r - 1][i].Y);
                        var z      = ((1 - a_ir) * points[r - 1][i - 1].Z) + (a_ir * points[r - 1][i].Z);
                        var weight = ((1 - a_ir) * points[r - 1][i - 1].Weight) + (a_ir * points[r - 1][i].Weight);

                        points[r][i] = new Point4D(x, y, z, weight);
                    }
                }

                point = points[h][k - s].ToNurbsPoint();
            }
            else
            {
                // ReSharper disable once UnthrowableException
                throw new IndexOutOfRangeException("u not in [u_k, u_k+1)");
            }

            return(point);
        }