Beispiel #1
0
 public virtual List<Plano> Projeta(BoundingVolume Caixa2)
 {
     throw new Exception("Implementar Projeta() com override na classe filho");
 }
Beispiel #2
0
 public override List<Plano> ProcuraPlano(BoundingVolume Caixa2)
 {
     List<Plano> Planos = this.Projeta(Caixa2);
     Planos.AddRange (Caixa2.Projeta(this).ToArray());
     return Planos;
 }
Beispiel #3
0
        public override List<Plano> Projeta(BoundingVolume nCaixa)
        {
            List<Plano> Planos = new List<Plano>();
            OBB Caixa2 = ((OBB)nCaixa);

            //    %--------------------------------------------------------
            //    % Projetando a Caixa2 nesta Caixa
            //    %--------------------------------------------------------
            //pega os Vectores
            Matrix t = Caixa2.VectoresFace.Clone();
            //subtrai o centro para preparar para a rotação
            t.SubtractInplace(this.Centro);
            //rotaciona de acordo com a transformação estabelecida
            t.MultiplyInplace(this.MatrixTransformacao);

            //procurando distancias maximas e minimas a partir do centro projetado.

            //centro projetado no SCL da caixa 1
            //Vector Centro_Projetado = (Caixa2.Centro - Caixa1.Centro) * Caixa1.MatrixTransformação;
            Vector Centro_Projetado = Caixa2.Centro.Clone();
            Centro_Projetado.SubtractInplace(this.Centro);
            Centro_Projetado.MatrixMultiplyInPlace(this.MatrixTransformacao);

            //pega os VectoresFace da caixa 2 e subtrai o centro da caixa 2.
            //desse modo os VetF estarao situados na origem
            t.SubtractInplace(Vector.VectorRepetitionLines(Centro_Projetado, Caixa2.QntdVariaveis));
            //Soma o valor absoluto em cada eixo (x, y, ....) pois existe uma combinação linear
            //dos VetF que consegue atingir esse valor nesse eixo, configurando o máximo de extensão
            //positivo ou negativo com esse módulo nesta direção.
            t.Abs();
            //Vector nt = t.SomaColuna();
            Vector nt = Vector.Ones(t.ColumnCount);
            nt.MatrixMultiplyInPlace(t);

            Vector Maximo = Centro_Projetado.Add(nt);
            Vector Minimo = Centro_Projetado.Subtract(nt);
            //    % Verifica se o centro projetado da caixa 2 no Vector 'i' da caixa 1 é
            //    % positivo ou negativo
            for (int i = 0; i < Caixa2.QntdVariaveis; i++)
            {
                //        % Se positivo, o menor valor das projecoes de todos os vertices
                //        % no Vector 'i' tem que ser maior que a borda da caixa
                if (Centro_Projetado._data[i] > 0)
                {
                    if (Minimo._data[i] > this.Limites._data[i])
                    {
                        Plano p = new Plano();
                        p.Minimo = Vector.Zeros(this.QntdVariaveis);
                        p.Minimo._data[i] = this.Limites._data[i];
                        //                 % PontoMin é o ponto pelo qual passa o plano mais rente a caixa
                        //p.Minimo = (p.Minimo * Caixa1.AutoVectores) + Caixa1.Centro;
                        p.Minimo.MatrixMultiplyInPlace(this.AutoVectores);
                        p.Minimo.AddInplace(this.Centro);
                        //                 % PontoMax é o ponto pelo qual passa o plano mais longe da caixa
                        p.Maximo = new Vector(this.QntdVariaveis);
                        p.Maximo._data[i] = Minimo._data[i];

                        //p.Maximo = (p.Maximo * Caixa1.AutoVectores) + Caixa1.Centro;
                        p.Maximo.MatrixMultiplyInPlace(this.AutoVectores);
                        p.Maximo.AddInplace(this.Centro);

                        double dummy = Math.Abs(Minimo._data[i] - this.Limites._data[i]);
                        //                 % Direção é o Vector normal ao plano de separação
                        p.VectorNormal = this.AutoVectores.GetRowVector(i);
                        p.Média = (p.Maximo.Add(p.Minimo));
                        p.Média.ScaleInplace(0.5);

                        p.bias = -(p.Média.ScalarMultiply(p.VectorNormal));
                        p.d_2 = Math.Max(dummy / 2, double.MinValue);
                        //p.significancia = 0;// p.d_2;// Caixa1.Qntd_Dados + Caixa2.Qntd_Dados;
                        Planos.Add(p);
                        break;
                    }
                }
                else if (Centro_Projetado._data[i] < 0)
                {
                    //            % Se negativo, o maior valor das projecoes de todos os vertices
                    //            % no Vector 'i' tem que ser menor que a borda da caixa
                    if (Maximo._data[i] < -this.Limites._data[i])
                    {
                        Plano p = new Plano();
                        p.Minimo = new Vector(this.QntdVariaveis);
                        p.Minimo._data[i] = -this.Limites._data[i];
                        //p.Minimo = (p.Minimo * Caixa1.AutoVectores) + Caixa1.Centro;
                        p.Minimo.MatrixMultiplyInPlace(this.AutoVectores);
                        p.Minimo.AddInplace(this.Centro);

                        //                 % PontoMin é o ponto pelo qual passa o plano mais rente a caixa
                        p.Maximo = new Vector(this.QntdVariaveis);
                        p.Maximo._data[i] = Maximo._data[i];
                        //p.Maximo = (p.Maximo * Caixa1.AutoVectores) + Caixa1.Centro;
                        p.Maximo.MatrixMultiplyInPlace(this.AutoVectores);
                        p.Maximo.AddInplace(this.Centro);

                        double dummy = Math.Abs(Maximo._data[i] - this.Limites._data[i]);
                        //                 % PontoMin é o ponto pelo qual passa o plano mais longe da caixa
                        p.VectorNormal = this.AutoVectores.GetRowVector(i);
                        p.Média = p.Maximo.Add( p.Minimo);
                        p.Média.ScaleInplace(0.5);
                        p.bias = -(p.Média.ScalarMultiply(p.VectorNormal));
                        p.d_2 = Math.Max(dummy / 2, double.MinValue);
                        //p.significancia = 0;//p.d_2;// Caixa1.Qntd_Dados + Caixa2.Qntd_Dados;
                        Planos.Add(p);
                        break;
                    }
                }
            }
            return Planos;
        }
