Exemplo n.º 1
0
        public static double spiro_iter(SpiroSegment[] s, BandMatrix[] m, int[] perm, double[] v, int n, int nmat)
        {
            bool           cyclic;
            int            i, j, jthl, jthr, jk0l, jk0r, jk1l, jk1r, jk2l, jk2r, jinc, jj, k, n_invert;
            SpiroPointType ty0, ty1;
            double         dk, norm, th;

            double[][]   ends   = { new double[4], new double[4] };
            double[][][] derivs =
            {
                new double[2][] { new double[4], new double[4] },
                new double[2][] { new double[4], new double[4] },
                new double[2][] { new double[4], new double[4] },
                new double[2][] { new double[4], new double[4] },
            };

            cyclic = s[0].Type != SpiroPointType.OpenContour && s[0].Type != SpiroPointType.Corner;

            for (i = 0; i < nmat; i++)
            {
                v[i] = 0.0;

                for (j = 0; j < 11; j++)
                {
                    m[i].a[j] = 0.0;
                }

                for (j = 0; j < 5; j++)
                {
                    m[i].al[j] = 0.0;
                }
            }

            j = 0;

            if (s[0].Type == SpiroPointType.G4)
            {
                jj = nmat - 2;
            }
            else if (s[0].Type == SpiroPointType.G2)
            {
                jj = nmat - 1;
            }
            else
            {
                jj = 0;
            }

            for (i = 0; i < n; i++)
            {
                ty0  = s[i].Type;
                ty1  = s[i + 1].Type;
                jinc = compute_jinc(ty0, ty1);
                th   = s[i].bend_th;
                jthl = jk0l = jk1l = jk2l = -1;
                jthr = jk0r = jk1r = jk2r = -1;

                compute_pderivs(ref s[i], ends, derivs, jinc);

                // constraints crossing left
                if (ty0 == SpiroPointType.G4 || ty0 == SpiroPointType.G2 || ty0 == SpiroPointType.Left || ty0 == SpiroPointType.Right)
                {
                    jthl = jj++;
                    jj  %= nmat;
                    jk0l = jj++;

                    if (ty0 == SpiroPointType.G4)
                    {
                        jj  %= nmat;
                        jk1l = jj++;
                        jk2l = jj++;
                    }
                }

                // constraints on left
                if ((ty0 == SpiroPointType.Left || ty0 == SpiroPointType.Corner || ty0 == SpiroPointType.OpenContour || ty0 == SpiroPointType.G2) && jinc == 4)
                {
                    if (ty0 != SpiroPointType.G2)
                    {
                        jk1l = jj++;
                    }

                    jk2l = jj++;
                }

                // constraints on right
                if ((ty1 == SpiroPointType.Right || ty1 == SpiroPointType.Corner || ty1 == SpiroPointType.EndOpenContour || ty1 == SpiroPointType.G2) && jinc == 4)
                {
                    if (ty1 != SpiroPointType.G2)
                    {
                        jk1r = jj++;
                    }

                    jk2r = jj++;
                }

                // constraints crossing right
                if (ty1 == SpiroPointType.G4 || ty1 == SpiroPointType.G2 || ty1 == SpiroPointType.Left || ty1 == SpiroPointType.Right)
                {
                    jthr = jj;
                    jk0r = (jj + 1) % nmat;

                    if (ty1 == SpiroPointType.G4)
                    {
                        jk1r = (jj + 2) % nmat;
                        jk2r = (jj + 3) % nmat;
                    }
                }

                add_mat_line(m, v, derivs[0][0], th - ends[0][0], 1, j, jthl, jinc, nmat);
                add_mat_line(m, v, derivs[1][0], ends[0][1], -1, j, jk0l, jinc, nmat);
                add_mat_line(m, v, derivs[2][0], ends[0][2], -1, j, jk1l, jinc, nmat);
                add_mat_line(m, v, derivs[3][0], ends[0][3], -1, j, jk2l, jinc, nmat);
                add_mat_line(m, v, derivs[0][1], -ends[1][0], 1, j, jthr, jinc, nmat);
                add_mat_line(m, v, derivs[1][1], -ends[1][1], 1, j, jk0r, jinc, nmat);
                add_mat_line(m, v, derivs[2][1], -ends[1][2], 1, j, jk1r, jinc, nmat);
                add_mat_line(m, v, derivs[3][1], -ends[1][3], 1, j, jk2r, jinc, nmat);

                if (jthl >= 0)
                {
                    v[jthl] = mod_2pi(v[jthl]);
                }

                if (jthr >= 0)
                {
                    v[jthr] = mod_2pi(v[jthr]);
                }

                j += jinc;
            }

            if (cyclic)
            {
                BandMatrix.Copy(m, 0, m, nmat, nmat);
                BandMatrix.Copy(m, 0, m, 2 * nmat, nmat);
                Array.Copy(v, 0, v, nmat, nmat);
                Array.Copy(v, 0, v, 2 * nmat, nmat);
                n_invert = 3 * nmat;
                j        = nmat;
            }
            else
            {
                n_invert = nmat;
                j        = 0;
            }

            bandec11(m, perm, n_invert);
            banbks11(m, perm, v, n_invert);
            norm = 0.0;

            for (i = 0; i < n; i++)
            {
                jinc = compute_jinc(s[i].Type, s[i + 1].Type);

                for (k = 0; k < jinc; k++)
                {
                    dk = v[j++];

                    s[i].ks[k] += dk;
                    norm       += dk * dk;
                }

                s[i].ks[0] = 2.0 * mod_2pi(s[i].ks[0] / 2.0);
            }

            return(norm);
        }