O mais longo

Neste arquivo iremos colocar os problemas já resolvidos (não são problemas "mortos" porque a discussão pode continuar a qualquer altura!)

O mais longo

Mensagempor jap em Terça Mar 06, 2007 10:40 pm

Puseram-me este problema há alguns dias e, confesso, que é algo original (já devem ter percebido da minha infindável colecção de problemas que é *mesmo* difícil alguém surpreender-me com um problema que eu não tenha já visto algures na mesma forma ou noutra parecida!) 8)

É de enunciado extremamente simples, mas não é tão fácil de obter a resposta - a não ser numericamente, num computador ou máquina de calcular programável.

Aqui vai ele. É um "simples" problema de projécteis! :wink:

Lança-se um projéctil ao nível do solo, com velocidade v e ângulo \theta. Sabemos que o ângulo para alcance máximo é \theta=45º. Também já encontrámos o ângulo máximo para o qual o projéctil se afasta sempre de nós, \theta=70,53º, lembram-se?

Pois agora queremos encontrar o ângulo que maximiza o comprimento da trajectória (distância percorrida ao longo do voo no ar). Este ângulo é independente do valor da velocidade.

Alguém que consiga encontrar a resposta? Desafio a fazer primeiro uma simulação numérica...

Missão para .... VBMASTER e mais algum aficionado de programação, computadores e/ou máquinas de calcular?
última vez editado por jap s Terça Mar 06, 2007 10:58 pm, editado 1 vez no total
José António Paixão
Departamento de Física da FCTUC
Avatar do utilizador
jap
Site Admin
Site Admin
 
Mensagens: 6801
Registado: Quinta Nov 09, 2006 9:34 pm
Localização: Univ. de Coimbra

Mensagempor fnbrandao em Terça Mar 06, 2007 10:58 pm

Consideramos a Terra plana?
Avatar do utilizador
fnbrandao
bottom-Quark!
bottom-Quark!
 
Mensagens: 63
Registado: Domingo Fev 25, 2007 10:43 pm

Mensagempor jap em Terça Mar 06, 2007 11:00 pm

fnbrandao Escreveu:Consideramos a Terra plana?


Sim, e sem resistência do ar!
Não há truques. Pretende-se o ângulo máximo para uma dada velocidade (pequena, não tão grande que tenhamos de entrar em conta com a esfericidade da Terra!).
É tão simples como parece, mas obter a resposta analítica é difícil, ou melhor, se calhar não encontrei ainda a maneira mais simples de resolver a questão analiticamente - talvez vocês o consigam! :D
José António Paixão
Departamento de Física da FCTUC
Avatar do utilizador
jap
Site Admin
Site Admin
 
Mensagens: 6801
Registado: Quinta Nov 09, 2006 9:34 pm
Localização: Univ. de Coimbra

Mensagempor vbmaster em Quarta Mar 07, 2007 12:44 am

Gostava de ter a certeza do código que fiz, mas as horas não o permitem.

Ainda com pouca aproximação o resultado obtido aproximou-se bastante de um theta = 1 radiano.

Se não for amanhã vejo melhor o código, agora vou para a cama que isto são dias a mais a dormir muito pouco. :P
Avatar do utilizador
vbmaster
up-Quark!
up-Quark!
 
Mensagens: 464
Registado: Quarta Nov 15, 2006 11:49 pm
Localização: Peniche

Mensagempor jap em Quarta Mar 07, 2007 12:49 am

vbmaster Escreveu:Gostava de ter a certeza do código que fiz, mas as horas não o permitem.

Ainda com pouca aproximação o resultado obtido aproximou-se bastante de um theta = 1 radiano.

Se não for amanhã vejo melhor o código, agora vou para a cama que isto são dias a mais a dormir muito pouco. :P



:hands:

A resposta é
\theta \sim 56,5^\circ o que é muito próximo de 1 rad, como encontraste.

Parabéns, Miguel, o Ás da programação! :lol:

Tem um bom :zzz: e posta amanhã o código com umas explicações para os leigos. :wink:

E para os outros: toca a pensar na solução analítica deste problema...
última vez editado por jap s Quarta Mar 07, 2007 12:51 am, editado 1 vez no total
José António Paixão
Departamento de Física da FCTUC
Avatar do utilizador
jap
Site Admin
Site Admin
 