Beispiel #4
0
        private List<Plano> testeColisao(BoundingVolume C1, BoundingVolume C2)
        {
            //    % Testa se duas caixas colidem, em caso afirmativo as divide até não haver
            //    % colisão ou não ser possivel mais dividir
            List<Plano> Planos = C1.ProcuraPlano (C2);

            //    % Verifica se existe algum plano de separação, não encontrando nenhum plano
            //    % divide as caixas
            if (Planos.Count == 0) {
                if ((C1.QntdDados > 1) && (C1.Profundidade () < tipo.profundidade)) {
                    C1.CriaFilhos ();
                    //        % Caso ja existam os nós filhos
                    if (C1.volAcima  != null) {
                        Planos.AddRange (testeColisao (C2, C1.volAcima ).ToArray ());
                    }
                    if (C1.volAbaixo != null) {
                        Planos.AddRange (testeColisao (C2, C1.volAbaixo).ToArray ());
                    }
                } else if ((C2.QntdDados > 1) && (C2.Profundidade () < tipo.profundidade)) {
                    C2.CriaFilhos ();
                    if (C2.volAcima  != null) {
                        Planos.AddRange (testeColisao (C1, C2.volAcima ).ToArray ());
                    }
                    if (C2.volAbaixo != null) {
                        Planos.AddRange (testeColisao (C1, C2.volAbaixo).ToArray ());
                    }
                }
            }
            return Planos;
        }
Beispiel #5
0
        List<Plano> SelecionaPlanos(BoundingVolume Caixa1, BoundingVolume Caixa2, List<Plano> planos)
        {
            ElencaPlanos (Caixa1, Caixa2, ref planos);

            List<Vector> pad1 = new List<Vector> ();
            List<Vector> pad2 = new List<Vector> ();

            // Guarda o numero dos planos escolhidos
            List<int> PlanSelec = new List<int> ();

            // Guarda o numero dos planos NÃO escolhidos
            List<int> PlanNSelec = new List<int> (planos.Count);

            for (int i = 0; i < planos.Count; i++) {
                PlanNSelec.Add (i);
            }

            int ini1 = 0;
            int ini2 = 0;
            bool separado = false;

            while (!separado) {
                //retorna o número do plano, que é o índice dele na variavel "planos"
                int Indice = ProcuraIndiceSepara (ref ini1, ref  ini2, planos, Caixa1, Caixa2, PlanNSelec);
                //se nao encontrou incrementa ini2, pula esse ponto
                if (Indice == -1) {
                    ini2++;
                } else {

                    PlanSelec.Add (Indice);
                    PlanNSelec.Remove (Indice);

                    Vector vdummy1 = new Vector (Caixa1.QntdDados);
                    for (int i = 0; i < Caixa1.QntdDados; i++) {
                        vdummy1._data [i] = VerificaPonto (Caixa1.Pontos [i], planos [Indice]);
                    }

                    pad1.Add (vdummy1);

                    Vector vdummy2 = new Vector (Caixa2.QntdDados);
                    for (int i = 0; i < Caixa2.QntdDados; i++) {
                        vdummy2._data [i] = VerificaPonto (Caixa2.Pontos [i], planos [Indice]);
                    }
                    pad2.Add (vdummy2);

                }
                if (pad1.Count != 0) {
                    separado = VerificaSeparacao (pad1, pad2, ref ini1, ref ini2);
                }

            }

            List<Plano> novosPlanos = new List<Plano> ();
            foreach (int i in PlanSelec) {
                novosPlanos.Add (planos [i]);
            }
            return novosPlanos;
        }
