# #Copyright (C) 2012 Shams Karim Valibhai #Escola Secundária da Ramada # #This program is free software; you can redistribute it and/or modify it under #the terms of the GNU General Public License as published by the Free Software #Foundation; either version 2 of the License, or (at your option) any later #version. # #This program is distributed in the hope that it will be useful, but WITHOUT #ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. # # -*- coding: cp1252 -*- from visual import * scene.height=1500 scene.width=1400 #Variaveis menu="0" menu1="0" dt=0.001 t=0 posicao=0 #Funções def mola (mola,a,b,c,d,e): #a e b são os objetos/c é o que vai regular a largura da mola/d controla o numero de espiras/e é o desvio em x (serve para pôr as molas em paralelo) x=(arange(0,(a.pos.y-b.pos.y),0.08)) mola.y=a.pos.y-x mola.x=e+a.pos.x+0.25*c*sin((d/(a.pos.y-b.pos.y))*(x)) mola.z=a.pos.z+0.25*c*cos((d/(a.pos.y-b.pos.y))*(x)) return mola def pedido(a,b,c): while 1==1: pedido=input("\nInsira o valor d"+str(c)+" "+str(a)+str(b)+":") try: pedido=float(pedido) if pedido <=0 and a!="fator de amortecimento da mola" and (b!=", em metros" or c!="o"): #Os valores nao podem ser menores ou iguais a 0, excepto o fator de amortecimento e os desvios no movimento com 2 corpos print ("\n"+str(c.upper())+" "+str(a)+" precisa de ter um valor positivo.") elif (pedido <=0 or pedido>1) and a=="fator de amortecimento da mola": print ("\nO valor inserido deve estar no intervalo ]0,1].") else: break except: print("\nTem de inserir um número.") return pedido def saida_menu(menu,escolha): while menu!="0" and menu != "99": if escolha in ["s","sim"]: menu="99" elif escolha in ["n","não"]: menu="0" else: escolha=str(input("\nPor favor responda sim (s) ou não (n):")) return str(menu) #Menu while menu != "99": menu1="0" if menu == "0": #Escolher a simulação print("\n1.Corpo suspenso por 1 mola (teto-mola-corpo) \n2.Dois corpos e 2 molas (teto-mola1-corpo1-mola2-corpo2) \n3.Molas em paralelo e mola equivalente \n4.Arrastar objeto com o rato") menu=str(input("Insira o número da simulação desejada:")) while menu not in ["1","2","3","4"]: print ("\nPor favor escolha uma das duas opções, inserindo apenas o número dessa opção.") menu=str(input("\nInsira o número da simulação desejada:")) elif menu=="1": #Escolher entre M.H.S. e M.H.A. simulacao=float(menu) while menu1 != "1" and menu1 !="2" and menu1 != "3": print("\n1.Movimento harmónico simples \n2.Movimento harmónico amortecido \n3.Voltar atrás") menu1=str(input("Escolha entre um dos tipos de movimento ou volte ao menu anterior:")) if menu1=="3": #Voltar ao menu inicial menu="0" while menu1 != "1" and menu1 !="2" and menu1 != "3": print ("\nPor favor escolha uma das três opções, inserindo apenas o número dessa opção.") menu1=str(input("\nInsira o número da opção desejada:")) if menu1=="3": menu="0" if menu1 == "1" or menu1 == "2": #Variaveis para M.H.S./M.H.A. movimento=int(menu1)-1 #movimento=0 para M.H.S. e movimento=1 para M.H.A. predefinido=str(input("\nDeseja utilizar os parâmetros predefinidos para o movimento (s) ou inserir os seus próprios parâmetros (n)?")) while predefinido not in ["s","n","sim","não"]: predefinido=str(input("\nPor favor responda sim (s) ou não (n):")) if predefinido in ["s","sim"]: amplitude=8 b=0.15 massa1=10 k1=80 else: if movimento==0: amplitude=pedido("amplitude do movimento",", em metros","a") if movimento==1: amplitude=pedido("amplitude inicial do movimento",", em metros","a") b=pedido("fator de amortecimento da mola",", que tem de estar no intervalo ]0,1]","o") massa1=pedido("massa do corpo",", em kg","a") k1=pedido("constante elástica da mola",", em N/m","a") if movimento == 0: print("\nMassa do corpo: "+str(massa1)+"kg\nConstante elástica da mola: "+str(k1)+"N/m\nAmplitude do movimento: "+str(amplitude)+"m") if movimento == 1: print("\nMassa do corpo: "+str(massa1)+"kg\nConstante elástica da mola: "+str(k1)+"N/m\nAmplitude do movimento: "+str(amplitude)+"m\nFator de amortecimento: "+str(b)) escolha=str(input("\nDeseja iniciar a simulação? (Pode voltar atrás para mudar algum dos parâmetros ou o tipo de movimento) (s/n):")) menu=saida_menu (menu,escolha) elif menu=="2": #Movimento com 2 corpos e 2 molas simulacao=float(menu) predefinido=str(input("\nDeseja utilizar os parâmetros predefinidos para o movimento (s) ou inserir os seus próprios parâmetros (n)?")) while predefinido not in ["s","n","sim","não"]: predefinido=str(input("\nPor favor responda sim (s) ou não (n):")) if predefinido in ["s","sim"]: desvio1=2 desvio2=5 massa1=15 massa2=10 k1=80 k2=90 distancia=12 else: print("\nValores positivos equivalem a desvios para cima e um dos corpos pode ter um desvio nulo.") desvio1=pedido("desvio do corpo 1 em relação à posição de equílbrio",", em metros","o") desvio2=pedido("desvio do corpo 2 em relação à posição de equílbrio",", em metros","o") while desvio1==0 and desvio2==0: print ("\nApenas um dos corpos pode ter um desvio nulo.") desvio1=pedido("desvio do corpo 1 em relação à posição de equílbrio",", em metros","o") desvio2=pedido("desvio do corpo 2 em relação à posição de equílbrio",", em metros","o") massa1=pedido("massa do corpo 1",", em kg","a") massa2=pedido("massa do corpo 2",", em kg","a") k1=pedido("constante elástica da mola 1",", em N/m","a") k2=pedido("constante elástica da mola 2",", em N/m","a") distancia=pedido("distância entre o corpo 1 e o corpo 2 na posição de equílibrio",", em metros","a") while distancia <= desvio2: print("\nA distância entre os corpos necessita de ser maior do que o desvio do corpo 2, ou este corpo irá ficar à altura do corpo 1.") distancia=pedido("distância entre o corpo 1 e o corpo 2 na posição de equílibrio",", em metros","a") print("\nMassa do corpo 1: "+str(massa1)+"kg\nMassa do corpo 2: "+str(massa2)+"kg\nConstante elástica da mola 1: "+str(k1)+"N/m\nConstante elástica da mola 2: "+str(k2)+"N/m\nDesvio do corpo 1: "+str(desvio1)+"m\nDesvio do corpo 2: "+str(desvio2)+"m\nDistância entre os dois corpos: "+str(distancia)+"m") escolha=str(input("\nDeseja iniciar a simulação? (Pode voltar atrás para mudar algum dos parâmetros ou a simulação desejada) (s/n):")) menu=saida_menu(menu,escolha) elif menu=="3": #Movimento com 2 molas em paralelo simulacao=float(menu) print("\nA mola 1 e a mola 2 serão as que se vão encontrar em paralelo.") k1=pedido("constante elástica da mola 1",", em N/m","a") k2=pedido("constante elástica da mola 2",", em N/m","a") k3=pedido("constante elástica da mola 3",", em N/m (que para fazer de mola equivalente terá de ter o valor: "+str(k1+k2)+"N/m)","a") if k3!=k1+k2: print("\nEscolheu um valor de constante elástica para a mola 3 diferente do recomendado, os movimentos não serão iguais.") massa1=10 desvio1=15 print("\nConstante elástica da mola equivalente: "+str(k3)+"N/m\n\nSerão utilizados dois corpos com massa 10kg e os movimentos terão 15m de amplitude.") escolha=str(input("\nDeseja iniciar a simulação? (Pode voltar atrás para mudar algum dos parâmetros ou a simulação desejada) (s/n):")) menu=saida_menu(menu,escolha) elif menu=="4": simulacao=float(menu) menu="99" mola1=curve() mola2=curve() mola3=curve() # Movimento harmónico simples (H.M.S.) e movimento harmónico amortecido (H.M.A.) if simulacao==1 and (movimento==0 or movimento==1): wo=sqrt(k1/massa1) #Corpo cubo1=sphere(pos=(0,0,0),radius=(0.1*float(massa1)), color=color.blue) folga=5+2*cubo1.radius #Legenda caixa=label(pos=(-10,5,0)) if movimento==0: caixa2=label(pos=(-10,3,0), text="velocidade angular: "+str("%.2f" %(wo))+" rad/s") elif movimento==1: caixa2=label(pos=(-10,3,0), text="velocidade angular: "+str("%.2f" %(wo*sqrt(1-((b)**2))))+" rad/s") #A velocidade angular no M.H.A. é igual a wo*sqrt(1-b**2) #Objetos tecto=box(pos=(0,folga+amplitude,0),size=(0.5*amplitude,0.05*amplitude,0.5*amplitude),color=color.blue) chao=box(pos=(0,-amplitude-folga,0),size=(3*amplitude,0.2,3*amplitude),color=color.white) suporte=curve(radius=0.15*cubo1.radius,x=0.5*amplitude,y=arange(chao.y,tecto.y+0.1,0.1)) curva=curve(radius=0.15*cubo1.radius,x=(0.5*amplitude)/2+((0.5*amplitude)/2)*cos(arange(0,pi,0.1)),y=tecto.y+((0.5*amplitude)/2)*sin(arange(0,pi,0.1))) exemplo=box(size=(1,1,1),pos=(-0.25*amplitude,0.6+chao.y,0),color=color.orange) while true: rate(1000) #Mola mola(mola1,tecto,cubo1,cubo1.radius,120,0) #Movimento cubo1.pos.y=posicao t=t+0.001 if movimento==0: posicao=amplitude*sin((wo*t)+pi/2) caixa.text="velocidade: "+str("%.2f" %(amplitude*wo*cos((wo*t)+pi/2)))+" m/s" else: posicao=((exp(-b*t))*(amplitude*sin((wo*t)+pi/2))) #A velocidade é obtida a partir da derivada da funçao posição caixa.text="velocidade: "+str("%.2f" %(amplitude*(-b*exp(-b*t)*sin((wo*t)+pi/2)+wo*exp(-b*t)*cos((wo*t+pi/2)))))+" m/s" if abs(amplitude*(-b*exp(-b*t)*sin((wo*t)+pi/2)+wo*exp(-b*t)*cos((wo*t+pi/2))))<0.005 and -0.00001 tecto.y - folga: cubo1.pos.y = tecto.y - folga elif cubo1.pos.y < -(tecto.y - folga): cubo1.pos.y = -(tecto.y - folga) #Voltar à origem if scene.kb.keys: l=scene.kb.getkey() if l=="0": cubo1.pos=(0,0,0) while true: #Movimento do objeto rate(1000) informacao.text="Clique para parar o movimento\nAmplitude: "+str("%.2f" % amp)+"m" mola(mola1,tecto,cubo1,cubo1.radius,120,0) Fe=-k1*cubo1.pos.y cubo1.velocity.y=cubo1.velocity.y+(Fe/massa1)*dt cubo1.pos=cubo1.pos+cubo1.velocity*dt if scene.mouse.clicked: break