Mensagens: 6801
Registado: Quinta Nov 09, 2006 9:34 pm
Localização: Univ. de Coimbra

Mensagempor vbmaster em Quarta Mar 07, 2007 12:51 am

wow, hoje vou dormir bem.

Sim, o ângulo que obtive era 0,977 qualquer coisa... mas como a aproximação estava de grau em grau, e o x ao milimetro, podia ser pouco e quis jogar pelo seguro.

Ih ih ih.
Avatar do utilizador
vbmaster
up-Quark!
up-Quark!
 
Mensagens: 464
Registado: Quarta Nov 15, 2006 11:49 pm
Localização: Peniche

Mensagempor vbmaster em Quarta Mar 07, 2007 2:19 pm

Ora bem....vamos lá a isto.

Desta vez só fiz mesmo versão em Scheme, pelo que peço desculpa se provocar algum estrabismo a alguém.

Como em qualquer problema a resolver com recurso aos computadores, a primeira coisa a fazer é indentificar precisamente o que se pede, e conceber mentalmente os passos a executar para chegar ao pretendido - algoritmo.

Neste caso, antes de pôr-mos as mãos no teclado era necessária alguma reflexão. Queria-se portanto, o ângulo de lançamento que proporcionasse a maior viagem pelo ar, ou seja, teriamos de pegar na linha da equação da trajectória (aquele arco que todos devem estar a imaginar), e caso ela "fosse maléavel", extende-la em linha recta e medir o seu comprimento, avaliar esse valor para todos os thetas entre 0 e pi/2 para se averiguar o maior, e a que ângulo correspondia - que seria o resultado a retornar.

Encontrar tal equação não seria díficil, basta apenas integrar (não, não é esse integrar que estão a pensar) equação do movimento em x com y que é obtida:

y = \tan(\theta)x - \frac{4.9 x^2}{v_0^2 \cos(\theta)^2}

Posto isto, só havia mesmo mais um problema, como a partir de tal equação obter o comprimento do arco. Bem, isso é simples também, basta considerar que qualquer linha curva pode ser um infinito número de linhas rectas muito pequenas. E como ir obtendo isso? Tão simples como o teorema de pitágoras, ou seja, para determinado x e correspondente y, obtém-se um comprimento em linha recta em relaçao a um outro ponto anterior por:

z = \sqrt{ (x - x_{anterior})^2 + (y - y_{anterior})^2}

Ou seja, se andarmos a obter os valor de y a cada 0,001 de x, basta fazer o teorema de pitágoras acima para se obter uma pequena linha recta que será bastante aproximada à curva (o yanterior é o valor de y obtido para o x da interaçao anterior), ou seja

z = \sqrt{ (0,001)^2 + (y - y_{anterior})^2}

Neste método há só que ter o cuidado de, na queda, adicionar uma módulos para não dar buraco.

Depois, indo-se calculado x's com intervalo de 1mm, basta só parar o loop secundário quando o x for superior ao alcance, e passar para o angulo seguinte, que neste caso fui testanto em intervalos de pi / 180 em pi / 180.


Aqui está o código:

Código: Seleccionar Todos
(define (trajectorias)
  (define (angulos theta dmaximo thetamax)
    (define (posiçoes theta x d dmaximo thetamax)
      (if (> x (/ (* 578 (sin theta) (cos theta)) 9.8))
          (angulos (+ theta (/ pi 180)) (if (> d dmaximo) d dmaximo) (if (> d dmaximo) theta thetamax))
          (posiçoes theta (+ x 0.001) (+ d (sqrt (+ (expt 0.001 2) (expt (abs (- (- (* (tan theta) x) (/ (* 4.9 (expt x 2)) (* 289 (expt (cos theta) 2)))) (- (* (tan theta) (- x 0.001)) (/ (* 4.9 (expt (- x 0.001) 2)) (* 289 (expt (cos theta) 2)))))) 2)))) dmaximo thetamax)))
    (if (> theta (/ pi 2))
        thetamax
        (posiçoes (+ theta (/ pi 180)) 0 0 dmaximo thetamax)))
  (angulos (/ pi 180) 0 0))


