Em um post anterior eu comentei sobre a importância do operador módulo e como ele pode, além de simplesmente dar o resto da divisão, também ajudar a criar ciclos numéricos, muito úteis quando precisamos seguir uma sequência numérica em que, ao chegar no final, a contagem reinicia.
O limite do módulo
A abordagem é totalmente funcional, mas tem uma limitação na forma do ciclo: o módulo sobe em linha reta e, ao chegar no limite, cai bruscamente de volta ao zero, formando uma onda “dente de serra”. Se você precisar de algo que suba e desça suavemente, passando por valores intermediários nos dois sentidos, o módulo não resolve, pois ele nunca “volta” de forma gradual, só reinicia.
Seno e cosseno
Neste ponto, para nos ajudar, encontramos as funções periódicas, sendo as famigeradas funções seno e cosseno as principais candidatas. Daqui pra frente vamos trabalhar apenas com a função seno, mas saiba que tudo deste post se aplica a ambas, com a diferença de que a função cosseno está adiantada noventa graus em relação à função seno (mais tarde explico isso também).
A primeira coisa que precisamos definir é que a função tem sua imagem, ou seja, o conjunto de resultados possíveis, no intervalo : ela fica subindo e descendo entre esses dois valores. Outro detalhe importante é que o seno trabalha em radianos, e não em graus: uma volta completa, os 360°, equivale a radianos. Por isso, no gráfico abaixo, a onda leva unidades no eixo X para completar um ciclo.
Amplitude: a altura da onda
Neste momento pode surgir uma dúvida: como algo que só varia entre -1 e 1 pode ser útil para mim? A resposta é simples: quando precisarmos que ela varie entre números maiores, podemos simplesmente multiplicá-la por um valor que consideremos nosso limite. Aqui vamos chamar esse valor de e teremos . Considerando igual a 5, temos o gráfico a seguir:
O que esse representa é uma grandeza chamada amplitude, ou seja, quanto a onda se afasta, para cima e para baixo, da sua linha central (por enquanto o eixo X, mas isso vai mudar daqui a pouco). Como amplitude é uma medida de distância, e distância negativa não existe, definimos formalmente como . Um negativo apenas espelha a onda, deixando-a de cabeça para baixo.
Período: o tamanho do ciclo
Agora finalmente temos uma função mais útil, variando até qualquer valor que eu deseje, mas entra uma nova questão: estamos presos num ciclo de tamanho fixo, ou seja, a onda sempre leva a mesma distância no eixo X para subir, descer e voltar ao ponto de partida, que no nosso caso é . A essa distância damos o nome de período, comumente representado por .
Aqui as coisas ficam divertidas, pois podemos controlar o período multiplicando o por um valor dentro da função seno. Esse valor é chamado de frequência angular e costuma ser representado pela letra grega (ômega):
Mas por que isso muda o período? O seno completa um ciclo quando o seu argumento vai de até . Como agora o argumento é , o ciclo se completa quando , ou seja, quando . Esse é o nosso novo período:
O pode ser qualquer número diferente de zero; se for negativo, a onda apenas fica espelhada, e por isso a fórmula usa o valor absoluto. Perceba que, quanto maior o , mais rápido o argumento chega em e menor fica o período.
Na prática, porém, geralmente sabemos qual período queremos e precisamos descobrir o . Para isso basta isolá-lo na fórmula acima (considerando positivo):
Se quisermos, por exemplo, que o período seja de 1 unidade no eixo X, temos , e a nossa função fica :
Já para um ciclo completo a cada 5 unidades, é só trocar o : , e a função fica:
Olhando no gráfico, podemos verificar o ocorrido:
Um pequeno parêntese sobre o nome: a frequência “comum”, , diz quantos ciclos acontecem a cada unidade do eixo X. A frequência angular é essa mesma ideia medida em radianos, ou seja, .
Linha central: subindo e descendo a onda
Perceba que a variação ainda vai de um valor negativo até esse mesmo valor positivo, mas pode ser que precisemos que ela ocorra mais acima ou mais abaixo. Para isso, vamos introduzir um novo parâmetro na nossa equação, o , que permitirá deslocar a onda para cima e para baixo. Isso é bem simples: basta somar ao que temos até agora:
Desta forma, agora toda a onda é deslocada em unidades. Se, por exemplo, definirmos como 10, nosso gráfico se deslocará 10 unidades para cima, com a linha central agora em 10, não mais iniciando no zero nem tocando o eixo X:
Exemplo: a temperatura ao longo do ano
Apenas com estes três parâmetros podemos, por exemplo, modelar alguns probleminhas simples: vamos supor que, num ciclo de 365 dias, a temperatura de uma cidade, em Celsius, começa em 20 graus na primavera, atinge um pico de 30 graus no verão, volta aos 20 graus no outono e chega a 10 graus no inverno. Isolando cada valor, podemos chegar a algumas conclusões:
- A temperatura oscila entre 10 e 30 graus, então sua linha central é a média dos dois, , e esse é o nosso deslocamento vertical . (Como o seno começa justamente na linha central, isso bate com os 20 graus do início do ciclo.)
- A partir da linha central, a temperatura sobe ou desce no máximo 10 graus, assim sabemos que esse é o nosso . Ele também pode ser calculado como metade da distância entre o máximo e o mínimo, .
- O ciclo completo de medições é de 365 dias, ou seja, nosso período é , logo .
As duas primeiras contas valem para qualquer onda da qual você conheça o máximo e o mínimo:
E chegamos à nossa função final:
E o nosso gráfico de temperatura fica:
Neste modelo simples já é possível ter uma noção de como a temperatura varia no decorrer do ano, seus máximos e mínimos e, principalmente, os valores intermediários. É claro que um modelo real é muito mais complexo, mas, para a compreensão básica, isso já ajuda a entender o poder das funções periódicas.
Fase: deslocando a onda no tempo
Mas vamos enriquecer o nosso problema com mais uma restrição: no modelo acima, o dia 0 é o início da primavera, mas, como aqui no Brasil o verão é em janeiro, queremos que o dia 0 seja o início do ano, já no pico da temperatura. Hoje esse pico está no dia , então precisamos deslocar a função de ano para trás. Temos como controlar isso através do (a letra grega fi), que é somado ao argumento da função seno:
Para entender o efeito do , basta colocar o em evidência:
Somar ao faz a função mostrar agora o que só mostraria mais adiante: no dia 0 ela já vale o que antes valia no dia . Ou seja, a onda inteira é deslocada unidades para a esquerda. Usando a convenção de que valores positivos são deslocamentos para a direita, o número exato que será deslocado é:
Assim, para trazer o pico para o dia zero, precisamos mover a curva um quarto de ano para a esquerda, ou seja, um deslocamento de . Podemos desenvolver:
Se aplicarmos ao nosso modelo, temos:
Por que o cosseno está adiantado
E aqui cumpro a promessa do início do post: o deslocamento de fase que encontramos, , é justamente um quarto de volta, os tais noventa graus, e é exatamente a diferença entre seno e cosseno. Vale a identidade , então nossa função final pode ser escrita como .
É isso que significa dizer que o cosseno está “adiantado” noventa graus: ele já começa no pico onde o seno só chega depois de um quarto de ciclo. Na prática, escolher seno ou cosseno é só uma questão de qual ponto do ciclo você quer no instante zero.
Juntando tudo em código
Para fechar, vamos voltar ao código. Juntando tudo o que vimos, podemos escrever uma função que gera qualquer uma dessas ondas e compará-la com o ciclo feito com o módulo no início do post:
import math
def onda(x, amplitude, periodo, centro=0.0, fase=0.0):
omega = 2 * math.pi / periodo
return amplitude * math.sin(omega * x + fase) + centro
for x in range(11):
dente_de_serra = x % 5
suave = onda(x, amplitude=2, periodo=5, centro=2)
print(f"{x:2}: {dente_de_serra} {suave:.2f}")
0: 0 2.00
1: 1 3.90
2: 2 3.18
3: 3 0.82
4: 4 0.10
5: 0 2.00
6: 1 3.90
7: 2 3.18
8: 3 0.82
9: 4 0.10
10: 0 2.00
Os dois ciclos têm período 5 e ficam entre 0 e 4, mas enquanto o módulo sobe e despenca, a onda sobe e desce passando por todos os valores intermediários. E, como a função aceita qualquer número real, basta trocar o pelo tempo decorrido para ter um botão pulsando na tela, um LED “respirando” ou um inimigo flutuando para cima e para baixo em um jogo.
Resumo dos parâmetros
Para consulta rápida, um resumo dos parâmetros de :
| Parâmetro | O que controla | Como calcular |
|---|---|---|
| quanto a onda sobe e desce | ||
| o período | ||
| o deslocamento horizontal | ||
| a linha central |