Beispiel #1
0
        static internal CutNode GenCube(int dim, double V)
        {
            int m = 1;

            for (int i = 0; i < dim; i++)
            {
                m *= 3;
            }
            CutNode[] u = new CutNode[m];
            for (int a = 0; a < m; a++)
            {
                int d = 0;
                for (int b = a; b > 0; b /= 3)
                {
                    if (b % 3 == 2)
                    {
                        d++;
                    }
                }
                if (d == 0)
                {
                    double[] pt = new double[dim];
                    int      b  = a;
                    for (int i = 0; i < dim; i++)
                    {
                        pt[i] = (b % 3 - 0.5) * 2 * V;
                        b    /= 3;
                    }
                    u[a] = new PointNode()
                    {
                        Pos = pt, Dim = 0
                    };
                }
                else
                {
                    CutNode[] ch = new CutNode[2 * d];
                    int       k  = 0;
                    for (int b = 1; b < m; b *= 3)
                    {
                        if ((a / b) % 3 == 2)
                        {
                            ch[k++] = u[a - 2 * b];
                            ch[k++] = u[a - b];
                        }
                    }
                    u[a] = new CutNode()
                    {
                        Dim = d, Children = ch
                    };
                }
            }
            return(u[m - 1]);
        }
Beispiel #2
0
        internal virtual CutNode Copy(int opgen)
        {
            if (opgen == OpGen)
            {
                return(Pair);
            }
            OpGen = opgen;
            CutNode res = new CutNode();

            res.Dim      = Dim;
            res.Children = new CutNode[Children.Length];
            for (int i = 0; i < Children.Length; i++)
            {
                res.Children[i] = Children[i].Copy(opgen);
            }
            Pair = res;
            return(res);
        }
Beispiel #3
0
        private void CutFaces()
        {
            double RMax = 0;

            foreach (PBaseFace F in BaseFaces)
            {
                RMax = Math.Max(RMax, PGeom.VLength(F.Pole));
            }
            int minrank = int.MaxValue;

            foreach (PBaseFace F in BaseFaces)
            {
                CutNode  face = CutNode.GenCube(Dim, RMax * Dim);
                double[] hpln = CutNetwork.GetPlane(F.Pole, 1);
                face.Split(1, hpln, false);
                face = face.ZeroNode;
                int opgen = 1;
                foreach (PFace FF in Faces)
                {
                    if (F.Id != FF.Id)
                    {
                        hpln = CutNetwork.GetPlane(FF.Pole, 1);
                        face.Split(++opgen, hpln, true);
                        if (face.Status != CutNode.STAT_PLUS)
                        {
                            throw new Exception("Empty face: Id=" + F.Id);
                        }
                    }
                }

                int        nff   = face.Children.Length;
                double[][] ffpol = new double[nff][];
                for (int i = 0; i < nff; i++)
                {
                    ffpol[i] = face.Children[i].Pole;
                }
                F.FPoles = ffpol;

                LMesh m = new LMesh(Dim, true);
                face.FillLMesh(++opgen, m);
                m.CloseCtr();
                F.FaceMesh      = new PMesh(m);
                F.FaceMesh.FCtr = F.Pole;

                double[]   verts  = m.pts;
                int        nverts = m.npts;
                CutNetwork CN     = new CutNetwork(face, Dim, opgen);
                double[][] fctrs  = null;
                if (QSimplified)
                {
                    fctrs = CN.GetCtrs();
                }
                F.AxisLayers = new int[Axes.Length];
                for (int u = 0; u < Axes.Length; u++)
                {
                    PAxis    Ax = Axes[u];
                    double[] D = Ax.Dir;
                    double   lD = PGeom.Dist2(D, new double[Dim]);
                    double   smin = double.MaxValue, smax = double.MinValue;
                    for (int i = 0; i < nverts; i++)
                    {
                        double v = 0;
                        for (int j = 0; j < Dim; j++)
                        {
                            v += D[j] * verts[i * Dim + j];
                        }
                        if (v < smin)
                        {
                            smin = v;
                        }
                        if (v > smax)
                        {
                            smax = v;
                        }
                    }
                    smin /= lD; smax /= lD;
                    bool cs = false, cc = false;
                    int  k = Ax.Base.NLayers - 1;
                    for (int i = 0; i < Ax.Base.Cut.Length; i++)
                    {
                        double p = Ax.Base.Cut[i];
                        if (p >= smax - 0.0001)
                        {
                            continue;
                        }
                        if (!cs)
                        {
                            k = i; cs = true;
                        }
                        if (p <= smin + 0.0001)
                        {
                            break;
                        }
                        hpln = CutNetwork.GetPlane(Ax.Dir, p);
                        CN.Split(hpln, false);
                        cc = true;
                    }
                    if (cc)
                    {
                        k = -1;
                    }
                    F.AxisLayers[u] = k;
                }
                F.SetStickers(m, CN, Axes, fctrs);
                minrank = Math.Min(minrank, F.MinRank());
            }
            foreach (PBaseFace F in BaseFaces)
            {
                F.SubRank(minrank);
            }
        }
