movimento senoidal

Ver o tópico anterior Ver o tópico seguinte Ir em baixo

movimento senoidal

Mensagem por saim em Sex 30 Dez 2011, 09:51

O que poderia causar um problema na função arcsin(x)? Achei que era só se x fosse maior que 1 ou menor que -1. Mas não.
Deixa eu voltar uns capítulos atrás pra você entender o que está acontecendo.

Estou fazendo um boss que, quanto mais você acerta, mais difícil fica de acertar. Pra fazer isso acontecer, pensei no seguinte: eu prendo ele num ponto e, toda vez que ele for acertado, ele começa a oscilar em torno desse ponto. Como se tivesse uma mola prendendo ele (talvez eu coloque LITERALMENTE uma mola na tela).
Mas, pra fazer esse movimento, existem duas alternativas: ou eu fazia a aceleração depender da distância ao ponto central ou eu usava um movimento senoidal. Optei pela segunda alternativa, por uma série de motivos que não vêm ao caso (eu sempre falo demais, se for explicar ISSO, a pergunta vira "os lusíadas").

Bom, então, pra fazer um movimento senoidal, eu precisei de alguns parâmetros.
origem (ox) - o ponto central do movimento
amplitude (ampx) - vai ser a distância máxima, a partir da origem, que o objeto vai chegar
velocidade angular (angspdx) - vai ser a velocidade do movimento, o que vai determinar a frequência com que o objeto completa o movimento
ângulo (angx) - variando a partir da velocidade angular, determina a posição do objeto a partir da origem e amplitude

E, a cada pancada que eu dou no boss, eu mudo o valor da amplitude, o que aumenta sua velocidade (já que a velocidade angular é constante) e dificulta o próximo acerto.
Agora, antes de chegar ao problema, vou mostrar um pouco de código.

Isso aqui está no step do boss. É o que faz ele mudar de posição. Eu mudei pra space_pressed pra poder acompanhar mais de perto, o movimento.
Código:
x = ox + ampx * sin(degtorad(angx));
angx = (angx + angspdx) mod 360; //o mod talvez seja desnecessário, não sei
Faço o equivalente em y, também.
Agora, imagine só tudo isso funcionando. O boss vai e volta em torno de ox, e chega até ox - ampx e ox + ampx.
E no momento em que eu mudo ampx? O movimento se altera, mas não apenas isso. Nesse momento, o boss dá um salto. Pensei um pouquinho e percebi que, numa amplitude diferente e com o mesmo ângulo, a posição dele tem que mudar MESMO. Só que eu não quero esse salto, quero só que a amplitude mude. Então, (deixa eu colocar isso em destaque...)
tenho que encontrar um ângulo que corresponda à posição atual na nova amplitude
Invertendo a equação x = ox + ampx * sin(degtorad(angx));, podemos perceber que sin(degtorad(angx)) = (x - ox) / amp;, seja qual for a amplitude. Então, defini o NOVO ângulo como
Código:
tempAng = radtodeg(arcsin((x - ox)/ampx));
E fim do problema!

Mas então aconteceu um erro na função arcsin(). E aqui começa minha pergunta.
Em algumas situações, a amplitude diminui. Nesses casos, dependendo da posição, o objeto ficaria além da amplitude, o que CERTAMENTE daria um erro.
Beleza, vamos forçar a barra nesses casos e colocar o objeto no limite. Daí, o ângulo vai resultar em 90 ou -90. Tuudo bem.
Código:
//já mudei a amplitude
if (abs(x - ox) > ampx){ //se a posição está fora da amplitude
   x = ox + ampx * sign(x - ox); //corrige a posição
   }
//verifica se o seno está entre -1 e 1
if abs((x - ox)/ampx)>1{
   show_message("é, isso mesmo!");
   }

//uma vez corrigida a posição, calcula-se o novo ângulo
tempAng = radtodeg(arcsin((x - ox)/ampx));
O erro continua acontecendo. Mesmo sem a mensagem "é, isso mesmo!" aparecer.
Alguém pode me dizer COMO posso estar abusando do arcsin()?

saim

Ranking : Nota B
Número de Mensagens : 2964
Idade : 38
Data de inscrição : 14/01/2011
Notas recebidas : C-D-A-B
Reputação : 121
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 1
   : 0
   : 3

Voltar ao Topo Ir em baixo

Re: movimento senoidal

Mensagem por Markituh em Sex 30 Dez 2011, 10:05

Hmm... Achei um tópico de dúvida na GMC (resolvido) a respeito:
http://gmc.yoyogames.com/index.php?showtopic=463001
Dá uma olhada aí e vê se sana teu problema. Não manjo muito de matemática angular, então não posso falar muita coisa Happy

___________

"Não deixe para amanhã o que se pode fazer hoje"