Beispiel #6
0
        private int ProcuraIndiceSepara(ref int l1, ref int l2, List<Plano> planos, BoundingVolume Caixa1, BoundingVolume Caixa2, List<int> PlanNSelec)
        {
            //adjusting the pointers
            if (l2 >= Caixa2.QntdDados) {
                l2 = 0;
                l1++;
            }

            int best = -1;
            double bestDist = 0;

            //for (int c = 0; c < planos.Count; c++)
            foreach (int c in PlanNSelec) {
                double p1 = VerificaPonto (Caixa1.Pontos [l1], planos [c]);

                double p2 = VerificaPonto (Caixa2.Pontos [l2], planos [c]);

                //if the plane divide correctly we use it.
                if ((p1 == -p2) && (Math.Abs (p1) == 1)) {
                    return c;
                }

                //otherwise we keep the best result
                if (tipo.Bounds) {
                    if (Math.Sign (p1) == -Math.Sign (p2)) {
                        if (Math.Min (Math.Abs (p1), Math.Abs (p2)) > bestDist) {
                            best = c;
                            bestDist = Math.Min (Math.Abs (p1), Math.Abs (p2));
                        }
                    }
                }
            }
            //if (Bounds)
            //    planos[best].d_2 *= bestDist;
            return best;
        }
Beispiel #7
0
        private PreRedeNeural GeraPreRedeNeural(BoundingVolume Caixa1, BoundingVolume Caixa2, List<Plano> planos)
        {
            List<Vector> pad1 = new List<Vector> ();
            List<Vector> pad2 = new List<Vector> ();

            for (int Indice = 0; Indice< planos.Count; Indice++) {
                Vector vdummy1 = new Vector (Caixa1.QntdDados);
                for (int i = 0; i < Caixa1.QntdDados; i++) {
                    vdummy1._data [i] = VerificaPonto (Caixa1.Pontos [i], planos [Indice]);
                }

                pad1.Add (vdummy1);

                Vector vdummy2 = new Vector (Caixa2.QntdDados);
                for (int i = 0; i < Caixa2.QntdDados; i++) {
                    vdummy2._data [i] = VerificaPonto (Caixa2.Pontos [i], planos [Indice]);
                }
                pad2.Add (vdummy2);

            }
            if (tipo.Bounds) {
                AjustaDistancias (ref pad1, ref pad2, ref planos);
            }

            //para deixar binário, -1 ou 1;
            AjustaPadrões (ref pad1, ref pad2);

            // pega os padrões de verdade

            Matrix p1, p2;
            p1 = FindUnique (pad1);
            p2 = FindUnique (pad2);

            PreRedeNeural nova_rede = new PreRedeNeural ();

            nova_rede.planos = planos;

            nova_rede.padDentro = p1;
            nova_rede.dentro = Caixa1.Nome;

            nova_rede.padFora = p2;
            nova_rede.fora = Caixa2.Nome;

            return nova_rede;
        }
Beispiel #8
0
        private void ElencaPlanos(BoundingVolume Caixa1, BoundingVolume Caixa2, ref List<Plano> planos)
        {
            if (tipo.MBC) {
                for (int np = 0; np < planos.Count; np++) {
                    double Qntd1P = 0;
                    double Qntd1N = 0;
                    double Qntd2P = 0;
                    double Qntd2N = 0;

                    for (int i = 0; i < Caixa1.QntdDados; i++) {
                        if (VerificaPonto (Caixa1.Pontos [i], planos [np]) > 0) {
                            Qntd1P++;
                        } else {
                            Qntd1N++;
                        }
                    }

                    for (int i = 0; i < Caixa2.QntdDados; i++) {
                        if (VerificaPonto (Caixa2.Pontos [i], planos [np]) > 0) {
                            Qntd2P++;
                        } else {
                            Qntd2N++;
                        }
                    }

                    Qntd1P /= Caixa1.QntdDados;
                    Qntd1N /= Caixa1.QntdDados;
                    double s1;
                    if (Qntd1P > Qntd1N)
                        s1 = Qntd1P;
                    else
                        s1 = -Qntd1N;

                    Qntd2P /= Caixa2.QntdDados;
                    Qntd2N /= Caixa2.QntdDados;
                    double s2;
                    if (Qntd2P > Qntd2N)
                        s2 = Qntd2P;
                    else
                        s2 = -Qntd2N;

                    //if (Math.Sign(s1) == Math.Sign(s2))
                    //    planos[np].significancia = -s1 * s2;
                    //else
                    //    planos[np].significancia = -s1 * s2;

                    if (tipo.MPD) {
                        planos [np].significancia = -s1 * s2 * planos [np].d_2;

                    } else {
                        planos [np].significancia = -s1 * s2;
                    }
                }

                //int total = Caixa1.Qntd_Dados + Caixa2.Qntd_Dados;
                //for (int np = 0; np < planos.Count; np++)
                //{
                //    planos[np].significancia /= total;
                //}
                planos.Sort ();
            } else {
                if (tipo.MPD) {
                    for (int np = 0; np < planos.Count; np++) {
                        planos [np].significancia = planos [np].d_2;
                    }
                    planos.Sort ();
                }
            }
        }