/*Dado uma posicao, checa se para alguma direcao existe um control point, e retorna qual direcao esta o mais perto, contando giradas necessárias*/ int searchNearestControl (Grid *g, Position p, Robot *r) { int i, min = 500, best_dir = 0, cont; for(i = 0; i < 6; i++) { /*Conta para chegar o numero de viradas necessarias ja que elas gastam um turno*/ cont = 1 + quickTurn (r->dir, i); Position s = getNeighbor (p,i); while(valid (s, g->m, g->n, g)) { if(isControlPoint (g,s)) { if(cont < min) { min = cont; best_dir = i; break; } } cont++; s = getNeighbor (s, i); } } /*Nao existe control points no mapa*/ if (min == 500) return -1; else return best_dir; }
void AffineDeformationFast::doAffineDeformation() { if(oldControlPoint.size()!=newControlPoint.size()) { return;//控制点形变前后数目不等,不能形变 } if(!isPreComputed) { calcA(); } int i,j; Point tempPoint,qstar; double sumofwqx,sumofwqy; ansPoint=commonPoint; for(i=0;i<ansPoint.size();i++) { if((j=isControlPoint(commonPoint[i]))>=0) { ansPoint[i].xx=newControlPoint[j].xx; ansPoint[i].yy=newControlPoint[j].yy; continue; } sumofwqx=0.0; sumofwqy=0.0; for(j=0;j<oldControlPoint.size();j++) { sumofwqx+=w[i][j]*newControlPoint[j].xx; sumofwqy+=w[i][j]*newControlPoint[j].yy; } qstar.xx=sumofwqx/sumofw[i]; qstar.yy=sumofwqy/sumofw[i]; tempPoint.xx=0; tempPoint.yy=0; for(j=0;j<oldControlPoint.size();j++) { tempPoint.xx+=A[i][j]*(newControlPoint[j].xx-qstar.xx); tempPoint.yy+=A[i][j]*(newControlPoint[j].yy-qstar.yy); } ansPoint[i].xx=tempPoint.xx+qstar.xx; ansPoint[i].yy=tempPoint.yy+qstar.yy; } isComputed=true; }
Action Desviar (Position pos, Grid *grid, Robot *r){ int deve, i, dir_proj, dir_ini; Position p, proj_pos; Projectile *proj; deve = deveDesviar (pos, grid, r); /*Se estivermos num ponto de controle e nao estivermos sendo atacados*/ if (isControlPoint (grid, pos)) { dir_proj = searchNearestProjectile (grid, pos, r); dir_ini = searchNearestRobot (grid, pos, r); /* Caso seja encontrado um projetil numa direcao valida e caso exista municao realizamos uma acao */ if (dir_ini != -1 && dir_proj != -1 && r->bullets > 0 ) { if (dir_proj == r->dir) return SHOOT_CENTER; if (dir_proj == (r->dir + 1)%6) return SHOOT_RIGHT; if (dir_proj == (r->dir + 2)%6) return OBSTACLE_RIGHT; if (dir_proj == (r->dir + 3)%6) return OBSTACLE_CENTER; if (dir_proj == (r->dir + 4)%6) return OBSTACLE_LEFT; if (dir_proj == (r->dir + 5)%6) return SHOOT_LEFT; } } else { if(deve==1) return WALK; else if(deve==-1) { p=getNeighbor (pos, (r->dir+1)%6); if(limiteDoMapa (p, grid->m, grid->n) && (grid->map[p.x][p.y].type == NONE)) return TURN_RIGHT; else return TURN_LEFT; /*vai virar pra esquerda caso a posição da esquerda seja vazia, ou nem a da direita ou da esquerda seja vazia, ai ele vai ter q da uma volta*/ } else {/*sobrou só o caso -2*/ for (i = 0; i < 6; i++){ if (adjacentes[i] == 3){ proj_pos = getNeighbor (pos, i); proj = &grid->map[proj_pos.x][proj_pos.y].object.projectile; if ((proj->dir + 3)%6 == i){ if (r->dir == i) return SHOOT_CENTER; if (r->dir == (i + 3)%6) return OBSTACLE_CENTER; } } } } } return STAND; }
/* Retorna a acao a ser realizada quando a vida do robo eh baixa */ Action acaoSaudavel (Grid *g, Position p) { int i, j, control_dir; Position s; Robot *r = &g->map[p.x][p.y].object.robot; /*Se estiver em cima de um control point, SCORE TIME*/ if (isControlPoint (g, p) && !inimigoAdjacente (p, g, r)) { if (deveDesviar (p, g, r)) return Desviar (p, g, r); return atiraNoInimigo (g, p, r); } else { /*procura algum control point em alguam direcao do robo*/ control_dir = searchNearestControl (g, p, r); /*Caso em nenhuma direcao tem um control point livre andar em uma direcao valida, ou comeca a virar para uma direcao valida*/ if (control_dir == -1) { for(i = r->dir, j = 0; j < 6; i++,j++){ if (i >= 6) i-=6; s = getNeighbor(p,i); if(valid(s, g->m, g->n, g)) { if(i == r->dir) { return WALK; } else { return fastTurn (r->dir, i); } } } /*Se nenhuma posicao em volta eh valida, SAD TIME*/ return STAND; } /*Se encontrou um control point em alguma direcao, comeca a virar e andar em sua direcao*/ else if(control_dir == r->dir) return WALK; else { return fastTurn (r->dir, control_dir); } } }
void AffineDeformationFast::calcA() { int i,j; double sumofwpx,sumofwpy; Point *pstar=new Point[commonPoint.size()]; if(sumofw!=NULL) { delete[] sumofw; sumofw=NULL; } sumofw=new double[commonPoint.size()]; w.clear();//w[非控制点下标][控制点下标] vector<double> tempVector(oldControlPoint.size(),0.0); precomputedpart=commonPoint; for(i=0;i<commonPoint.size();i++) { if(isControlPoint(commonPoint[i])>=0)//是控制点,不需要计算w值 { w.push_back(tempVector); continue; } sumofw[i]=0.0; sumofwpx=0.0; sumofwpy=0.0; for(j=0;j<oldControlPoint.size();j++) { double t1=oldControlPoint[j].xx-commonPoint[i].xx; double t2=oldControlPoint[j].yy-commonPoint[i].yy; t1=1.0/pow(t1*t1+t2*t2,alpha); sumofw[i]+=t1; sumofwpx+=t1*oldControlPoint[j].xx; sumofwpy+=t1*oldControlPoint[j].yy; tempVector[j]=t1; } pstar[i].xx=sumofwpx/sumofw[i]; pstar[i].yy=sumofwpy/sumofw[i]; precomputedpart[i].xx=commonPoint[i].xx-pstar[i].xx; precomputedpart[i].yy=commonPoint[i].yy-pstar[i].yy; w.push_back(tempVector); cleartempMatrix(); for(j=0;j<oldControlPoint.size();j++) { double a=oldControlPoint[j].xx-pstar[i].xx; double b=oldControlPoint[j].yy-pstar[i].yy; tempMatrix[0][0]+=tempVector[j]*a*a; tempMatrix[1][1]+=tempVector[j]*b*b; a*=b; tempMatrix[0][1]+=tempVector[j]*a; tempMatrix[1][0]+=tempVector[j]*a; } double tt,dt=tempMatrix[0][0]*tempMatrix[1][1]-tempMatrix[0][1]*tempMatrix[1][0]; doubleswap(tempMatrix[0][0],tempMatrix[1][1]); tempMatrix[0][0]/=dt; tempMatrix[1][1]/=dt; tempMatrix[0][1]/=(-dt); tempMatrix[1][0]/=(-dt); tt=precomputedpart[i].xx*tempMatrix[0][0]+precomputedpart[i].yy*tempMatrix[1][0]; dt=precomputedpart[i].xx*tempMatrix[0][1]+precomputedpart[i].yy*tempMatrix[1][1]; precomputedpart[i].xx=tt; precomputedpart[i].yy=dt; } A.clear();//A[非控制点下标][控制点下标] for(i=0;i<commonPoint.size();i++) { if(isControlPoint(commonPoint[i])>=0)//是控制点,不需要计算w值 { A.push_back(tempVector); continue; } for(j=0;j<oldControlPoint.size();j++) { Point tempPoint; tempPoint.xx=oldControlPoint[j].xx-pstar[i].xx; tempPoint.yy=oldControlPoint[j].yy-pstar[i].yy; tempVector[j]=w[i][j]*(precomputedpart[i].xx*tempPoint.xx+precomputedpart[i].yy*tempPoint.yy); } A.push_back(tempVector); } delete[] pstar; isPreComputed=true; }