Links úteis:
Índice de Tutoriais
Manual online do GMS

Markituh

Ranking : Sem avaliações
Número de Mensagens : 2183
Data de inscrição : 11/10/2009
Reputação : 106
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

Voltar ao Topo Ir em baixo

Re: movimento senoidal

Mensagem por saim em Sex 30 Dez 2011, 10:10

Valeu, Markituh! A GMC está bloqueada daqui, mas chegando em casa, eu dou uma olhada.
Enquanto isso, se alguém mais quiser verificar o problema, fique à vontade.

saim

Ranking : Nota B
Número de Mensagens : 2964
Idade : 38
Data de inscrição : 14/01/2011
Notas recebidas : C-D-A-B
Reputação : 121
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 1
   : 0
   : 3

Voltar ao Topo Ir em baixo

Re: movimento senoidal

Mensagem por Markituh em Sex 30 Dez 2011, 10:20

Hmmm... Então me deixe poupar o seu trabalho Very Happy

Pelo que eu li no tópico, o erro de fato é causado porque o número pode estar fora do "domínio" do arcsin, que é entre (-1) e 1. Início e desfecho:
O código do cara é esse:
Código:
var d,a,phi,beta;
d=point_direction(x,y,inst.x,inst.y); //Inst is the object to aim at...
a=(inst.spd*global.Spd)/(8*global.Spd)
; http://global.Spd is a modifier that can be between 0.5 and 3 in increments of .5....
phi=degtorad(inst.direction-d);
beta=a*sin(phi);
d+=radtodeg(arcsin(beta));
E o problema foi sanado desta forma:
Código:
beta = median(-1, a*sin(phi), 1);
Tente usar median nos seus cálculos para ver se resolve.

___________

"Não deixe para amanhã o que se pode fazer hoje"

Links úteis:
Índice de Tutoriais
Manual online do GMS

Markituh

Ranking : Sem avaliações
Número de Mensagens : 2183
Data de inscrição : 11/10/2009
Reputação : 106
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

Voltar ao Topo Ir em baixo

Re: movimento senoidal

Mensagem por MatheusReis em Sex 30 Dez 2011, 10:22

Há algum erro por parte do GameMaker nos cálculos. Nesse caso, eu mesmo limitaria o valor de "(x - ox)/ampx)" para o domínio do arcsin para solucionar(-1 a 1):
Código:
le_sin=(x - ox)/ampx;
tempAng = radtodeg(arcsin(    max(-1,min(1,le_sin))    ));

OBS: Acho que o erro se dá por causa dos arredondamentos que o GameMaker faz por si. Possivelmente em um desses arredondamentos, o fim de calculo do seno saiu com módulo maior que 1. Se for 1.00001 ou -1.00001, já complicou sua vida.


EDIT

E a guerra por quem responde antes continua KKKKKKKKKKKKKKKK

MatheusReis

Ranking : Nota A
Número de Mensagens : 1087
Idade : 23
Data de inscrição : 13/01/2010
Notas recebidas : B-A-A
Reputação : 30
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 2
   : 1
   : 0

http://www.mathaeuz.deviantart.com

Voltar ao Topo Ir em baixo

Re: movimento senoidal

Mensagem por PedroX em Sex 30 Dez 2011, 11:17

Tente ver desse modo:
sin(angx) = (x - ox) / amp;
angx = arcsin((x-ox)/amp);
angx = radtodeg(angx);


A parte em negrito é colocada no código.

PedroX

Ranking : Nota C
Número de Mensagens : 6034
Idade : 21
Data de inscrição : 26/07/2008
Notas recebidas : C+B
Reputação : 286
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   :
   :
   :

Voltar ao Topo Ir em baixo

Re: movimento senoidal

Mensagem por saim em Sex 30 Dez 2011, 11:32

Parece que era mesmo um arredondamento. Usar median resolveu.
Estranho o game maker ter sensibilidade pra uma função (arcsin(x - ox)/ampx)) e não ter pra testes (if abs((x - ox)/ampx)>1{).
Vou deixar em aberto, aqui, por um tempo, pro caso de alguém ter uma explicação pra isso, mas até lá, o tópico está resolvido!

saim

Ranking : Nota B
Número de Mensagens : 2964
Idade : 38
Data de inscrição : 14/01/2011
Notas recebidas : C-D-A-B
Reputação : 121
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 1
   : 0
   : 3

Voltar ao Topo Ir em baixo

Re: movimento senoidal

Mensagem por Conteúdo patrocinado Hoje à(s) 04:03


Conteúdo patrocinado


Voltar ao Topo Ir em baixo

Ver o tópico anterior Ver o tópico seguinte Voltar ao Topo

- Tópicos similares

 
Permissão deste fórum:
Você não pode responder aos tópicos neste fórum