int classificaPonto(Coordenada c){ if(c.getX()==-1) return 1;//borda Oeste if(c.getY()==1) return 2;//borda Norte if(c.getX()==1) return 3;//borda Leste if(c.getY()==-1) return 4;//borda Sul return 0; //centro }
int rcCode(Coordenada ponto){ int code =0; if (ponto.getX() < -1) code |= 1; else if (ponto.getX() > 1) code |= 2; if (ponto.getY() < -1) code |= 4; else if (ponto.getY() > 1) code |= 8; return code; }
list<Coordenada*>* Clipping::getWindowLista(list<Coordenada*>* poligonoVertices) { list<Coordenada*>* windowVertices = new list<Coordenada*>(); Coordenada *A = this->window->CPPstart->clone(); Coordenada *C = this->window->CPPend->clone(); Coordenada *B = new Coordenada(A->getX(), C->getY(), 0); Coordenada *D = new Coordenada(C->getX(), A->getY(), 0); windowVertices->push_back(A); windowVertices->push_back(B); windowVertices->push_back(C); windowVertices->push_back(D); this->addListToList(poligonoVertices, windowVertices, A, CoordenadaUtils::compareEqualXAndIsInterseccao, CoordenadaUtils::compareMenorY); this->addListToList(poligonoVertices, windowVertices, B, CoordenadaUtils::compareEqualYAndIsInterseccao, CoordenadaUtils::compareMenorX); this->addListToList(poligonoVertices, windowVertices, C, CoordenadaUtils::compareEqualXAndIsInterseccao, CoordenadaUtils::compareMaiorY); this->addListToList(poligonoVertices, windowVertices, D, CoordenadaUtils::compareEqualYAndIsInterseccao, CoordenadaUtils::compareMaiorX); return windowVertices; }
void move(Coordenada passo) { double xFactor = largura * passo.getX() / 100.0; double yFactor = altura * passo.getY() / 100.0; _centro += Coordenada(xFactor, yFactor); }
vector<vector<double> > getTransformadaMundo(Coordenada wCentro, Window * window){ Coordenada tr(-1*wCentro.getX(),-1*wCentro.getY(),1); vector<vector<double> > m = manipulaMtr->getTranslacao(tr); m = manipulaMtr->multiplicaMatriz(m, manipulaMtr->getRotacao(-1*angulo)); Coordenada tr2(2/window->getLargura(),2/window->getAltura(),1); m = manipulaMtr->multiplicaMatriz(m, manipulaMtr->getEscalonamento(tr2)); return m; }
void escalona(Objeto* obj, Coordenada c){ Coordenada centro = obj->getCentro(); Coordenada a(-1*centro.getX(),-1*centro.getY(),1); vector<vector<double> > m = manipulador->getTranslacao(a); m = manipulador->multiplicaMatriz(m, manipulador->getEscalonamento(c)); m = manipulador->multiplicaMatriz(m, manipulador->getTranslacao(centro)); transformaObjeto(obj, m); }
bool gambs_pontoPertence(ListaEnc<Coordenada> pontos, Coordenada obj){ Elemento<Coordenada>* it = pontos.getHead(); for(int i =0; i<pontos.getSize(); i++){ if(igual(it->info->getX(),obj.getX()) && igual(it->info->getY(),obj.getY())) return true; it = it->_next; } return false; }
void rotaciona(Window* window, double angulo){ this->angulo+=angulo; Coordenada centro = window->getwCentro(); Coordenada a(-1*centro.getX(),-1*centro.getY(),1); vector<vector<double> > m = manipulaMtr->getTranslacao(a); m = manipulaMtr->multiplicaMatriz(m, manipulaMtr->getRotacao(angulo)); m = manipulaMtr->multiplicaMatriz(m, manipulaMtr->getTranslacao(centro)); transformaWindow(window, m); manipulaWrld->fuckMundo(window->getDisplay(), window->getDisplay_virtual(), getTransformadaMundo(centro, window)); }
//Obs: não consegui passar parâmetro null para fazer uma única funćão void insereNoObjeto(ListaEnc<Coordenada>* pontosObjeto, Coordenada ref, Coordenada pontoA){ int pos = 0; Elemento<Coordenada> *it_lista = pontosObjeto->getHead(); while(!igual(it_lista->info->getX(),ref.getX()) || !igual(it_lista->info->getY(),ref.getY())){//busca como referência o ponto A it_lista = it_lista->_next; pos++; } pos++; pontosObjeto->adicionaNaPosicao(pontoA, pos); }
void rotaciona(Objeto* obj, Coordenada coord, double angulo){ /* (0,0,1): rotaciona no centro do mundo * getCentro: rotaciona no centro do objeto * (x, y, 1): rotaciona no ponto */ Coordenada a(-1*coord.getX(),-1*coord.getY(),1); vector<vector<double> > m = manipulador->getTranslacao(a); m = manipulador->multiplicaMatriz(m, manipulador->getRotacao(angulo)); m = manipulador->multiplicaMatriz(m, manipulador->getTranslacao(coord)); transformaObjeto(obj, m); }
Matriz::Matriz(Coordenada coord) { mat.resize(1); mat[0].resize(4); mat[0][0] = coord.getX(); mat[0][1] = coord.getY(); mat[0][2] = coord.getZ(); mat[0][3] = coord.getW(); linhas = 1; colunas = 4; }
DisplayFile transformadaViewport(Window w) { DisplayFile novoDisplay; DisplayFile originalDisplay = *w.getDisplay_virtual(); //constantes da transformacao double divX, divY, multX, multY; // divX = (w.getwMax() - w.getwMin()).getX(); // divY = (w.getwMax() - w.getwMin()).getY(); //Alterado para 2 devido ao processo de normalizacao das coordenadas do mundo: window=(-1,-1), (1,1) divX = 2; divY = 2; multX = (vMax - vMin).getX(); multY = (vMax - vMin).getY(); // iterando lista de objetos Elemento<Objeto*>* it_originalDisplay = originalDisplay.getHead(); for (int i = 0; i < originalDisplay.getSize(); i++) { Objeto *novoObj = new Objeto((it_originalDisplay->getInfo())->nome(), it_originalDisplay->getInfo()->getTipo(), it_originalDisplay->getInfo()->isPreenchido()); ListaEnc<Coordenada>* coordenadas_obj = (it_originalDisplay->getInfo())->pontos(); Elemento<Coordenada>* it_coordenada = coordenadas_obj->getHead(); //iterando as coordenadas do objeto for (int j = 0; j < coordenadas_obj->getSize(); j++) { Coordenada atual = it_coordenada->getInfo(); //Transformacao double newX, newY, newZ; // newX = ((atual.getX() - w.getwMin().getX()) / divX) * multX; // newY = (1 - (atual.getY() - w.getwMin().getY()) / divY) * multY; //Alterado para 2 devido ao processo de normalizacao das coordenadas do mundo: window=(-1,-1), (1,1) newX = ((atual.getX() +1) / divX) * multX + vMin.getX(); newY = (1 - (atual.getY() +1) / divY) * multY + vMin.getY(); newZ = 1; //criando novo ponto Coordenada* novoPonto = new Coordenada(newX, newY, newZ); novoObj->adiciona(*novoPonto); it_coordenada = it_coordenada->getProximo(); } novoDisplay.adicionaNoInicio(novoObj); it_originalDisplay = it_originalDisplay->getProximo(); } return novoDisplay; }
void insereNaWindow(ListaEnc<Coordenada>* pontosWindow, Coordenada ponto){ //Código monstruoso comecando em 9, 8, 7, ... /* B---2---C * | | * 1 0 3 * | | * A---4---D */ //1 e 2 contam em ordem crescente, considerando Y e X, respectivamente; //3 e 4 contam em ordem decrescente, considerando Y e X, respectivamente; int lado = classificaPonto(ponto); int pos = 0; //!!!!!!!!!!!PODE DAR MERDA NOS INDICES!!!!!!!!!!!!! Elemento<Coordenada> *it_lista = pontosWindow->getHead(); switch(lado){ case(1):{ while(!igual(it_lista->info->getX(),-1) || !igual(it_lista->info->getY(),-1)){//busca como referência o ponto A it_lista = it_lista->_next; pos++; } while(igual(it_lista->info->getX(),-1) && igual(it_lista->info->getY(),-1)){//para caso hajam pontos A além da referência it_lista = it_lista->_next; pos++; } while(it_lista->info->getY()<ponto.getY()){//busca em ordem crescente it_lista = it_lista->_next; pos++; } pontosWindow->adicionaNaPosicao(ponto, pos); return; } case(2):{ while(!igual(it_lista->info->getX(),-1) || !igual(it_lista->info->getY(),1)){//busca como referência o ponto B it_lista = it_lista->_next; pos++; } while(igual(it_lista->info->getX(),-1) && igual(it_lista->info->getY(),1)){//busca como referência o ponto B it_lista = it_lista->_next; pos++; } while(it_lista->info->getX()<ponto.getX()){//busca em ordem crescente it_lista = it_lista->_next; pos++; } pontosWindow->adicionaNaPosicao(ponto, pos); return; } case(3):{ while(!igual(it_lista->info->getX(),1) || !igual(it_lista->info->getY(),1)){//busca como referência o ponto C it_lista = it_lista->_next; pos++; } while(igual(it_lista->info->getX(),1) && igual(it_lista->info->getY(),1)){//busca como referência o ponto C it_lista = it_lista->_next; pos++; } while(it_lista->info->getY()>ponto.getY()){//busca em ordem crescente it_lista = it_lista->_next; pos++; } pontosWindow->adicionaNaPosicao(ponto, pos); return; } case(4):{ while(!igual(it_lista->info->getX(),1) || !igual(it_lista->info->getY(),-1)){//busca como referência o ponto D it_lista = it_lista->_next; pos++; } while(igual(it_lista->info->getX(),1) && igual(it_lista->info->getY(),-1)){//busca como referência o ponto D pos++; if(pos==pontosWindow->getSize()){ pontosWindow->adiciona(ponto); return; } it_lista = it_lista->_next; } while(it_lista->info->getX()>ponto.getX()){//busca em ordem crescente it_lista = it_lista->_next; pos++; if(pos==pontosWindow->getSize()){ pontosWindow->adiciona(ponto); return; } } pontosWindow->adicionaNaPosicao(ponto, pos); return; } } }
void clip_Poligono(Objeto obj, DisplayFile* virt_clip){ //CHANCE DE DAR MERDA EM TUDO POR COMPARAR IGUALDADE ENTRE DOUBLES //Inicializando as 3 listas ListaEnc<Coordenada> pontos_obj; ListaEnc<Coordenada> pontos_obj_ori;//usado para percorrer os pontos do objeto. pontos_obj será modificado. ListaEnc<Coordenada> pontos_window; ListaEnc<Coordenada> pontos_window_ori; ListaEnc<Coordenada> entrantes; ListaEnc<Coordenada>* pontos_obj_ = obj.pontos(); for(int i =0; i<pontos_obj_->getSize();i++){ pontos_obj.adiciona(*pontos_obj_->posicaoMem(i)); pontos_obj_ori.adiciona(*pontos_obj_->posicaoMem(i)); } pontos_window.adiciona(Coordenada(-1,-1,1)); pontos_window.adiciona(Coordenada(-1,1,1)); pontos_window.adiciona(Coordenada(1,1,1)); pontos_window.adiciona(Coordenada(1,-1,1)); pontos_window_ori.adiciona(Coordenada(-1,-1,1)); pontos_window_ori.adiciona(Coordenada(-1,1,1)); pontos_window_ori.adiciona(Coordenada(1,1,1)); pontos_window_ori.adiciona(Coordenada(1,-1,1)); bool gambiarraTudoDentro = true; //percorrendo os segmentos de reta do polígono e montando as 3 listas Elemento<Coordenada>* it_objeto = pontos_obj_ori.getHead(); for(int i =0; i<pontos_obj_ori.getSize();i++){ Coordenada pontoA = *pontos_obj_ori.posicaoMem(i); Coordenada pontoB = *pontos_obj_ori.posicaoMem((i+1) % (pontos_obj_ori.getSize())); it_objeto = it_objeto->_next; if(rcCode(pontoA)==0){ // A dentro; if(rcCode(pontoB)!=0){ //pontoB fora; //caso dentro-fora Objeto reta(" ", Reta, false); reta.adiciona(pontoA); reta.adiciona(pontoB); Objeto *nova_reta = reta_clippada(reta); ListaEnc<Coordenada>* pontos_reta = nova_reta->pontos(); Coordenada novoB = *pontos_reta->posicaoMem(1);//pode dar problema de índice; insereNaWindow(&pontos_window, novoB); insereNoObjeto(&pontos_obj, pontoA, novoB); gambiarraTudoDentro = false; }else{ // cout << "dentro dentro" << endl; } } else{ gambiarraTudoDentro = false; Objeto reta(" ", Reta, false); reta.adiciona(pontoA); reta.adiciona(pontoB); Objeto *nova_reta = reta_clippada(reta); if(rcCode(pontoB)==0){ //pontoB dentro; //caso fora-dentro; ListaEnc<Coordenada>* pontos_reta = nova_reta->pontos(); Coordenada novoA = *pontos_reta->posicaoMem(0);//pode dar problema de índice; insereNaWindow(&pontos_window, novoA); insereNoObjeto(&pontos_obj, pontoA, novoA); entrantes.adiciona(novoA); } else{ //caso fora-fora if(nova_reta==0){ continue; } //cortando 2 pontos da window: ListaEnc<Coordenada>* pontos_reta = nova_reta->pontos(); Coordenada novoA = *pontos_reta->posicaoMem(0);//pode dar problema de índice; Coordenada novoB = *pontos_reta->posicaoMem(1);//pode dar problema de índice; insereNaWindow(&pontos_window, novoA); insereNaWindow(&pontos_window, novoB); insereNoObjeto(&pontos_obj, pontoA, novoA, novoB); entrantes.adiciona(novoA); } } } while(!entrantes.listaVazia()){ Objeto* novo = new Objeto(obj.nome(), obj.getTipo(), obj.isPreenchido()); Coordenada inicial = entrantes.retiraDoInicio(); Coordenada atual = inicial; novo->adiciona(atual); Coordenada* it_pontos_obj = pontos_obj.posicaoMem(0); Coordenada* it_pontos_window = pontos_window.posicaoMem(0); //ajustando iteradores para as posićões corretas. bool varreWindow =false; int fuck1=0, fuck2=0; do{ if(varreWindow){ while(!igual(it_pontos_window->getX(), atual.getX()) || !igual(it_pontos_window->getY(),atual.getY())){ it_pontos_window = pontos_window.posicaoMem(fuck1); fuck1 = (fuck1+1) % pontos_window.getSize(); } it_pontos_window = pontos_window.posicaoMem(fuck1); fuck1 = (fuck1+1) % pontos_window.getSize(); atual = *it_pontos_window; // cout << "adicionou" << endl; cout<< atual.getX() << ", " << atual.getY() << endl; novo->adiciona(atual); if(gambs_pontoPertence(pontos_window_ori, atual)){ continue; } varreWindow = false; } else{ while(!igual(it_pontos_obj->getX(), atual.getX()) || !igual(it_pontos_obj->getY(),atual.getY())){ it_pontos_obj = pontos_obj.posicaoMem(fuck2); fuck2 = (fuck2+1) % pontos_obj.getSize(); } it_pontos_obj = pontos_obj.posicaoMem(fuck2); fuck2 = (fuck2+1) % pontos_obj.getSize(); atual = *it_pontos_obj; novo->adiciona(atual); if(gambs_pontoPertence(pontos_window, atual)){ varreWindow = true; continue; } if(gambs_pontoPertence(pontos_obj_ori, atual)){ continue; } varreWindow = true; } }while(!igual(atual.getX(), inicial.getX()) || !igual(atual.getY(), inicial.getY()));//atual!=inicial virt_clip->adiciona(novo); } if(gambiarraTudoDentro){ ListaEnc<Coordenada>* pontos_obj_ = obj.pontos(); Objeto* novo = new Objeto(obj.nome(), obj.getTipo(), obj.isPreenchido()); for(int i =0; i<pontos_obj_->getSize();i++){ novo->adiciona(*pontos_obj_->posicaoMem(i)); } virt_clip->adiciona(novo); } }
void ViewPort::calculeCoordenadaVP(Coordenada* pontoObjeto){ Coordenada* startWindow = window->CPPstart; Coordenada* endWindow = window->CPPend; pontoObjeto->setX((((pontoObjeto->getX() - startWindow->getX()) / (endWindow->getX() - startWindow->getX())) * (end->getX() - start->getX())) + 10); pontoObjeto->setY((((1 - ((pontoObjeto->getY() - startWindow->getY()) / (endWindow->getY() - startWindow->getY()))) * (end->getX() - start->getX()))) + 10); }