Nota: a velocidade inicial está com um valor de 17 m/s, mas podia estar com qualquer outro, desde que nao fosse pequeno de mais, pois tornaria o intervalo em que calculo os x's grande de mais, havendo maior incerteza no resultado obtido.


Posso explicar melhor depois se for necessário, agora tenho desporto escolar...


Resultado:

> (time (trajectorias))
cpu time: 7735 real time: 7937 gc time: 2533
0.9773843811168255
última vez editado por vbmaster s Quarta Mar 07, 2007 6:50 pm, editado 1 vez no total
Avatar do utilizador
vbmaster
up-Quark!
up-Quark!
 
Mensagens: 464
Registado: Quarta Nov 15, 2006 11:49 pm
Localização: Peniche

Mensagempor vbmaster em Quarta Mar 07, 2007 5:07 pm

Entretanto, e visto que o resultado certo ter uma casa decimal, e eu estava a calcular os ângulos de pi / 180 em pi / 180, ou seja, de grau em grau, passei a calcular de pi / 360 em pi / 360, ou seja, de meio em meio grau.

Desta forma, o resultado demora mais tempo a calcular, mas ei-lo, o valor certo:

Código: Seleccionar Todos
(define (trajectorias)
  (define (angulos theta dmaximo thetamax)
    (define (posiçoes theta x d dmaximo thetamax)
      (if (> x (/ (* 578 (sin theta) (cos theta)) 9.8))
          (angulos (+ theta (/ (/ pi 180) 2)) (if (> d dmaximo) d dmaximo) (if (> d dmaximo) theta thetamax))
          (posiçoes theta (+ x 0.001) (+ d (sqrt (+ (expt 0.001 2) (expt (abs (- (- (* (tan theta) x) (/ (* 4.9 (expt x 2)) (* 289 (expt (cos theta) 2)))) (- (* (tan theta) (- x 0.001)) (/ (* 4.9 (expt (- x 0.001) 2)) (* 289 (expt (cos theta) 2)))))) 2)))) dmaximo thetamax)))
    (if (> theta (/ pi 2))
        thetamax
        (posiçoes (+ theta (/ (/ pi 180) 2)) 0 0 dmaximo thetamax)))
  (angulos (/ pi 180) 0 0))



> (time (trajectorias))
cpu time: 25500 real time: 26036 gc time: 8200
0.9861110273767973



56,5 certos. ;)
Avatar do utilizador
vbmaster
up-Quark!
up-Quark!
 
Mensagens: 464
Registado: Quarta Nov 15, 2006 11:49 pm
Localização: Peniche

Mensagempor jap em Quarta Mar 07, 2007 6:45 pm

Obrigado, Miguel!

Explicação perfeita :wink:
Haja outros que re(escrevam) o mesmo algoritmo noutras linguagens,
Eu farei em Python!

:D
José António Paixão
Departamento de Física da FCTUC
Avatar do utilizador
jap
Site Admin
Site Admin
 
Mensagens: 6801
Registado: Quinta Nov 09, 2006 9:34 pm
Localização: Univ. de Coimbra

Mensagempor fnbrandao em Quarta Mar 07, 2007 7:05 pm

E que tal em pseudo-linguagem?...Sempre fica mais universal :roll:
Avatar do utilizador
fnbrandao
bottom-Quark!
bottom-Quark!
 
Mensagens: 63
Registado: Domingo Fev 25, 2007 10:43 pm

Mensagempor jap em Quarta Mar 07, 2007 11:01 pm

Versão pitónica:


Código: Seleccionar Todos
"""
Programa para calcular o angulo de lancamento que maximiza o comprimento
da trajectoria de um projectil (nao confundir com alcance maximo!)
"""

from math import *

def deg(theta):
    "transforma o angulo dado em radianos em graus"
    return 180*theta/pi

def comprimento(theta,v=1,dt=1E-4):
    "Comprimento da trajectoria"
   
    v0x = v*cos(theta)
    v0y = v*sin(theta)
    tmax = v0y/g  # tempo para atingir o cimo da parabola
   
    t,s = 0,0

    while t < tmax:
        vy = v0y-g*t
        dx = v0x*dt
        dy = vy*dt
        ds = sqrt(dx**2 +dy**2)
        s += ds
        t += dt
    return 2*s # 2 ramos de parabola simetricos, um a subir, outro a descer