Beispiel #4
0
 internal CutNetwork(CutNode x, int dim, int opgen)
 {
     Nodes = new CutNode[] { x };
     Dim   = dim;
     OpGen = opgen;
 }
Beispiel #5
0
        internal virtual void Split(int opgen, double[] hpln, bool qpos)
        {
            if (opgen == OpGen)
            {
                return;
            }
            OpGen    = opgen;
            ZeroNode = Pair = null;
            int nplus = 0, nminus = 0;

            foreach (CutNode D in Children)
            {
                D.Split(opgen, hpln, qpos);
                if (D.IsDivided)
                {
                    nminus++;
                }
                switch (D.Status)
                {
                case STAT_MINUS: nminus++; break;

                case STAT_PLUS: nplus++; break;

                case STAT_ZERO: ZeroNode = D; break;
                }
            }
            if (nplus == 0)
            {
                Status = nminus != 0 ? STAT_MINUS : STAT_ZERO;
                //                PrintLevel();
                return;
            }
            if (nminus == 0)
            {
                Status = STAT_PLUS;
                //                PrintLevel();
                return;
            }
            CutNode[] chp = new CutNode[nplus + 1];
            CutNode[] chm = new CutNode[nminus + 1];

            if (ZeroNode == null)
            {
                if (Dim == 1)
                {
                    if (nplus != 1 || nminus != 1)
                    {
                        throw new Exception("Wrong length of edge");
                    }
                    PointNode p0 = (PointNode)Children[0];
                    PointNode p1 = (PointNode)Children[1];
                    double    p  = p1.Val / (p1.Val - p0.Val);
                    int       n  = p0.Pos.Length;
                    double[]  cc = new double[n];
                    for (int i = 0; i < n; i++)
                    {
                        cc[i] = p0.Pos[i] * p + p1.Pos[i] * (1 - p);
                    }
                    PointNode z = new PointNode();
                    z.Pos    = cc;
                    z.Val    = 0;
                    ZeroNode = z;
                }
                else
                {
                    ArrayList arr = new ArrayList();
                    foreach (CutNode D in Children)
                    {
                        if (D.Status == STAT_PLUS && D.HaveZero)
                        {
                            arr.Add(D.ZeroNode);
                        }
                    }
                    if (Dim == 2 && arr.Count != 2)
                    {
                        throw new Exception("Wrong number of segment ends");
                    }
                    ZeroNode          = new CutNode();
                    ZeroNode.Children = (CutNode[])arr.ToArray(typeof(CutNode));
                }
                ZeroNode.Dim    = Dim - 1;
                ZeroNode.Status = STAT_ZERO;
                ZeroNode.BrdDim = BrdDim;
                ZeroNode.Pole   = IntPole(Pole, hpln);
                ZeroNode.OpGen  = opgen;
                //                if(Dim>1) ZeroNode.PrintLevel();
            }

            chp[0] = chm[0] = ZeroNode;
            int np = 1, nm = 1;

            foreach (CutNode D in Children)
            {
                if (D.IsDivided)
                {
                    chm[nm++] = D.Pair;
                }
                if (D.Status == STAT_PLUS)
                {
                    chp[np++] = D;
                }
                else if (D.Status == STAT_MINUS)
                {
                    chm[nm++] = D;
                }
            }
            if (np != nplus + 1 || nm != nminus + 1)
            {
                throw new Exception("Wrong length of children");
            }

            Pair          = new CutNode();
            Pair.Dim      = Dim;
            Pair.Children = chm;
            Pair.Status   = STAT_MINUS;
            Pair.ZeroNode = ZeroNode;
            Pair.BrdDim   = BrdDim;
            Pair.OpGen    = opgen;

            Children = chp;
            Status   = STAT_PLUS;
            //            PrintLevel();
        }