public virtual List<Plano> Projeta(BoundingVolume Caixa2) { throw new Exception("Implementar Projeta() com override na classe filho"); }
public override List<Plano> ProcuraPlano(BoundingVolume Caixa2) { List<Plano> Planos = this.Projeta(Caixa2); Planos.AddRange (Caixa2.Projeta(this).ToArray()); return Planos; }
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; }
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; }
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; }
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; }
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; }
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 (); } } }