# programa principal

g = 9.8
theta = 0
theta_max = 0
dtheta=1E-4
smax = 0

while theta < pi/2:
    s = comprimento(theta)
    if s > smax:
        smax = s
        theta_max = deg(theta)
    theta += dtheta


print "maximo comprimento = ", smax
print "theta max = ",theta_max
última vez editado por jap s Quinta Mar 08, 2007 2:39 am, editado 14 vezes no total
José António Paixão
Departamento de Física da FCTUC
Avatar do utilizador
jap
Site Admin
Site Admin
 
Mensagens: 6801
Registado: Quinta Nov 09, 2006 9:34 pm
Localização: Univ. de Coimbra

Mensagempor vbmaster em Quarta Mar 07, 2007 11:18 pm

definitivamente, python não rula! :tease:
Avatar do utilizador
vbmaster
up-Quark!
up-Quark!
 
Mensagens: 464
Registado: Quarta Nov 15, 2006 11:49 pm
Localização: Peniche

Mensagempor jap em Quarta Mar 07, 2007 11:31 pm

vbmaster Escreveu:definitivamente, python não rula! :tease:



Ai rula, rula, talvez gostes mais com o código devidamente identado! (vê acima) :lol:

PS - Consigo fazer o código em python ainda mais compacto do que o teu em scheme (e com menos parêntesis :mock:), se me desafiares! :confident:
José António Paixão
Departamento de Física da FCTUC
Avatar do utilizador
jap
Site Admin
Site Admin
 
Mensagens: 6801
Registado: Quinta Nov 09, 2006 9:34 pm
Localização: Univ. de Coimbra

Mensagempor vbmaster em Quarta Mar 07, 2007 11:47 pm

jap Escreveu:
vbmaster Escreveu:definitivamente, python não rula! :tease:



Ai rula, rula, talvez gostes mais com o código devidamente identado! (vê acima) :lol:

PS - Consigo fazer o código em python ainda mais compacto do que o teu em scheme (e com menos parêntesis :mock:), se me desafiares! :confident:


Eu digo isso mais pela estrutura "pouco estruturada" da linguagem (gosto tanto das { } :P ), mas já agora gostava de ver isso (não duvido mesmo nada que seja possível, mas queria ver).
Avatar do utilizador
vbmaster
up-Quark!
up-Quark!
 
Mensagens: 464
Registado: Quarta Nov 15, 2006 11:49 pm
Localização: Peniche

Mensagempor jap em Quinta Mar 08, 2007 2:31 am

Aqui vai, Miguel, em estilo funcional...


Código: Seleccionar Todos
from math import *
from operator import add

getmax = lambda a,f: a[map(f,a).index(max(map(f,a)))]

deg = lambda x: 180*x/pi

def comprimento(theta,v=17.0,ntimes=1000):
    dt = (v*sin(theta)/g)/ntimes
    return 2*dt*reduce(add, map(lambda t: sqrt((v*cos(theta))**2+(v*sin(theta)-9.8*t)**2),[n*dt for n in range(ntimes+1)]))

print deg(getmax([n*(pi/2)/180 for n in range(180+1)],comprimento))


Já compete com o Scheme, não? :lol: Ainda consigo ser mais sintéctico: posso escrever todo o programa numa só (longa) linha...críptica! :shock:

Como vês, posso deitar fora todos os statements (ainda há lá uma atribuição que é trivial descartar, mas assim é mais legível) e usar apenas expressões e funções em python, como em scheme, se me der na real gana!

Claro que este não é o estilo mais pitónico, mas é interessante a versatilidade de se poder programar em estilo imperativo, funcional, ou por objectos ....

Mas não tenho é a possibilidade de usar notação RPN ! :?
José António Paixão
Departamento de Física da FCTUC
Avatar do utilizador
jap
Site Admin
Site Admin
 
Mensagens: 6801
Registado: Quinta Nov 09, 2006 9:34 pm
Localização: Univ. de Coimbra

Próximo

Voltar para Problemas resolvidos

Quem está ligado

Utilizadores a navegar neste fórum: Nenhum utilizador registado e 2 visitantes