[OpenGL] Coordenadas polares | ZWAME Fórum
[OpenGL] Coordenadas polares
Discussão em 'Programação' iniciada por Fork, 11 de Abril de 2009. (Respostas: 8; Visualizações: 2352)
Estou a fazer um trabalho em OpenGL. Em suma um boneco tem de navegar por um terreno em busca de uns objectos. Para isso dispõe de um detector.
Ok o meu problema agora é na implementação do detector ("radar") queria usar coordenadas polares para me indicarem a direcção do dito objecto. Ora a direcção do objecto depende da orientação do boneco. Mas não consigo exprimir isso em código.
Como posso dizer que o ângulo "0'" das coordenadas polares é na direcção do agente?
double directionKey(Key key)
double aux1 = key.pos_x - agent.pos_x;
double aux2 = key.pos_z - agent.pos_z;
return atan(aux2/aux1) * RAD;
Tu tens o angulo de direcção do boneco+posição do boneco+posição do objecto...
A partir das duas posições consegues saber o angulo do objecto relativamente ao boneco relativamente ao angulo 0º do sistema de coordendadas e depois é só subtrair o angulo de rotação do boneco e tá feito
EDIT: Para determinar o tal angulo com as duas posições é pegares em difx (diferença dos x's) e dify e fazer tan^-1(dify/difx) (atenção aos casos em que difx=0 e dify=0 que podem ser resolvidos mais facilemnte) e no final tens de verificar o quadrante em que se encontra no circulo trignométrico devido ao facto de uma tangente ser possível com dois pontos diferentes
Desde já o meu obrigado, mas não percebi bem as tuas instruções.
double agent_angle = atan(agent.pos_z/agent.pos_x) * RAD;
double key_angle = atan(key.pos_z/key.pos_x) * RAD;
Assim obtenho o angulo do agente (agent_angle) e o angulo do objecto (key_angle).
Como é que apartir destes obtenho o angulo relativo entre eles?
Isto é o angulo relativo, mas isto não me diz que tenho de rodar o agente X graus para a esquerda ou para a direita. Só diz que a chave está X graus relativos ao agente.
double diff_angle = key_angle - agent_angle;
Bem... essa trigonometria anda mesmo muito mal... aconselho-te a dar uma vista de olhos nos livros de matemática do secundário ou pela Wikipédia a ver se refrescas isso
Aqui fica um rascunho vindo directamente do paint que dá para ter uma ideia de como calculas o angulo global entre o boneco e o objecto... Ao resultado deste é que depois subtrais o angulo do boneco (cuidado com as unidades radiano e graus para não misturares ):
EDIT: Para variar voltei a usar 'Y' em vez de 'Z'... sorry
Tipo não é bem isso que pretendo, talvez me tenha expressado mal, mas na minha imagem abaixo.
O angulo relativo entre o boneco seria sensivelmente 180º, mas o boneco (que está virado para cima) só tem de se virar 90º para a direita para ficar apontado directamente para o objecto. Dizes-me que a estes 180º devo subtrair o angulo do boneco (~60º).
O que eu queria fazer era transformar o angulo 0 na direcção em que o agente está a olhar.
Se percebi bem o que tás a querer fazer então estás a ir pelo caminho errado... toma sempre a origem dos teus cálculos um dos objectos que isso torna as contas bem mais fáceis... Essa situação que demostrast é bem fácil de resolver segundo o algoritmo que te expliquei:
o boneco tem um angulo de 90º;
o angulo entre o boneco e o objecto dá 0º pois o dz=0 e tan-1 (0/difx)=0 logo para o boneco se voltar para o objecto apenas tem de virar -90º (0º-90º)... get it?
Trago boas novas, consegui.
Sim tinhas razão, mas no código não ficou exactamente como disses-te. Tive de ajustar um bocado porque o 0 do referencial é diferente da orientação 0 do agente.
Depois tive de guardar um caso especial, quando a chave está atrás do agente. Enfim, o código ficou assim.
double difx = key.pos_x - agent.pos_x;
double difz = key.pos_z - agent.pos_z;
double key_angle = atan(difz/difx) * RAD;
double agent_orientation = (agent.horizontal_angle) * RAD;
if (agent.pos_x < key.pos_x)
return key_angle + agent_orientation - 90;
else /*if (agent.pos_x > key.pos_x)*/
return key_angle + agent_orientation + 90;
Se tiveres alguma sugestão para melhorar o código sou todo ouvidos. E obrigado pela ajuda.
Inda bem que conseguiste aqui ficam umas sugestões em comentário no código:
//Verifica se difx é zero para não fazeres uma divisão por zero (que é fácil de ver qual o ângulo nesse caso.