From 8bb059f4c4771486e8f4759943ed7b9e52a43a13 Mon Sep 17 00:00:00 2001 From: Pedro Romero Date: Mon, 10 Mar 2025 14:00:45 +0100 Subject: [PATCH] Tab Power --- Docs/Models.aux | 14 ++ Docs/Models.fdb_latexmk | 58 ++++++ Docs/Models.fls | 109 ++++++++++++ Docs/Models.pdf | Bin 0 -> 130191 bytes Docs/Models.synctex.gz | Bin 0 -> 15225 bytes Docs/Models.tex | 83 +++++++++ src/LaunchSim.py | 19 +- src/tabs/geometry_viewer.py | 115 +++--------- src/tabs/tab_coil.py | 296 ++++++++----------------------- src/tabs/tab_drag.py | 192 ++++++-------------- src/tabs/tab_dynamic.py | 307 -------------------------------- src/tabs/tab_power.py | 296 +++++++++++++++++++++++++++++++ src/tabs/tab_search.py | 152 +++------------- src/tabs/tab_simulator.py | 343 +++++++++++------------------------- 14 files changed, 848 insertions(+), 1136 deletions(-) create mode 100644 Docs/Models.aux create mode 100644 Docs/Models.fdb_latexmk create mode 100644 Docs/Models.fls create mode 100644 Docs/Models.pdf create mode 100644 Docs/Models.synctex.gz create mode 100644 Docs/Models.tex delete mode 100644 src/tabs/tab_dynamic.py create mode 100644 src/tabs/tab_power.py diff --git a/Docs/Models.aux b/Docs/Models.aux new file mode 100644 index 0000000..4fd7b33 --- /dev/null +++ b/Docs/Models.aux @@ -0,0 +1,14 @@ +\relax +\@writefile{toc}{\contentsline {section}{\numberline {1}Introducción}{1}{}\protected@file@percent } +\@writefile{toc}{\contentsline {section}{\numberline {2}Bobina e Inductancias}{1}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}Autoinductancia de una espira}{1}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {2.2}Inductancia mutua entre dos espiras coaxiales}{1}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {2.3}Inductancia total de la bobina}{1}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {2.4}Resistencia en el bobinado de cobre}{1}{}\protected@file@percent } +\@writefile{toc}{\contentsline {section}{\numberline {3}Rozamiento Aerodinámico: Coeficiente $b$}{2}{}\protected@file@percent } +\@writefile{toc}{\contentsline {section}{\numberline {4}Dinámica del Proyectil}{2}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {4.1}Caso sin rozamiento}{2}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {4.2}Caso con rozamiento lineal}{2}{}\protected@file@percent } +\@writefile{toc}{\contentsline {section}{\numberline {5}Energía Mecánica}{2}{}\protected@file@percent } +\@writefile{toc}{\contentsline {section}{\numberline {6}Conclusión}{2}{}\protected@file@percent } +\gdef \@abspage@last{2} diff --git a/Docs/Models.fdb_latexmk b/Docs/Models.fdb_latexmk new file mode 100644 index 0000000..8803ca0 --- /dev/null +++ b/Docs/Models.fdb_latexmk @@ -0,0 +1,58 @@ +# Fdb version 4 +["pdflatex"] 1741606732.43984 "c:/Users/pedro/Desktop/Projects/source/Docs/Models.tex" "Models.pdf" "Models" 1741606733.02877 0 + "C:/Users/pedro/AppData/Local/MiKTeX/fonts/map/pdftex/pdftex.map" 1739986129 80909 eab91d9745dd2edfd62a31d53cd5fe15 "" + "C:/Users/pedro/AppData/Local/MiKTeX/miktex/data/le/pdftex/pdflatex.fmt" 1739984920 12004849 764d2605c2e5b05bd7dacdf1301c2e98 "" + "D:/Appdata/MiKTeX/fonts/tfm/public/amsfonts/cmextra/cmex7.tfm" 1233951848 1004 54797486969f23fa377b128694d548df "" + "D:/Appdata/MiKTeX/fonts/tfm/public/amsfonts/cmextra/cmex8.tfm" 1233951848 988 bdf658c3bfc2d96d3c8b02cfc1c94c20 "" + "D:/Appdata/MiKTeX/fonts/tfm/public/amsfonts/symbols/msam10.tfm" 1233951854 916 f87d7c45f9c908e672703b83b72241a3 "" + "D:/Appdata/MiKTeX/fonts/tfm/public/amsfonts/symbols/msam7.tfm" 1233951854 928 2dc8d444221b7a635bb58038579b861a "" + "D:/Appdata/MiKTeX/fonts/tfm/public/amsfonts/symbols/msbm10.tfm" 1233951854 908 2921f8a10601f252058503cc6570e581 "" + "D:/Appdata/MiKTeX/fonts/tfm/public/amsfonts/symbols/msbm7.tfm" 1233951854 940 228d6584342e91276bf566bcf9716b83 "" + "D:/Appdata/MiKTeX/fonts/tfm/public/cm/cmbx12.tfm" 1136765053 1324 c910af8c371558dc20f2d7822f66fe64 "" + "D:/Appdata/MiKTeX/fonts/tfm/public/cm/cmex10.tfm" 1136765053 992 662f679a0b3d2d53c1b94050fdaa3f50 "" + "D:/Appdata/MiKTeX/fonts/tfm/public/cm/cmmi12.tfm" 1136765053 1524 4414a8315f39513458b80dfc63bff03a "" + "D:/Appdata/MiKTeX/fonts/tfm/public/cm/cmmi6.tfm" 1136765053 1512 f21f83efb36853c0b70002322c1ab3ad "" + "D:/Appdata/MiKTeX/fonts/tfm/public/cm/cmmi8.tfm" 1136765053 1520 eccf95517727cb11801f4f1aee3a21b4 "" + "D:/Appdata/MiKTeX/fonts/tfm/public/cm/cmr12.tfm" 1136765053 1288 655e228510b4c2a1abe905c368440826 "" + "D:/Appdata/MiKTeX/fonts/tfm/public/cm/cmr17.tfm" 1136765053 1292 296a67155bdbfc32aa9c636f21e91433 "" + "D:/Appdata/MiKTeX/fonts/tfm/public/cm/cmr6.tfm" 1136765053 1300 b62933e007d01cfd073f79b963c01526 "" + "D:/Appdata/MiKTeX/fonts/tfm/public/cm/cmr8.tfm" 1136765053 1292 21c1c5bfeaebccffdb478fd231a0997d "" + "D:/Appdata/MiKTeX/fonts/tfm/public/cm/cmsy10.tfm" 1136765053 1124 6c73e740cf17375f03eec0ee63599741 "" + "D:/Appdata/MiKTeX/fonts/tfm/public/cm/cmsy6.tfm" 1136765053 1116 933a60c408fc0a863a92debe84b2d294 "" + "D:/Appdata/MiKTeX/fonts/tfm/public/cm/cmsy8.tfm" 1136765053 1120 8b7d695260f3cff42e636090a8002094 "" + "D:/Appdata/MiKTeX/fonts/type1/public/amsfonts/cm/cmbx12.pfb" 1247596666 32080 340ef9bf63678554ee606688e7b5339d "" + "D:/Appdata/MiKTeX/fonts/type1/public/amsfonts/cm/cmex10.pfb" 1247596667 30251 6afa5cb1d0204815a708a080681d4674 "" + "D:/Appdata/MiKTeX/fonts/type1/public/amsfonts/cm/cmmi12.pfb" 1247596667 36741 0ee9e374ec3e30da87cdfb0ea3575226 "" + "D:/Appdata/MiKTeX/fonts/type1/public/amsfonts/cm/cmmi8.pfb" 1247596666 35469 dcf3a5f2fc1862f5952e3ee5eb1d98c4 "" + "D:/Appdata/MiKTeX/fonts/type1/public/amsfonts/cm/cmr12.pfb" 1247596667 32722 d7379af29a190c3f453aba36302ff5a9 "" + "D:/Appdata/MiKTeX/fonts/type1/public/amsfonts/cm/cmr17.pfb" 1247596666 32362 bc3f3eec7ab7d65fe700963d4017d32c "" + "D:/Appdata/MiKTeX/fonts/type1/public/amsfonts/cm/cmr6.pfb" 1247596667 32734 69e00a6b65cedb993666e42eedb3d48f "" + "D:/Appdata/MiKTeX/fonts/type1/public/amsfonts/cm/cmr8.pfb" 1247596667 32726 39f0f9e62e84beb801509898a605dbd5 "" + "D:/Appdata/MiKTeX/fonts/type1/public/amsfonts/cm/cmsy10.pfb" 1247596667 32569 5e5ddc8df908dea60932f3c484a54c0d "" + "D:/Appdata/MiKTeX/fonts/type1/public/amsfonts/cm/cmsy8.pfb" 1247596667 32626 5abc8bb2f28aa647d4c70f8ea38cc0d3 "" + "D:/Appdata/MiKTeX/tex/generic/iftex/iftex.sty" 1734114575 7984 7dbb9280f03c0a315425f1b4f35d43ee "" + "D:/Appdata/MiKTeX/tex/generic/iftex/ifvtex.sty" 1734114575 1057 525c2192b5febbd8c1f662c9468335bb "" + "D:/Appdata/MiKTeX/tex/latex/amsfonts/amsfonts.sty" 1358197772 5949 3f3fd50a8cc94c3d4cbf4fc66cd3df1c "" + "D:/Appdata/MiKTeX/tex/latex/amsfonts/amssymb.sty" 1358197772 13829 94730e64147574077f8ecfea9bb69af4 "" + "D:/Appdata/MiKTeX/tex/latex/amsfonts/umsa.fd" 1358197772 961 6518c6525a34feb5e8250ffa91731cff "" + "D:/Appdata/MiKTeX/tex/latex/amsfonts/umsb.fd" 1358197772 961 d02606146ba5601b5645f987c92e6193 "" + "D:/Appdata/MiKTeX/tex/latex/amsmath/amsbsy.sty" 1731152860 2222 2166a1f7827be30ddc30434e5efcee1b "" + "D:/Appdata/MiKTeX/tex/latex/amsmath/amsgen.sty" 1731152859 4173 d22509bc0c91281d991b2de7c88720dd "" + "D:/Appdata/MiKTeX/tex/latex/amsmath/amsmath.sty" 1731152860 88370 c780f23aea0ece6add91e09b44dca2cd "" + "D:/Appdata/MiKTeX/tex/latex/amsmath/amsopn.sty" 1731152860 4474 23ca1d3a79a57b405388059456d0a8df "" + "D:/Appdata/MiKTeX/tex/latex/amsmath/amstext.sty" 1731152860 2444 71618ea5f2377e33b04fb97afdd0eac2 "" + "D:/Appdata/MiKTeX/tex/latex/base/article.cls" 1738160243 20144 63d8bacaf52e5abf4db3bc322373e1d4 "" + "D:/Appdata/MiKTeX/tex/latex/base/inputenc.sty" 1738160243 5048 0270515b828149155424600fd2d58ac5 "" + "D:/Appdata/MiKTeX/tex/latex/base/size12.clo" 1738160243 8449 ffe4ba2166a344827c3a832d1d5e0a91 "" + "D:/Appdata/MiKTeX/tex/latex/geometry/geometry.cfg" 1578053545 1104 7ac475a4e3466b0b43e138e9356bda83 "" + "D:/Appdata/MiKTeX/tex/latex/geometry/geometry.sty" 1578053545 42759 9cf6c5257b1bc7af01a58859749dd37a "" + "D:/Appdata/MiKTeX/tex/latex/graphics/keyval.sty" 1730544106 2671 70891d50dac933918b827d326687c6e8 "" + "D:/Appdata/MiKTeX/tex/latex/l3backend/l3backend-pdftex.def" 1716480499 29785 9f93ab201fe5dd053afcc6c1bcf7d266 "" + "Models.aux" 1741606732 1429 8fbbeca065203156c4d218ad6b7c149b "pdflatex" + "Models.tex" 1741606731 4396 231b46402b7e7a479b713b2d10ce0d0d "" + "c:/Users/pedro/Desktop/Projects/source/Docs/Models.tex" 1741606731 4396 231b46402b7e7a479b713b2d10ce0d0d "" + (generated) + "Models.aux" + "Models.log" + "Models.pdf" + (rewritten before read) diff --git a/Docs/Models.fls b/Docs/Models.fls new file mode 100644 index 0000000..f41e970 --- /dev/null +++ b/Docs/Models.fls @@ -0,0 +1,109 @@ +PWD c:\Users\pedro\Desktop\Projects\source\Docs +INPUT C:\Users\pedro\AppData\Local\MiKTeX\miktex\data\le\pdftex\pdflatex.fmt +INPUT c:\Users\pedro\Desktop\Projects\source\Docs\Models.tex +OUTPUT Models.log +INPUT D:\Appdata\MiKTeX\tex\latex\base\article.cls +INPUT D:\Appdata\MiKTeX\tex\latex\base\article.cls +INPUT D:\Appdata\MiKTeX\tex\latex\base\size12.clo +INPUT D:\Appdata\MiKTeX\tex\latex\base\size12.clo +INPUT D:\Appdata\MiKTeX\tex\latex\base\size12.clo +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\cm\cmr12.tfm +INPUT D:\Appdata\MiKTeX\tex\latex\base\inputenc.sty +INPUT D:\Appdata\MiKTeX\tex\latex\base\inputenc.sty +INPUT D:\Appdata\MiKTeX\tex\latex\amsmath\amsmath.sty +INPUT D:\Appdata\MiKTeX\tex\latex\amsmath\amsmath.sty +INPUT D:\Appdata\MiKTeX\tex\latex\amsmath\amsopn.sty +INPUT D:\Appdata\MiKTeX\tex\latex\amsmath\amstext.sty +INPUT D:\Appdata\MiKTeX\tex\latex\amsmath\amstext.sty +INPUT D:\Appdata\MiKTeX\tex\latex\amsmath\amsgen.sty +INPUT D:\Appdata\MiKTeX\tex\latex\amsmath\amsgen.sty +INPUT D:\Appdata\MiKTeX\tex\latex\amsmath\amsbsy.sty +INPUT D:\Appdata\MiKTeX\tex\latex\amsmath\amsbsy.sty +INPUT D:\Appdata\MiKTeX\tex\latex\amsmath\amsopn.sty +INPUT D:\Appdata\MiKTeX\tex\latex\amsfonts\amsfonts.sty +INPUT D:\Appdata\MiKTeX\tex\latex\amsfonts\amsfonts.sty +INPUT D:\Appdata\MiKTeX\tex\latex\amsfonts\amssymb.sty +INPUT D:\Appdata\MiKTeX\tex\latex\amsfonts\amssymb.sty +INPUT D:\Appdata\MiKTeX\tex\latex\geometry\geometry.sty +INPUT D:\Appdata\MiKTeX\tex\latex\geometry\geometry.sty +INPUT D:\Appdata\MiKTeX\tex\latex\graphics\keyval.sty +INPUT D:\Appdata\MiKTeX\tex\latex\graphics\keyval.sty +INPUT D:\Appdata\MiKTeX\tex\generic\iftex\ifvtex.sty +INPUT D:\Appdata\MiKTeX\tex\generic\iftex\ifvtex.sty +INPUT D:\Appdata\MiKTeX\tex\generic\iftex\iftex.sty +INPUT D:\Appdata\MiKTeX\tex\generic\iftex\iftex.sty +INPUT D:\Appdata\MiKTeX\tex\latex\geometry\geometry.cfg +INPUT D:\Appdata\MiKTeX\tex\latex\geometry\geometry.cfg +INPUT D:\Appdata\MiKTeX\tex\latex\geometry\geometry.cfg +INPUT D:\Appdata\MiKTeX\tex\latex\l3backend\l3backend-pdftex.def +INPUT D:\Appdata\MiKTeX\tex\latex\l3backend\l3backend-pdftex.def +INPUT .\Models.aux +INPUT .\Models.aux +INPUT Models.aux +OUTPUT Models.aux +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\cm\cmr17.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\cm\cmr12.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\cm\cmmi12.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\cm\cmsy10.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\cm\cmex10.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\amsfonts\cmextra\cmex7.tfm +INPUT D:\Appdata\MiKTeX\tex\latex\amsfonts\umsa.fd +INPUT D:\Appdata\MiKTeX\tex\latex\amsfonts\umsa.fd +INPUT D:\Appdata\MiKTeX\tex\latex\amsfonts\umsa.fd +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\amsfonts\symbols\msam10.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\amsfonts\symbols\msam10.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\amsfonts\symbols\msam7.tfm +INPUT D:\Appdata\MiKTeX\tex\latex\amsfonts\umsb.fd +INPUT D:\Appdata\MiKTeX\tex\latex\amsfonts\umsb.fd +INPUT D:\Appdata\MiKTeX\tex\latex\amsfonts\umsb.fd +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\amsfonts\symbols\msbm10.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\amsfonts\symbols\msbm10.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\amsfonts\symbols\msbm7.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\cm\cmr17.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\cm\cmbx12.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\cm\cmbx12.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\cm\cmr8.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\cm\cmr6.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\cm\cmmi12.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\cm\cmmi8.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\cm\cmmi6.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\cm\cmsy10.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\cm\cmsy8.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\cm\cmsy6.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\cm\cmex10.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\amsfonts\cmextra\cmex8.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\amsfonts\cmextra\cmex7.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\amsfonts\symbols\msam10.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\amsfonts\symbols\msam10.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\amsfonts\symbols\msam7.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\amsfonts\symbols\msbm10.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\amsfonts\symbols\msbm10.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\amsfonts\symbols\msbm7.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\cm\cmmi12.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\cm\cmsy10.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\cm\cmex10.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\amsfonts\symbols\msam10.tfm +INPUT D:\Appdata\MiKTeX\fonts\tfm\public\amsfonts\symbols\msbm10.tfm +OUTPUT Models.pdf +INPUT C:\Users\pedro\AppData\Local\MiKTeX\fonts\map\pdftex\pdftex.map +INPUT Models.aux +INPUT D:\Appdata\MiKTeX\fonts\type1\public\amsfonts\cm\cmbx12.pfb +INPUT D:\Appdata\MiKTeX\fonts\type1\public\amsfonts\cm\cmbx12.pfb +INPUT D:\Appdata\MiKTeX\fonts\type1\public\amsfonts\cm\cmex10.pfb +INPUT D:\Appdata\MiKTeX\fonts\type1\public\amsfonts\cm\cmex10.pfb +INPUT D:\Appdata\MiKTeX\fonts\type1\public\amsfonts\cm\cmmi12.pfb +INPUT D:\Appdata\MiKTeX\fonts\type1\public\amsfonts\cm\cmmi12.pfb +INPUT D:\Appdata\MiKTeX\fonts\type1\public\amsfonts\cm\cmmi8.pfb +INPUT D:\Appdata\MiKTeX\fonts\type1\public\amsfonts\cm\cmmi8.pfb +INPUT D:\Appdata\MiKTeX\fonts\type1\public\amsfonts\cm\cmr12.pfb +INPUT D:\Appdata\MiKTeX\fonts\type1\public\amsfonts\cm\cmr12.pfb +INPUT D:\Appdata\MiKTeX\fonts\type1\public\amsfonts\cm\cmr17.pfb +INPUT D:\Appdata\MiKTeX\fonts\type1\public\amsfonts\cm\cmr17.pfb +INPUT D:\Appdata\MiKTeX\fonts\type1\public\amsfonts\cm\cmr6.pfb +INPUT D:\Appdata\MiKTeX\fonts\type1\public\amsfonts\cm\cmr6.pfb +INPUT D:\Appdata\MiKTeX\fonts\type1\public\amsfonts\cm\cmr8.pfb +INPUT D:\Appdata\MiKTeX\fonts\type1\public\amsfonts\cm\cmr8.pfb +INPUT D:\Appdata\MiKTeX\fonts\type1\public\amsfonts\cm\cmsy10.pfb +INPUT D:\Appdata\MiKTeX\fonts\type1\public\amsfonts\cm\cmsy10.pfb +INPUT D:\Appdata\MiKTeX\fonts\type1\public\amsfonts\cm\cmsy8.pfb +INPUT D:\Appdata\MiKTeX\fonts\type1\public\amsfonts\cm\cmsy8.pfb diff --git a/Docs/Models.pdf b/Docs/Models.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e2aeef546b49cdaa7cc51b051b2d85967cead426 GIT binary patch literal 130191 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 h_c - # Izquierda: x ~ -(r_int + e_pvc) hasta -r_int - # Derecha : x ~ (r_int) hasta (r_int + e_pvc) - ax.fill_between( - x=[-(r_int + e_pvc), -r_int], - y1=0, - y2=h_c, - color="black", - alpha=0.3 - ) - ax.fill_between( - x=[r_int, r_int + e_pvc], - y1=0, - y2=h_c, - color="black", - alpha=0.3 - ) + # PVC a izquierda y derecha + ax.fill_between(x=[-(r_int + e_pvc), -r_int], y1=0, y2=h_c, color="black", alpha=0.3) + ax.fill_between(x=[r_int, r_int + e_pvc], y1=0, y2=h_c, color="black", alpha=0.3) - # 4) Cálculo de capas radiales y vueltas por capa num_capas = int(np.floor(r_capas / d_cu)) - if num_capas < 1: - num_capas = 1 - + if num_capas < 1: num_capas = 1 vueltas_por_capa = int(np.ceil(N / num_capas)) - - # 5) Distancia vertical entre vueltas en cada capa delta_h = h_c / (vueltas_por_capa + 1) - # Función auxiliar para dibujar un conductor (círculo) def dibuja_conductor(xc, yc, radio): circle = plt.Circle((xc, yc), radio, color="orange", fill=True) ax.add_patch(circle) - # 6) Bucle para colocar cada capa (izq/dcha) for i in range(num_capas): - # X de la capa i, en lado izquierdo x_left = -(r_int + e_pvc + (2*i + 1) * (d_cu / 2)) - # ... y lado derecho x_right = +(r_int + e_pvc + (2*i + 1) * (d_cu / 2)) - - # Añadimos vueltas en altura for j in range(vueltas_por_capa): - y = (j + 1) * delta_h - if y > h_c: - break # no dibujamos si excede la altura + y = (j + 1)*delta_h + if y > h_c: break dibuja_conductor(x_left, y, d_cu/2) dibuja_conductor(x_right, y, d_cu/2) - # 7) Ajustar los límites del dibujo en X e Y ax.set_xlim(-r_ext - d_cu, r_ext + d_cu) ax.set_ylim(0, h_c + d_cu) - ax.set_xlabel("Radio (X)") ax.set_ylabel("Altura (Y)") ax.grid(True) - # 8) Borramos lo anterior en parent_frame y embebemos esta figura for child in parent_frame.winfo_children(): child.destroy() - canvas = FigureCanvasTkAgg(fig, master=parent_frame) canvas_widget = canvas.get_tk_widget() canvas_widget.pack(fill="both", expand=True) diff --git a/src/tabs/tab_coil.py b/src/tabs/tab_coil.py index 11b2561..f4b6063 100644 --- a/src/tabs/tab_coil.py +++ b/src/tabs/tab_coil.py @@ -1,335 +1,191 @@ -# src/tab_coil.py - import tkinter as tk from tkinter import ttk from tkinter.scrolledtext import ScrolledText - import matplotlib matplotlib.use("TkAgg") import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg - import numpy as np import math as m - -# Se importan las integrales elípticas de SciPy para el cálculo preciso de la inductancia from scipy.special import ellipk, ellipe -# ------------------------------------------------------------------- -# Constantes y funciones para el cálculo de inductancia -# ------------------------------------------------------------------- - -MU0 = 4.0e-7 * m.pi # Permeabilidad magnética del vacío (H/m) +MU0 = 4.0e-7 * m.pi # Permeabilidad magnética vacío (H/m) +RHO_CU = 1.68e-8 # Resistividad cobre (Ohm·m) a 20°C def self_inductance_loop(r, a_eff=1e-4): - """ - Autoinductancia aproximada de un anillo fino de radio r. - Emplea la fórmula: L ~ mu0*r * [ln(8r/a_eff) - 2]. - """ - if r <= 0: - return 0.0 - return MU0 * r * (m.log(8.0 * r / a_eff) - 2.0) + if r <= 0: return 0.0 + return MU0*r*(m.log(8.0*r/a_eff) - 2.0) def mutual_inductance_coaxial(r1, r2, z_dist): - """ - Inductancia mutua entre dos anillos coaxiales de radios r1 y r2, - separados una distancia axial z_dist. - Emplea las integrales elípticas de primera y segunda especie. - """ - if r1 < 1e-12 or r2 < 1e-12: - return 0.0 - - k_sq = 4.0 * r1 * r2 / ((r1 + r2)**2 + z_dist**2) - if k_sq > 1.0: - # Caso no físico (puede ocurrir por redondeos), retornamos 0 - return 0.0 - + if r1 < 1e-12 or r2 < 1e-12: return 0.0 + k_sq = 4.0*r1*r2 / ((r1 + r2)**2 + z_dist**2) + if k_sq > 1.0: return 0.0 k = np.sqrt(k_sq) - - # Caso casi degenerado (r1 ~ r2, z_dist ~ 0) - if (1.0 - k_sq) < 1e-12: - # Aproximación cuando r1 ≈ r2 y z ≈ 0 - return MU0 * min(r1, r2) * m.pi - else: - Kk = ellipk(k_sq) - Ek = ellipe(k_sq) - factor = MU0 * np.sqrt(r1 * r2) - # Expresión: M = mu0 * sqrt(r1*r2)*((2-k)*K - 2E) / k - return factor * ((2.0 - k) * Kk - 2.0 * Ek) / k + if (1.0 - k_sq) < 1e-12: + return MU0*min(r1, r2)*m.pi + Kk, Ek = ellipk(k_sq), ellipe(k_sq) + factor = MU0*np.sqrt(r1*r2) + return factor*((2.0 - k)*Kk - 2.0*Ek)/k def compute_coil_geometry(N_total, R_int, R_ext, espesor_plast, H, wire_d): - """ - Genera la lista de (r_i, z_i) para las N_total espiras, asumiendo - que se llenan capas radiales y, en cada capa, vueltas a lo largo de la altura. - Todos los parámetros deben estar en metros. - """ - radial_thickness = R_ext - (R_int + 2 * espesor_plast) + radial_thickness = R_ext - (R_int + 2*espesor_plast) if radial_thickness <= 0: raise ValueError("No hay espacio radial para el bobinado.") - max_layers = int(np.floor(radial_thickness / wire_d)) if max_layers < 1: raise ValueError("No cabe ni una capa con el grosor de hilo dado.") - max_turns_per_layer = int(np.floor(H / wire_d)) if max_turns_per_layer < 1: raise ValueError("No cabe ni una vuelta en la altura dada.") - max_turns_possible = max_layers * max_turns_per_layer if max_turns_possible < N_total: - raise ValueError( - f"Con {max_layers} capas y {max_turns_per_layer} vueltas/capa " - f"sólo se pueden alojar {max_turns_possible} espiras, " - f"pero se solicitan {N_total}." - ) + raise ValueError(f"Se necesitan {N_total} espiras, pero solo caben {max_turns_possible}.") espiras = [] - vueltas_restantes = N_total - layer_index = 0 - - while vueltas_restantes > 0 and layer_index < max_layers: - r_layer = R_int + espesor_plast + layer_index * wire_d + wire_d / 2.0 - - if vueltas_restantes >= max_turns_per_layer: - n_vueltas = max_turns_per_layer - else: - n_vueltas = vueltas_restantes - + vueltas_rest = N_total + layer_idx = 0 + while vueltas_rest > 0 and layer_idx < max_layers: + r_layer = R_int + espesor_plast + layer_idx*wire_d + wire_d/2.0 + n_vueltas = max_turns_per_layer if vueltas_rest >= max_turns_per_layer else vueltas_rest for turn in range(n_vueltas): - z_i = (turn + 0.5) * wire_d + z_i = (turn + 0.5)*wire_d espiras.append((r_layer, z_i)) - - vueltas_restantes -= n_vueltas - layer_index += 1 - - if vueltas_restantes > 0: - raise ValueError( - f"No se pudo colocar toda la bobina. " - f"Faltan {vueltas_restantes} espiras por ubicar." - ) + vueltas_rest -= n_vueltas + layer_idx += 1 + if vueltas_rest > 0: + raise ValueError(f"Faltan {vueltas_rest} espiras por ubicar.") return espiras def inductance_from_spiralist(espiras, wire_radius): - """ - Calcula la inductancia total (en henrios) a partir de la lista (r_i, z_i), - sumando la autoinductancia de cada espira y la mutua entre pares (O(N^2)). - """ + """Suma autoinductancias + mutuas (O(N^2)).""" N = len(espiras) L_total = 0.0 - for i in range(N): r_i, z_i = espiras[i] - # Autoinductancia L_total += self_inductance_loop(r_i, wire_radius) - # Mutua con las espiras j > i for j in range(i + 1, N): r_j, z_j = espiras[j] - dist_z = abs(z_j - z_i) - M_ij = mutual_inductance_coaxial(r_i, r_j, dist_z) - L_total += 2.0 * M_ij - + M_ij = mutual_inductance_coaxial(r_i, r_j, abs(z_j - z_i)) + L_total += 2.0*M_ij return abs(L_total) -# ------------------------------------------------------------------- -# Importamos la función para dibujar la bobina 2D (tal y como estaba). -# ------------------------------------------------------------------- +# Importamos la función para dibujar la bobina from tabs.geometry_viewer import plot_coil_in_frame -# ------------------------------------------------------------------- -# Definición de la clase TabCoil, añadiendo la ventana de logs y -# el botón de cálculo de inductancia con mensajes de estado. -# ------------------------------------------------------------------- class TabCoil: def __init__(self, notebook, tab_simulator): - """ - Pestaña para representar la bobina en 2D y ajustar sus parámetros. - Recibe: - - notebook: el ttk.Notebook donde se añadirá - - tab_simulator: referencia a TabSimulator, si se necesita comunicar - """ self.notebook = notebook self.tab_simulator = tab_simulator - - # Frame principal dentro del notebook self.frame = tk.Frame(notebook) self.frame.pack(fill="both", expand=True) - # Layout principal: lado izq (parámetros) y lado der (dibujo) - frame_left = tk.Frame(self.frame) - frame_left.pack(side="left", fill="y", padx=5, pady=5) - + frame_left = tk.Frame(self.frame); frame_left.pack(side="left", fill="y", padx=5, pady=5) frame_right = tk.Frame(self.frame, bd=2, relief="groove") frame_right.pack(side="right", fill="both", expand=True, padx=5, pady=5) - # Este frame contendrá el canvas/figura para la bobina en 2D self.frame_2d = tk.Frame(frame_right) self.frame_2d.pack(fill="both", expand=True) - # - # Sección Izquierda: parámetros de la bobina - # tk.Label(frame_left, text="Parámetros de la Bobina:").pack(anchor="w") - - # Variables - self.var_N = tk.DoubleVar(value=500) # Número de espiras - self.var_e_pvc = tk.DoubleVar(value=2) # Espesor del plástico [mm] - self.var_r_int = tk.DoubleVar(value=4.035) # Radio interior [mm] - self.var_r_ext = tk.DoubleVar(value=10.64) # Radio exterior [mm] - self.var_h_c = tk.DoubleVar(value=53.12) # Altura de la bobina [mm] - self.var_d_cu = tk.DoubleVar(value=0.5) # Diámetro conductor [mm] - - # Variable para mostrar la inductancia (se mostrará en µH) + self.var_N = tk.DoubleVar(value=500) + self.var_e_pvc = tk.DoubleVar(value=2) + self.var_r_int = tk.DoubleVar(value=4.035) + self.var_r_ext = tk.DoubleVar(value=10.64) + self.var_h_c = tk.DoubleVar(value=53.12) + self.var_d_cu = tk.DoubleVar(value=0.5) self.var_L = tk.StringVar(value="") + self.var_R = tk.StringVar(value="") - # Frame para agrupar los Entries self.frame_params = tk.Frame(frame_left, bd=1, relief="sunken") self.frame_params.pack(fill="x", pady=5) - # Función auxiliar para añadir filas (etiqueta + entry) - def add_param_row(label_text, var, row, width=8): - lbl = tk.Label(self.frame_params, text=label_text) - lbl.grid(row=row, column=0, sticky="w", padx=5, pady=2) - ent = tk.Entry(self.frame_params, textvariable=var, width=width) - ent.grid(row=row, column=1, padx=5, pady=2) + def add_param_row(lbl_txt, var, row, w=8): + tk.Label(self.frame_params, text=lbl_txt).grid(row=row, column=0, sticky="w", padx=5, pady=2) + tk.Entry(self.frame_params, textvariable=var, width=w).grid(row=row, column=1, padx=5, pady=2) rowcount = 0 - add_param_row("N (vueltas):", self.var_N, rowcount); rowcount += 1 - add_param_row("e_pvc (mm):", self.var_e_pvc, rowcount); rowcount += 1 - add_param_row("r_int (mm):", self.var_r_int, rowcount); rowcount += 1 - add_param_row("r_ext (mm):", self.var_r_ext, rowcount); rowcount += 1 - add_param_row("h_c (mm):", self.var_h_c, rowcount); rowcount += 1 - add_param_row("d_cu (mm):", self.var_d_cu, rowcount); rowcount += 1 + add_param_row("N (vueltas):", self.var_N, rowcount); rowcount += 1 + add_param_row("e_pvc (mm):", self.var_e_pvc, rowcount); rowcount += 1 + add_param_row("r_int (mm):", self.var_r_int, rowcount); rowcount += 1 + add_param_row("r_ext (mm):", self.var_r_ext, rowcount); rowcount += 1 + add_param_row("h_c (mm):", self.var_h_c, rowcount); rowcount += 1 + add_param_row("d_cu (mm):", self.var_d_cu, rowcount); rowcount += 1 - # Campo para ver la inductancia en microHenrios (µH). - lblL = tk.Label(self.frame_params, text="Induct. (µH):") - lblL.grid(row=rowcount, column=0, sticky="w", padx=5, pady=2) - entL = tk.Entry(self.frame_params, textvariable=self.var_L, width=10, state="readonly") - entL.grid(row=rowcount, column=1, padx=5, pady=2) + tk.Label(self.frame_params, text="Induct. (µH):").grid(row=rowcount, column=0, sticky="w", padx=5, pady=2) + tk.Entry(self.frame_params, textvariable=self.var_L, width=10, state="readonly").grid(row=rowcount, column=1, padx=5, pady=2) rowcount += 1 - # Botones - btn_refrescar = tk.Button( - frame_left, text="Refrescar Vista 2D", - command=self.refrescar_2d - ) - btn_refrescar.pack(pady=10) + tk.Label(self.frame_params, text="R (Ohms):").grid(row=rowcount, column=0, sticky="w", padx=5, pady=2) + tk.Entry(self.frame_params, textvariable=self.var_R, width=10, state="readonly").grid(row=rowcount, column=1, padx=5, pady=2) + rowcount += 1 - btn_calc_L = tk.Button( - frame_left, text="Calcular Inductancia", - command=self.calcular_inductancia - ) - btn_calc_L.pack(pady=5) + tk.Button(frame_left, text="Refrescar Vista 2D", command=self.refrescar_2d).pack(pady=10) + tk.Button(frame_left, text="Calcular", command=self.calcular_inductancia).pack(pady=5) - # - # Sección de Logs - # tk.Label(frame_left, text="Logs:").pack(anchor="w") self.log_area = ScrolledText(frame_left, wrap="word", height=8, width=35) self.log_area.pack(fill="x", padx=5, pady=5) self.log_area.configure(state="disabled") - - # Definimos etiquetas de color self.log_area.tag_config("info", foreground="green") self.log_area.tag_config("error", foreground="red") - # - # Figura y canvas para la bobina en 2D - # self.fig = plt.Figure(figsize=(4,3), dpi=100) self.ax = self.fig.add_subplot(111) self.canvas_2d = FigureCanvasTkAgg(self.fig, master=self.frame_2d) self.canvas_2d_widget = self.canvas_2d.get_tk_widget() self.canvas_2d_widget.pack(fill="both", expand=True) - # Dibujamos la bobina inicial self.refrescar_2d() def log_message(self, text, mode="info"): - """ - Inserta un mensaje en el log_area, en color definido por 'mode'. - mode puede ser 'info' (verde) o 'error' (rojo). - """ self.log_area.configure(state="normal") self.log_area.insert("end", text + "\n", mode) self.log_area.see("end") self.log_area.configure(state="disabled") def refrescar_2d(self): - """ - Lee los valores de la bobina y llama a 'plot_coil_in_frame' - para actualizar el dibujo en 2D. - """ - N_val = self.var_N.get() + N_val = self.var_N.get() e_pvc_val = self.var_e_pvc.get() r_int_val = self.var_r_int.get() r_ext_val = self.var_r_ext.get() - h_c_val = self.var_h_c.get() - d_cu_val = self.var_d_cu.get() - - # Limpiar el Axes + h_c_val = self.var_h_c.get() + d_cu_val = self.var_d_cu.get() self.ax.clear() - - # Llamada a la función que inserta la figura en self.frame_2d - plot_coil_in_frame( - parent_frame=self.frame_2d, - N=N_val, - e_pvc=e_pvc_val, - r_int=r_int_val, - r_ext=r_ext_val, - h_c=h_c_val, - d_cu=d_cu_val - ) + plot_coil_in_frame(self.frame_2d, N_val, e_pvc_val, r_int_val, r_ext_val, h_c_val, d_cu_val) def calcular_inductancia(self): - """ - Cálculo de la inductancia a partir de los parámetros introducidos. - Muestra el resultado en µH en el campo correspondiente y en la log_area. - """ try: - # Lectura de parámetros N_espiras = int(self.var_N.get()) e_pvc_val = self.var_e_pvc.get() r_int_val = self.var_r_int.get() r_ext_val = self.var_r_ext.get() - h_c_val = self.var_h_c.get() - d_cu_val = self.var_d_cu.get() + h_c_val = self.var_h_c.get() + d_cu_val = self.var_d_cu.get() + R_in, R_out = r_int_val/1000.0, r_ext_val/1000.0 + plast = e_pvc_val/1000.0 + altura = h_c_val/1000.0 + diam_hilo = d_cu_val/1000.0 - # Conversión mm -> m - R_in = r_int_val / 1000.0 - R_out = r_ext_val / 1000.0 - plast = e_pvc_val / 1000.0 - altura = h_c_val / 1000.0 - diam_hilo = d_cu_val / 1000.0 - - # Construir la geometría de la bobina - espiras_xyz = compute_coil_geometry( - N_total=N_espiras, - R_int=R_in, - R_ext=R_out, - espesor_plast=plast, - H=altura, - wire_d=diam_hilo - ) - - # Radio efectivo para autoinductancia - wire_radius = diam_hilo / 2.0 - - # Calcular la inductancia total (en henrios) + espiras_xyz = compute_coil_geometry(N_espiras, R_in, R_out, plast, altura, diam_hilo) + wire_radius = diam_hilo/2.0 L_h = inductance_from_spiralist(espiras_xyz, wire_radius) - L_uH = L_h * 1e6 + L_uH = L_h*1e6 + + wire_length = 0.0 + for (r_i, _) in espiras_xyz: + wire_length += 2.0*m.pi*r_i + wire_area = m.pi*(wire_radius**2) + R_coil = RHO_CU*(wire_length/wire_area) - # Actualizar variable de resultado self.var_L.set(f"{L_uH:.3f}") - - # Log de éxito - self.log_message("Inductancia calculada correctamente", "info") - + self.var_R.set(f"{R_coil:.3f}") + self.log_message(f"Inductancia: {L_uH:.3f} µH, Resistencia: {R_coil:.3f} Ω", "info") except ValueError as e: - # Si hay algún problema con la geometría, etc. self.var_L.set("Error") + self.var_R.set("Error") self.log_message(f"Error en cálculo: {str(e)}", "error") except Exception as ex: - # Errores generales self.var_L.set("Error") - self.log_message(f"Error inesperado: {str(ex)}", "error") \ No newline at end of file + self.var_R.set("Error") + self.log_message(f"Error inesperado: {str(ex)}", "error") diff --git a/src/tabs/tab_drag.py b/src/tabs/tab_drag.py index 2c0abd7..2207ea8 100644 --- a/src/tabs/tab_drag.py +++ b/src/tabs/tab_drag.py @@ -1,7 +1,6 @@ import tkinter as tk from tkinter import ttk import math - import matplotlib matplotlib.use("TkAgg") import matplotlib.pyplot as plt @@ -11,66 +10,39 @@ import numpy as np class TabDrag: def __init__(self, notebook, tab_simulator): - """ - Pestaña para calcular un coef. 'b' a partir de la geometría - y exponer métodos para la reluctancia (l_fe y S_disp). - """ self.notebook = notebook self.tab_simulator = tab_simulator - self.frame = tk.Frame(notebook) self.frame.pack(fill="both", expand=True) - # Layout principal - frame_left = tk.Frame(self.frame) - frame_left.pack(side="left", fill="y", padx=5, pady=5) - + frame_left = tk.Frame(self.frame); frame_left.pack(side="left", fill="y", padx=5, pady=5) frame_right = tk.Frame(self.frame, bd=2, relief="groove") frame_right.pack(side="right", fill="both", expand=True, padx=5, pady=5) + self.frame_3d = tk.Frame(frame_right); self.frame_3d.pack(fill="both", expand=True) - self.frame_3d = tk.Frame(frame_right) - self.frame_3d.pack(fill="both", expand=True) - - # Sección Izquierda: geometría + parámetros tk.Label(frame_left, text="Selecciona geometría:").pack(anchor="w") self.geometria_var = tk.StringVar(value="Prisma cuadrado") - self.combo_geometrias = ttk.Combobox( - frame_left, textvariable=self.geometria_var, - values=["Prisma cuadrado", "Cilindro", "Esfera"], - state="readonly" - ) + self.combo_geometrias = ttk.Combobox(frame_left, textvariable=self.geometria_var, + values=["Prisma cuadrado","Cilindro","Esfera"], state="readonly") self.combo_geometrias.pack(anchor="w", pady=5) self.frame_parametros = tk.Frame(frame_left, bd=1, relief="sunken") self.frame_parametros.pack(fill="x", pady=5) - self.label_param1 = tk.Label(self.frame_parametros, text="Parámetro 1:") self.label_param1.grid(row=0, column=0, sticky="w", padx=5, pady=2) - self.entry_param1 = tk.Entry(self.frame_parametros, width=8) - self.entry_param1.grid(row=0, column=1, padx=5, pady=2) + self.entry_param1 = tk.Entry(self.frame_parametros, width=8); self.entry_param1.grid(row=0, column=1, padx=5, pady=2) self.entry_param1.insert(0, "1") self.label_param2 = tk.Label(self.frame_parametros, text="Parámetro 2:") self.label_param2.grid(row=1, column=0, sticky="w", padx=5, pady=2) - self.entry_param2 = tk.Entry(self.frame_parametros, width=8) - self.entry_param2.grid(row=1, column=1, padx=5, pady=2) + self.entry_param2 = tk.Entry(self.frame_parametros, width=8); self.entry_param2.grid(row=1, column=1, padx=5, pady=2) self.entry_param2.insert(0, "7") self.label_result_b = tk.Label(frame_left, text="Coef (b): N/A", fg="blue") self.label_result_b.pack() + tk.Button(frame_left, text="Calcular Coef. Rozamiento", command=self.calcular_coef_rozamiento).pack(pady=5) + tk.Button(frame_left, text="Refrescar Vista 3D", command=self.refrescar_3d).pack(pady=10) - btn_calc_b = tk.Button( - frame_left, text="Calcular Coef. Rozamiento", - command=self.calcular_coef_rozamiento - ) - btn_calc_b.pack(pady=5) - - tk.Button( - frame_left, text="Refrescar Vista 3D", - command=self.refrescar_3d - ).pack(pady=10) - - # Creamos la figura 3D self.fig = plt.Figure(figsize=(4,3), dpi=100) self.ax = self.fig.add_subplot(111, projection='3d') self.canvas_3d = FigureCanvasTkAgg(self.fig, master=self.frame_3d) @@ -99,58 +71,42 @@ class TabDrag: self.label_param2.config(text="(no aplica):") self.entry_param2.delete(0, tk.END) self.entry_param2.config(state="disabled", fg="gray") - else: - self.label_param1.config(text="Parámetro 1:") - self.label_param2.config(text="Parámetro 2:") def refrescar_3d(self): - # Dibuja la geometría en self.ax geom = self.geometria_var.get() + try: p1 = float(self.entry_param1.get()) + except ValueError: p1 = 1.0 try: - p1 = float(self.entry_param1.get()) - except ValueError: - p1 = 1.0 - try: - if self.entry_param2.cget("state") != "disabled": - p2 = float(self.entry_param2.get()) - else: - p2 = 1.0 + p2 = float(self.entry_param2.get()) if self.entry_param2.cget("state") != "disabled" else 1.0 except ValueError: p2 = 1.0 - self.ax.clear() self.ax.set_axis_off() if geom == "Prisma cuadrado": - Xs = [0,p1,p1,0,0,p1,p1,0] - Ys = [0,0,p1,p1,0,0,p1,p1] - Zs = [0,0,0,0,p2,p2,p2,p2] - edges = [(0,1),(1,2),(2,3),(3,0), - (4,5),(5,6),(6,7),(7,4), - (0,4),(1,5),(2,6),(3,7)] - for (i,j) in edges: - self.ax.plot([Xs[i],Xs[j]], [Ys[i],Ys[j]], [Zs[i],Zs[j]], color='orange') + Xs=[0,p1,p1,0,0,p1,p1,0] + Ys=[0,0,p1,p1,0,0,p1,p1] + Zs=[0,0,0,0,p2,p2,p2,p2] + edges=[(0,1),(1,2),(2,3),(3,0),(4,5),(5,6),(6,7),(7,4),(0,4),(1,5),(2,6),(3,7)] + for i,j in edges: + self.ax.plot([Xs[i],Xs[j]],[Ys[i],Ys[j]],[Zs[i],Zs[j]],color='orange') self.ax.set_box_aspect((p1,p1,p2)) elif geom == "Cilindro": - import numpy as np - r = p1 - h = p2 + r, h = p1, p2 theta = np.linspace(0,2*math.pi,30) z = np.linspace(0,h,30) T,Z = np.meshgrid(theta,z) - X = r*np.cos(T) - Y = r*np.sin(T) + X = r*np.cos(T); Y = r*np.sin(T) self.ax.plot_surface(X, Y, Z, color='orange', alpha=0.8) self.ax.set_box_aspect((2*r,2*r,h)) elif geom == "Esfera": - import numpy as np r = p1 phi = np.linspace(0,math.pi,30) t = np.linspace(0,2*math.pi,30) - phi_grid,t_grid = np.meshgrid(phi,t) - X = r*np.sin(phi_grid)*np.cos(t_grid) - Y = r*np.sin(phi_grid)*np.sin(t_grid) - Z = r*np.cos(phi_grid) + Phi,T = np.meshgrid(phi,t) + X = r*np.sin(Phi)*np.cos(T) + Y = r*np.sin(Phi)*np.sin(T) + Z = r*np.cos(Phi) self.ax.plot_surface(X,Y,Z,color='orange',alpha=0.8) self.ax.set_box_aspect((2*r,2*r,2*r)) else: @@ -160,113 +116,63 @@ class TabDrag: self.canvas_3d.draw() def calcular_coef_rozamiento(self): - """ - Calcula un coeficiente b ~ 0.5*rho*Cd*A - """ geom = self.geometria_var.get() - try: - p1 = float(self.entry_param1.get()) - except: + try: p1 = float(self.entry_param1.get()) + except: self.label_result_b.config(text="Error param1", fg="red") return - Cd=1.0 - A=1.0 - if geom=="Prisma cuadrado": - try: - p2=float(self.entry_param2.get()) + Cd, A = 1.0, 1.0 + if geom == "Prisma cuadrado": + try: p2 = float(self.entry_param2.get()) except: self.label_result_b.config(text="Error param2", fg="red") return - Cd=1.15 - A=p1*p1 - elif geom=="Cilindro": - try: - p2=float(self.entry_param2.get()) + Cd, A = 1.15, p1*p1 + elif geom == "Cilindro": + try: p2 = float(self.entry_param2.get()) except: self.label_result_b.config(text="Error param2", fg="red") return - Cd=0.82 - A=math.pi*(p1**2) - elif geom=="Esfera": - Cd=0.47 - A=math.pi*(p1**2) - - rho=1.225 - b_calc=0.5*rho*Cd*A + Cd, A = 0.82, math.pi*(p1**2) + elif geom == "Esfera": + Cd, A = 0.47, math.pi*(p1**2) + rho = 1.225 + b_calc = 0.5*rho*Cd*A self.label_result_b.config(text=f"Coef (b) ~ {b_calc:.4f}", fg="blue") self.tab_simulator.set_b_value(b_calc) def get_l_fe(self): - """ - Devuelve la 'altura' l_fe (m) según la geometría: - - Prisma cuadrado: param2 (Longitud) - - Cilindro: param2 (Altura) - - Esfera: 2*radio (diámetro) - """ geom = self.geometria_var.get() - - try: - p1 = float(self.entry_param1.get()) - except ValueError: - p1 = 1.0 - + try: p1 = float(self.entry_param1.get()) + except ValueError: p1 = 1.0 l_fe_val = 1.0 - if geom == "Prisma cuadrado": - try: - l_fe_val = float(self.entry_param2.get()) - except ValueError: - l_fe_val = 1.0 - + try: l_fe_val = float(self.entry_param2.get()) + except ValueError: l_fe_val = 1.0 elif geom == "Cilindro": - try: - l_fe_val = float(self.entry_param2.get()) - except ValueError: - l_fe_val = 1.0 - + try: l_fe_val = float(self.entry_param2.get()) + except ValueError: l_fe_val = 1.0 elif geom == "Esfera": - # Usamos 2*r (diámetro). Ajusta si prefieres 0 - l_fe_val = 2.0 * p1 - + l_fe_val = 2.0*p1 return l_fe_val def get_projectile_section_for_reluctance(self, tab_coil): - """ - Devuelve S_disp (m^2) para la fórmula de reluctancia: - - Si la geometría es "Esfera", => S_disp = 2 * S_bob - con S_bob = pi * (r_ext^2) - (r_ext lo lees de tab_coil en mm, conv a m) - - En otros casos => área frontal real (p1^2 si prisma, pi*r^2 si cilindro). - """ geom = self.geometria_var.get() - - # 1) Leer r_ext de tab_coil (en mm) => m - try: - r_ext_mm = float(tab_coil.var_r_ext.get()) - except: - r_ext_mm = 10.0 + try: r_ext_mm = float(tab_coil.var_r_ext.get()) + except: r_ext_mm = 10.0 r_ext_m = r_ext_mm / 1000.0 - - # S_bob = pi*(r_ext_m^2) s_bob = math.pi*(r_ext_m**2) - # 2) Leer p1 - try: - p1 = float(self.entry_param1.get()) - except ValueError: - p1 = 1.0 + try: p1 = float(self.entry_param1.get()) + except ValueError: p1 = 1.0 if geom == "Esfera": - # S_disp = 2*S_bob - return 2.0 * s_bob + return 2.0*s_bob elif geom == "Prisma cuadrado": - # Sección frontal ~ p1 x p1 - return (p1**2) + return p1**2 elif geom == "Cilindro": - # Sección frontal ~ pi*(radio^2) = pi*(p1^2) return math.pi*(p1**2) else: - # Por defecto, algo por si la geo no es conocida return 1.0 diff --git a/src/tabs/tab_dynamic.py b/src/tabs/tab_dynamic.py deleted file mode 100644 index 84ce8f9..0000000 --- a/src/tabs/tab_dynamic.py +++ /dev/null @@ -1,307 +0,0 @@ -# src/tab_dynamic.py - -import tkinter as tk -from tkinter import ttk -from tkinter.scrolledtext import ScrolledText -import math -import numpy as np - -MU0 = 4.0e-7 * math.pi - -class TabDynamic: - def __init__(self, notebook, tab_coil=None, tab_simulator=None, tab_drag=None): - """ - Pestaña que: - - Obtiene el trabajo W desde tab_simulator. - - Calcula la reluctancia media con la integración en x in [0, h_c]. - - Usa el modelo W = ((N I)^2 * h_c)/(4 mu0 S_fe (sumR_avg)^2) para hallar I. - - Ofrece dimensionamiento de fuente (condensador / DC). - """ - self.notebook = notebook - self.tab_coil = tab_coil - self.tab_simulator = tab_simulator - self.tab_drag = tab_drag - - self.frame = tk.Frame(notebook) - self.frame.pack(fill="both", expand=True) - - # Panel Izq: Botones / parámetros - left_frame = tk.Frame(self.frame) - left_frame.pack(side="left", fill="y", padx=5, pady=5) - - # Panel Der: Logs - right_frame = tk.Frame(self.frame, bd=2, relief="groove") - right_frame.pack(side="right", fill="both", expand=True, padx=5, pady=5) - - # Sección 1: Importar Config - import_frame = tk.LabelFrame(left_frame, text="1) Importar Config") - import_frame.pack(fill="x", pady=5) - - btn_import = tk.Button(import_frame, text="Importar Config", command=self.importar_config) - btn_import.pack(pady=5) - - self.var_W_mech = tk.StringVar(value="") - tk.Label(import_frame, text="W (J):").pack(anchor="w") - tk.Entry(import_frame, textvariable=self.var_W_mech, width=12, state="readonly").pack(pady=2) - - self.W_mech = 0.0 # energía mecánica importada - - # Sección 2: Calcular Reluctancia Media - rel_frame = tk.LabelFrame(left_frame, text="2) Reluctancia Media") - rel_frame.pack(fill="x", pady=5) - - self.var_sumR_avg = tk.StringVar(value="") - tk.Button(rel_frame, text="Calcular Rel. Media", command=self.calcular_reluctancia_media).pack(pady=5) - tk.Label(rel_frame, text="sum(R)_avg:").pack(anchor="w") - tk.Entry(rel_frame, textvariable=self.var_sumR_avg, width=15, state="readonly").pack(pady=2) - - self.sumR_avg = 0.0 # valor en el interior - - # Sección 3: Calcular Corriente - work_frame = tk.LabelFrame(left_frame, text="3) Corriente Necesaria") - work_frame.pack(fill="x", pady=5) - - self.var_S_fe = tk.DoubleVar(value=1e-4) # Sección en la zona férrea - tk.Label(work_frame, text="S_fe (m²):").grid(row=0, column=0, sticky="w", padx=5, pady=2) - tk.Entry(work_frame, textvariable=self.var_S_fe, width=10).grid(row=0, column=1, padx=5, pady=2) - - tk.Button(work_frame, text="Calcular Corriente", command=self.calcular_corriente_trabajo).grid(row=1, column=0, columnspan=2, pady=5) - - self.var_I_req = tk.StringVar(value="") - tk.Label(work_frame, text="I_req (A):").grid(row=2, column=0, sticky="w", padx=5, pady=2) - tk.Entry(work_frame, textvariable=self.var_I_req, width=10, state="readonly").grid(row=2, column=1, padx=5, pady=2) - - # Sección 4: Dimensionar Fuente - fuente_frame = tk.LabelFrame(left_frame, text="4) Dimensionar Fuente") - fuente_frame.pack(fill="x", pady=5) - - tk.Button(fuente_frame, text="Dimensionar Capacitor", command=self.dimensionar_condensador).pack(pady=5) - tk.Button(fuente_frame, text="Fuente DC minima", command=self.dimensionar_fuente_dc).pack(pady=5) - - self.var_C_sug = tk.StringVar(value="") - self.var_V_sug = tk.StringVar(value="") - self.var_Vdc_min = tk.StringVar(value="") - - tk.Label(fuente_frame, text="C (F) ~").pack(anchor="w") - tk.Entry(fuente_frame, textvariable=self.var_C_sug, width=15, state="readonly").pack(pady=2) - - tk.Label(fuente_frame, text="Vcap (V) ~").pack(anchor="w") - tk.Entry(fuente_frame, textvariable=self.var_V_sug, width=15, state="readonly").pack(pady=2) - - tk.Label(fuente_frame, text="V_DC min (V) ~").pack(anchor="w") - tk.Entry(fuente_frame, textvariable=self.var_Vdc_min, width=15, state="readonly").pack(pady=2) - - # LOGS - tk.Label(right_frame, text="Logs:").pack(anchor="w") - self.log_area = ScrolledText(right_frame, wrap="word", height=25, width=50) - self.log_area.pack(fill="both", expand=True) - self.log_area.configure(state="disabled") - self.log_area.tag_config("info", foreground="green") - self.log_area.tag_config("error", foreground="red") - - # -------------------------------------------------------- - # Log helper - # -------------------------------------------------------- - def log_message(self, msg, mode="info"): - self.log_area.configure(state="normal") - self.log_area.insert("end", msg + "\n", mode) - self.log_area.see("end") - self.log_area.configure(state="disabled") - - # -------------------------------------------------------- - # 1) Importar Config (energía W) - # -------------------------------------------------------- - def importar_config(self): - """ - Lee la energía mecánica W de tab_simulator y la guarda en self.W_mech - """ - try: - if not self.tab_simulator: - raise ValueError("No hay tab_simulator para leer W.") - w_val = self.tab_simulator.get_energy_required() - if w_val<=0: - raise ValueError("Energía <= 0.") - self.W_mech = w_val - self.var_W_mech.set(f"{w_val:.3f}") - self.log_message(f"Importado W={w_val:.3f} J", "info") - - except Exception as e: - self.log_message(f"Error importar_config: {e}", "error") - - # -------------------------------------------------------- - # 2) Calcular Reluctancia Media (sum(R)_avg) - # => integrando la ecuación sum_R(x)= ... - # -------------------------------------------------------- - def calcular_reluctancia_media(self): - try: - if not self.tab_coil: - raise ValueError("Falta referencia a tab_coil.") - if not self.tab_drag: - raise ValueError("Falta referencia a tab_drag.") - - # 1) Leer h_c, N, r_int (en mm->m) - h_c_m = float(self.tab_coil.var_h_c.get())/1000.0 - if h_c_m<=0: - raise ValueError("h_c_m <=0.") - - r_int_m = float(self.tab_coil.var_r_int.get())/1000.0 - if r_int_m<=0: - raise ValueError("r_int_m <=0.") - - # 2) l_fe => de tab_drag - l_fe_m = self.tab_drag.get_l_fe() # en metros - if l_fe_m<0: - raise ValueError("l_fe<0?") - - # 3) s_disp => get_projectile_section_for_reluctance - s_disp = self.tab_drag.get_projectile_section_for_reluctance(self.tab_coil) - if s_disp<=0: - raise ValueError("s_disp <=0.") - - # 4) s_c= pi*r_int^2 - s_c = math.pi*(r_int_m**2) - if s_c<=0: - raise ValueError("s_c<=0.") - - # 5) Definir sumR(x) - def sumR_of_x(x): - # sum_R = h_c/(mu0*s_disp) - # + (h_c + l_fe - x)/(mu0*s_disp) - # + (h_c - x)/(mu0*s_c) - return ( - (h_c_m/(MU0*s_disp)) - + ((h_c_m + l_fe_m - x)/(MU0*s_disp)) - + ((h_c_m - x)/(MU0*s_c)) - ) - - # 6) Integración en [0..h_c_m] - n_steps=200 - dx = h_c_m/n_steps - area_sum=0.0 - x_curr=0.0 - for _ in range(n_steps): - x_mid= x_curr+0.5*dx - val_mid= sumR_of_x(x_mid) - area_sum+= val_mid - x_curr+=dx - area_sum*= dx - - sumR_avg= area_sum/h_c_m - if sumR_avg<=1e-30: - raise ValueError("sumR_avg nulo o negativo.") - - self.sumR_avg= sumR_avg - self.var_sumR_avg.set(f"{sumR_avg:.3e}") - self.log_message(f"Reluctancia media= {sumR_avg:.3e} H^-1", "info") - - except ValueError as ve: - self.sumR_avg=0.0 - self.var_sumR_avg.set("") - self.log_message(f"Error calc Reluctancia media: {ve}", "error") - except Exception as ex: - self.sumR_avg=0.0 - self.var_sumR_avg.set("") - self.log_message(f"Excepción calc Reluct. media: {ex}", "error") - - # -------------------------------------------------------- - # 3) Calcular Corriente, con W = ((N I)^2 * h_c)/(4 mu0 S_fe (sumR_avg)^2) - # -------------------------------------------------------- - def calcular_corriente_trabajo(self): - try: - if self.W_mech<=0: - raise ValueError("No hay W_mech positivo. Importa config primero.") - if self.sumR_avg<=0: - raise ValueError("sumR_avg<=0. Calcula la Reluctancia media antes.") - - # 1) Leer h_c (mm->m), N, etc. de tab_coil - h_c_m = float(self.tab_coil.var_h_c.get())/1000.0 - N_val = float(self.tab_coil.var_N.get()) - if h_c_m<=0 or N_val<=0: - raise ValueError("Parámetros de bobina inválidos.") - - # 2) Leer S_fe - S_fe_val= self.var_S_fe.get() - if S_fe_val<=0: - raise ValueError("S_fe <=0") - - # 3) Tomamos sumR_avg, W - sumR_avg= self.sumR_avg - W= self.W_mech - - # 4) W= ((N I)^2 * h_c)/(4 mu0 S_fe (sumR_avg)^2) - # => (N I)^2= [4 mu0 S_fe (sumR_avg)^2 W]/h_c - top= 4.0*MU0*S_fe_val*(sumR_avg**2)* W - bottom= h_c_m - if bottom<=1e-30: - raise ValueError("h_c_m=0?") - - NI_sq= top/bottom - if NI_sq<=0: - raise ValueError("Resultado (N I)^2 <=0, no válido.") - - NI= math.sqrt(NI_sq) - I_req= NI/ N_val - - self.var_I_req.set(f"{I_req:.3f}") - self.log_message(f"I necesaria= {I_req:.3f} A", "info") - - except ValueError as ve: - self.var_I_req.set("") - self.log_message(f"Error calc I trabajo: {ve}", "error") - except Exception as ex: - self.var_I_req.set("") - self.log_message(f"Excepción calc I trabajo: {ex}", "error") - - # -------------------------------------------------------- - # 4) Dimensionar la fuente (ejemplo condensador y DC) - # -------------------------------------------------------- - def dimensionar_condensador(self): - """ - Ejemplo: suponer que la energía total W -> (1/2)C V^2 - W_marg = W_mech * factor... etc. - """ - try: - W= self.W_mech - if W<=0: - raise ValueError("Primero importa config. W<=0?") - - # suponer un factor "pérdidas" - eff=0.7 - # E capacitor= W/ eff - E_cap= W/eff - # asumes C= 1mF => V= sqrt(2 E_cap/C) - # o V= 200 => C= 2E_cap/V^2, etc. - # Aquí arbitrariamente p.ej C=1e-3 y calculamos V - C_val= 1e-3 - Vcalc= math.sqrt(2.0*E_cap/C_val) - - self.var_C_sug.set(f"{C_val:.3g}") - self.var_V_sug.set(f"{Vcalc:.1f}") - self.log_message(f"Caps: C=1mF => V~{Vcalc:.1f} V (descarga)", "info") - - except ValueError as ve: - self.log_message(f"Error dimensionar_condensador: {ve}", "error") - except Exception as ex: - self.log_message(f"Excepción dimensionar_condensador: {ex}", "error") - - def dimensionar_fuente_dc(self): - """ - Ejemplo simple: V_dc >= R_coil * I_req - R_coil en ohms => la obtendrías o la metes manual. - """ - try: - Ireq_str= self.var_I_req.get() - Ireq= float(Ireq_str) - if Ireq<=0: - raise ValueError("I_req <=0? Calcula la corriente primero.") - - # supongamos R_coil= 2 ohms (ejemplo) - R_coil= 2.0 - V_dc= R_coil* Ireq - self.var_Vdc_min.set(f"{V_dc:.1f}") - self.log_message(f"Fuente DC~ {V_dc:.1f} V (min. ohmico)", "info") - - except ValueError as ve: - self.log_message(f"Error dimensionar_fuente_dc: {ve}", "error") - except Exception as ex: - self.log_message(f"Excepción dimensionar_fuente_dc: {ex}", "error") diff --git a/src/tabs/tab_power.py b/src/tabs/tab_power.py new file mode 100644 index 0000000..1563a7b --- /dev/null +++ b/src/tabs/tab_power.py @@ -0,0 +1,296 @@ +# tab_power.py + +import tkinter as tk +from tkinter import ttk +from tkinter.scrolledtext import ScrolledText +import math + +class TabPower: + def __init__(self, notebook, tab_coil, tab_simulator): + """ + Pestaña para dimensionar C o V0 a partir de la energía mecánica deseada, + considerando n etapas/bobinas idénticas. + + :param notebook: ttk.Notebook donde se añade esta pestaña + :param tab_coil: referencia a la instancia de TabCoil + :param tab_simulator: referencia a la instancia de TabSimulator (para leer E_target) + """ + self.notebook = notebook + self.tab_coil = tab_coil + self.tab_simulator = tab_simulator + + # Frame principal para la pestaña + self.frame = tk.Frame(notebook) + self.frame.pack(fill="both", expand=True) + + # Añadir la pestaña al notebook + notebook.add(self.frame, text="Power Stages (Energy-driven)") + + # Layout: parte izquierda (entradas) y derecha (resultados / logs) + self.frame_left = tk.Frame(self.frame) + self.frame_left.pack(side="left", fill="y", padx=5, pady=5) + + self.frame_right = tk.Frame(self.frame, bd=2, relief="groove") + self.frame_right.pack(side="right", fill="both", expand=True, padx=5, pady=5) + + # ------------------------------ + # Variables y widgets de entrada + # ------------------------------ + # Modo de dimensionado + self.mode_var = tk.StringVar(value="Dimensionar C") # o "Dimensionar V0" + tk.Label(self.frame_left, text="Modo de Dimensionado:").pack(anchor="w") + self.combo_mode = ttk.Combobox( + self.frame_left, textvariable=self.mode_var, + values=["Dimensionar C", "Dimensionar V0"], + state="readonly" + ) + self.combo_mode.bind("<>", self.on_mode_change) + self.combo_mode.pack(pady=2) + + # Número de etapas + tk.Label(self.frame_left, text="Número de etapas (n):").pack(anchor="w") + self.var_n = tk.IntVar(value=3) + tk.Entry(self.frame_left, textvariable=self.var_n, width=10).pack(pady=2) + + # Capacidad (si se dimensiona V0, la capacit se fija) + tk.Label(self.frame_left, text="Capacidad (µF):").pack(anchor="w") + self.var_C = tk.DoubleVar(value=100.0) # ejemplo + self.entry_C = tk.Entry(self.frame_left, textvariable=self.var_C, width=10) + self.entry_C.pack(pady=2) + + # Tensión inicial (si se dimensiona C, la tensión se fija) + tk.Label(self.frame_left, text="Tensión inicial (V):").pack(anchor="w") + self.var_V0 = tk.DoubleVar(value=200.0) # ejemplo + self.entry_V0 = tk.Entry(self.frame_left, textvariable=self.var_V0, width=10) + self.entry_V0.pack(pady=2) + + # Tiempo de descarga aproximado + tk.Label(self.frame_left, text="Tiempo de etapa (ms):").pack(anchor="w") + self.var_time_ms = tk.DoubleVar(value=10.0) # 10 ms + tk.Entry(self.frame_left, textvariable=self.var_time_ms, width=10).pack(pady=2) + + # Botón dimensionar + tk.Button(self.frame_left, text="Dimensionar", command=self.dimensionar).pack(pady=5) + + # ------------------------------ + # Sección derecha: Logs/Resultados + # ------------------------------ + tk.Label(self.frame_right, text="Resultados:", font=("Arial",10,"bold")).pack(anchor="nw", padx=5, pady=5) + self.log_area = ScrolledText(self.frame_right, wrap="word", height=20, width=50) + self.log_area.pack(fill="both", expand=True, padx=5, pady=5) + self.log_area.configure(state="disabled") + + # Forzar actualización inicial de estados de input + self.on_mode_change() + + def on_mode_change(self, event=None): + """Habilita o deshabilita las entradas de C o V0 según el modo de dimensionado.""" + mode = self.mode_var.get() + if mode == "Dimensionar C": + # Bloqueamos el field de C para escritura manual? + # O, según la lógica, convendría DESBLOQUEAR C si lo vamos a dimensionar? + # Típicamente: dimensionar C => el usuario fija V0 + self.entry_C.config(state="disabled") # Se calculará + self.entry_V0.config(state="normal") # Se ingresa manualmente + else: + # Dimensionar V0 => el usuario fija C + self.entry_C.config(state="normal") + self.entry_V0.config(state="disabled") + + def log_message(self, text, mode="info"): + """Inserta texto en el área de log.""" + self.log_area.configure(state="normal") + if mode=="error": + self.log_area.insert("end", "ERROR: " + text + "\n", "error") + else: + self.log_area.insert("end", text + "\n", mode) + self.log_area.see("end") + self.log_area.configure(state="disabled") + + def dimensionar(self): + """ + Lee la energía objetivo desde TabSimulator, y ajusta C o V0 + para que la energía total (n etapas) se aproxime a E_target. + """ + # 0) Energía objetivo proveniente de TabSimulator + E_target_total = self.tab_simulator.get_energy_required() + if E_target_total <= 0: + self.log_message("E_target <= 0. Asegúrate de que TabSimulator calcule algo válido.", "error") + return + + # n (etapas) + n = self.var_n.get() + if n < 1: + self.log_message("El número de etapas debe ser >= 1", "error") + return + + # => La energía por etapa + E_target_stage = E_target_total / n + + # 1) Leer inductancia y resistencia desde TabCoil + try: + L_uH = float(self.tab_coil.var_L.get()) # microHenrios + R_coil = float(self.tab_coil.var_R.get()) # Ohms + except ValueError: + self.log_message("No se pudo leer L/R de TabCoil.", "error") + return + L_coil = L_uH * 1e-6 # Henrios + + # h_c + try: + h_c_mm = float(self.tab_coil.var_h_c.get()) + except ValueError: + self.log_message("No se pudo leer h_c de TabCoil.", "error") + return + h_c = h_c_mm / 1000.0 # m + + # 2) Leer los datos de (C, V0, dt) (aunque uno de los dos se va a dimensionar) + dt_ms = self.var_time_ms.get() + if dt_ms <= 0: + self.log_message("Tiempo de etapa (ms) inválido", "error") + return + T_total = dt_ms*1e-3 + + mode = self.mode_var.get() + + # Obtenemos un valor 'fijo' para el que no dimensionamos + # y definimos la test_function acorde + if mode=="Dimensionar C": + # El user fija V0: + try: + V0_fixed = float(self.var_V0.get()) + if V0_fixed <= 0: + self.log_message("Tensión (V) inválida", "error") + return + except ValueError: + self.log_message("Tensión (V) inválida", "error") + return + + # Rango de bisección en [Cmin, Cmax], µF + lower = 0.1 + upper = 1e6 + def test_function(C_uF): + E_stage = self.simular_descarga( + C_uF, V0_fixed, L_coil, R_coil, T_total, h_c + ) + return E_stage + + else: + # Dimensionar V0 => user fija C + try: + C_uF_fixed = float(self.var_C.get()) + if C_uF_fixed<=0: + self.log_message("Capacidad (µF) inválida", "error") + return + except ValueError: + self.log_message("Capacidad (µF) inválida", "error") + return + + # Rango de bisección en [1..5000] V, p. ej. + lower = 1.0 + upper = 5000.0 + def test_function(V0): + E_stage = self.simular_descarga( + C_uF_fixed, V0, L_coil, R_coil, T_total, h_c + ) + return E_stage + + # Bisección + E_low = test_function(lower) + E_up = test_function(upper) + + # Comprobación de que la energía buscada (E_target_stage) está entre E_low y E_up + if not ((E_low <= E_target_stage <= E_up) or (E_up <= E_target_stage <= E_low)): + self.log_message("ADVERTENCIA: El rango de bisección puede no encapsular la E_target. Ajusta límites.", "error") + + iteration_count = 0 + max_iter = 40 + tol = 0.01*E_target_stage # 1% de la energía por etapa + best_param = 0.0 + while iteration_count < max_iter: + mid = 0.5*(lower + upper) + E_mid = test_function(mid) + diff = E_mid - E_target_stage + if abs(diff) < tol: + best_param = mid + break + # Suponemos monotonicidad: +C => +E, +V0 => +E + if E_mid > E_target_stage: + upper = mid + else: + lower = mid + iteration_count += 1 + best_param = mid + + E_final_stage = test_function(best_param) + E_final_total = E_final_stage * n + diff_total = E_final_total - E_target_total + + # 3) Mostrar resultados + self.log_message("-"*40) + self.log_message(f"E_target_total = {E_target_total:.3f} J, n = {n}") + self.log_message(f"E_target_stage = {E_target_stage:.3f} J", "info") + + if mode=="Dimensionar C": + self.log_message(f"Dimensionado de C => V0={V0_fixed:.1f} V fijo.", "info") + self.log_message(f"Capacidad final ~ {best_param:.2f} µF", "info") + else: + self.log_message(f"Dimensionado de V0 => C={self.var_C.get():.1f} µF fijo.", "info") + self.log_message(f"Tensión final ~ {best_param:.2f} V", "info") + + self.log_message(f"E_result_stage ~ {E_final_stage:.3f} J => total ~ {E_final_total:.3f} J (diff={diff_total:.3f})", "info") + self.log_message("-"*40) + + + def simular_descarga(self, C_uF, V0, L_coil, R_coil, T_total, h_c): + """ + Modelo simplificado R-L(x)-C de una 'etapa' para un tiempo T_total. + Devuelve la energía consumida del condensador. + + Reutilizamos la lógica de Euler para la descarga, + asumiendo L varía ~ 20% a lo largo x in [0..h_c]. + """ + if C_uF<=0 or V0<=0 or T_total<=0: + return 0.0 + + # Convertimos C a F + C = C_uF * 1e-6 + # Asumimos L variable ~ 20% de variación + L0 = 1.2*L_coil + Lf = 0.8*L_coil + + def L_of_x(x): + return L0 + (Lf - L0)*(x/h_c) if h_c>1e-9 else L_coil + def dLdx_of_x(x): + return (Lf - L0)/h_c if h_c>1e-9 else 0.0 + + N_steps = 1000 + dt = T_total/N_steps + vCap = V0 + i = 0.0 + + def x_of_t(t): + return (h_c / T_total)*t if T_total>1e-9 else 0.0 + + for step in range(N_steps+1): + x = x_of_t(step*dt) + Lx = L_of_x(x) + dLdt = dLdx_of_x(x)*(h_c / T_total) + + if abs(Lx)>1e-12: + di_dt = (vCap - R_coil*i - i*dLdt)/Lx + else: + di_dt = 0.0 + + i_new = i + di_dt*dt + vCap_new = vCap - (i/C)*dt + if vCap_new<0: + vCap_new=0.0 + i = i_new + vCap = vCap_new + + # Energía consumida ~ 1/2*C*(V0^2 - vCap^2) + E_consumida = 0.5*C*(V0**2 - vCap**2) + if E_consumida<0: + E_consumida=0.0 + return E_consumida \ No newline at end of file diff --git a/src/tabs/tab_search.py b/src/tabs/tab_search.py index 20d3b9d..6e48965 100644 --- a/src/tabs/tab_search.py +++ b/src/tabs/tab_search.py @@ -1,68 +1,38 @@ -# tab_search.py - import tkinter as tk from tkinter import ttk import math import matplotlib - matplotlib.use("TkAgg") import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg - class TabSearch: def __init__(self, notebook, tab_simulator): - """ - Tercera pestaña: 'Búsqueda de ángulo'. - Recibe 'tab_simulator' para leer la config en la pestaña 1: - - masa (m) - - coef de rozamiento (b) - - altura h0 - - si hay drag o no - - alcance (si el modo es "Alcance (m)") - """ self.notebook = notebook - self.tab_sim = tab_simulator # referencia a la pestaña de simulación - + self.tab_sim = tab_simulator self.frame = tk.Frame(notebook, width=280) self.frame.pack(side="left", fill="both", expand=True) - # Fijamos ancho y desactivamos propagación para la columna self.frame.pack_propagate(False) - # -- Layout principal: izquierda (botones + info), derecha (gráfico) -- self.frame_left = tk.Frame(self.frame, width=240) self.frame_left.pack(side="left", fill="y", padx=5, pady=5) self.frame_left.pack_propagate(False) - self.frame_right = tk.Frame(self.frame) self.frame_right.pack(side="right", fill="both", expand=True, padx=5, pady=5) - # 1) Botones e info en la parte izquierda tk.Button(self.frame_left, text="Importar config", command=self.import_config).pack(pady=5) tk.Button(self.frame_left, text="Ejecutar búsqueda", command=self.run_search).pack(pady=5) - # Etiquetas para mostrar la config importada - self.label_m = tk.Label(self.frame_left, text="Masa: ??? kg", bg="white") - self.label_m.pack(pady=2, anchor="w") + self.label_m = tk.Label(self.frame_left, text="Masa: ??? kg", bg="white"); self.label_m.pack(pady=2, anchor="w") + self.label_b = tk.Label(self.frame_left, text="b: ???", bg="white"); self.label_b.pack(pady=2, anchor="w") + self.label_h0 = tk.Label(self.frame_left, text="h0: ??? m", bg="white"); self.label_h0.pack(pady=2, anchor="w") + self.label_drag = tk.Label(self.frame_left, text="Drag: ???", bg="white"); self.label_drag.pack(pady=2, anchor="w") + self.label_x_target = tk.Label(self.frame_left, text="X_target: ???", bg="white"); self.label_x_target.pack(pady=2, anchor="w") - self.label_b = tk.Label(self.frame_left, text="b: ???", bg="white") - self.label_b.pack(pady=2, anchor="w") - - self.label_h0 = tk.Label(self.frame_left, text="h0: ??? m", bg="white") - self.label_h0.pack(pady=2, anchor="w") - - self.label_drag = tk.Label(self.frame_left, text="Drag: ???", bg="white") - self.label_drag.pack(pady=2, anchor="w") - - self.label_x_target = tk.Label(self.frame_left, text="X_target: ???", bg="white") - self.label_x_target.pack(pady=2, anchor="w") - - # Label para mostrar el ángulo/vel. hallados tras la búsqueda self.label_result = tk.Label(self.frame_left, text="Resultado:\n...", fg="green", bg="white") self.label_result.pack(pady=10, fill="x") - # 2) Creamos figure + canvas a la derecha (para dibujar la curva) - self.fig = plt.Figure(figsize=(4, 3), dpi=100) + self.fig = plt.Figure(figsize=(4,3), dpi=100) self.ax = self.fig.add_subplot(111) self.ax.set_xlabel("Ángulo (grados)") self.ax.set_ylabel("Vel. requerida (m/s)") @@ -71,149 +41,85 @@ class TabSearch: self.canvas_widget = self.canvas.get_tk_widget() self.canvas_widget.pack(fill="both", expand=True) - # Variables donde guardaremos la config importada - self.m = 1.0 # masa - self.b = 0.0 # coef rozamiento - self.h0 = 0.0 # altura + self.m, self.b, self.h0 = 1.0, 0.0, 0.0 self.has_drag = False - self.x_target = None # Alcance importado, si está en modo "Alcance (m)" + self.x_target = None def import_config(self): - """ - Lee la config actual de la pestaña 1 (simulador): - - masa - - b (si hay rozamiento) - - h0 - - check_rozamiento => has_drag - - y si param es "Alcance (m)", tomamos ese v0 como x_target - """ try: - # Masa self.m = float(self.tab_sim.entry_masa.get()) - - # Rozamiento if self.tab_sim.check_rozamiento.get(): self.has_drag = True self.b = float(self.tab_sim.entry_b.get()) else: self.has_drag = False self.b = 0.0 - - # Altura self.h0 = float(self.tab_sim.entry_h0.get()) - - # Alcance si param== "Alcance (m)" if self.tab_sim.parametro_var.get() == "Alcance (m)": self.x_target = float(self.tab_sim.entry_v0.get()) else: self.x_target = None - # Actualizamos en pantalla self.label_m.config(text=f"Masa: {self.m:.2f} kg") self.label_b.config(text=f"b: {self.b:.4f}") self.label_h0.config(text=f"h0: {self.h0:.2f} m") self.label_drag.config(text=f"Drag: {self.has_drag}") - if self.x_target is not None: self.label_x_target.config(text=f"X_target: {self.x_target:.2f} m") else: self.label_x_target.config(text="X_target: (No hay)") - self.label_result.config(text="Config importada OK", bg="lightgreen", fg="black") - except ValueError: self.label_result.config(text="Error al leer config", bg="red", fg="white") self.x_target = None def run_search(self): - """ - Barre ángulos de 0..90 y busca la velocidad mínima - para alcanzar la distancia x_target (si existe). - Si no hay x_target (porque el modo era Vel(m/s)), - mostramos error. - """ if self.x_target is None: - # Si el usuario está en modo "Velocidad (m/s)" en la pestaña 1, - # no tenemos 'x_target' válido. Lógica: - self.label_result.config( - text="Error: en la pestaña 1 no se eligió 'Alcance (m)'", - bg="red", fg="white" - ) + self.label_result.config(text="Error: en la pestaña 1 no se eligió 'Alcance (m)'", bg="red", fg="white") return - - X_target = self.x_target # usar la que importamos - angulos = [] - velocidades = [] - best_angle = None - best_v = 1e9 - - # Recorremos ángulos de 0..90 + X_target = self.x_target + angulos, velocidades = [], [] + best_angle, best_v = None, 1e9 for angle_deg in range(0, 91): - v0_min = 0.0 - v0_max = 300.0 - final_v = 0.0 - - # Bisección + v0_min, v0_max, final_v = 0.0, 300.0, 0.0 for _ in range(100): - guess = 0.5*(v0_min + v0_max) + guess = 0.5*(v0_min+v0_max) dist = self.simular_dist(guess, angle_deg, self.has_drag) if abs(dist - X_target) < 0.1: final_v = guess break - if dist < X_target: - v0_min = guess - else: - v0_max = guess + if dist < X_target: v0_min = guess + else: v0_max = guess final_v = guess - angulos.append(angle_deg) velocidades.append(final_v) - if final_v < best_v: - best_v = final_v - best_angle = angle_deg + best_v, best_angle = final_v, angle_deg - # Dibujamos self.ax.clear() self.ax.set_xlabel("Ángulo (grados)") self.ax.set_ylabel("Vel. requerida (m/s)") self.ax.plot(angulos, velocidades, color="red") - - # Marcamos el punto mínimo - self.ax.plot([best_angle], [best_v], marker="o", markersize=8, color="green") + self.ax.plot([best_angle],[best_v], marker="o", markersize=8, color="green") self.canvas.draw() - self.label_result.config( - text=f"Mín. en {best_angle}°, v0={best_v:.2f} m/s", - bg="white", fg="green" - ) + self.label_result.config(text=f"Mín. en {best_angle}°, v0={best_v:.2f} m/s", bg="white", fg="green") def simular_dist(self, v0_guess, angle_deg, drag): - """ - Integra la distancia horizontal partiendo de (0,h0) - hasta y<=0. Devuelve x final. Usa self.m, self.b, self.h0, drag (bool). - """ dt = 0.01 - x = 0.0 - y = self.h0 + x, y = 0.0, self.h0 alpha = math.radians(angle_deg) - vx = v0_guess * math.cos(alpha) - vy = v0_guess * math.sin(alpha) - + vx = v0_guess*math.cos(alpha) + vy = v0_guess*math.sin(alpha) while True: if drag: - ax = -(self.b / self.m) * vx - ay = -9.8 - (self.b / self.m) * vy + ax = -(self.b/self.m)*vx + ay = -9.8 - (self.b/self.m)*vy else: - ax = 0.0 - ay = -9.8 - + ax, ay = 0.0, -9.8 vx += ax*dt vy += ay*dt - x += vx*dt - y += vy*dt - - if y <= 0: - break - + x += vx*dt + y += vy*dt + if y <= 0: break return x diff --git a/src/tabs/tab_simulator.py b/src/tabs/tab_simulator.py index d8a07e4..6aa25f8 100644 --- a/src/tabs/tab_simulator.py +++ b/src/tabs/tab_simulator.py @@ -5,137 +5,77 @@ import math class TabSimulator: def __init__(self, notebook): self.frame = tk.Frame(notebook) - - self.m = 0.0 # Masa - self.h0 = 0.0 # Altura inicial (0..2m) + self.m = 0.0 + self.h0 = 0.0 self.trayectoria = [] self.t_final = 0 self.proyectil = None self.vel_text = None self.current_canvas_width = 1 self.current_canvas_height = 1 + self.energy_required = 0.0 - # ============ Estructura general ============ - # TOP - self.frame_top = tk.Frame(self.frame) - self.frame_top.pack(side="top", fill="x", padx=5, pady=5) + self.frame_top = tk.Frame(self.frame); self.frame_top.pack(side="top", fill="x", padx=5, pady=5) + self.frame_middle = tk.Frame(self.frame); self.frame_middle.pack(side="top", fill="both", expand=True) + self.frame_bottom = tk.Frame(self.frame); self.frame_bottom.pack(side="bottom", fill="both", expand=False) - # MIDDLE (canvas) - self.frame_middle = tk.Frame(self.frame) - self.frame_middle.pack(side="top", fill="both", expand=True) + self.frame_slider_and_energy = tk.Frame(self.frame_bottom); self.frame_slider_and_energy.pack(side="left", fill="y", padx=5, pady=5) + self.frame_slider = tk.Frame(self.frame_slider_and_energy); self.frame_slider.pack(side="top", fill="x", padx=5, pady=5) + self.frame_energy = tk.Frame(self.frame_slider_and_energy, bd=2, relief="groove"); self.frame_energy.pack(side="bottom", fill="both", padx=5, pady=5) + self.frame_log = tk.Frame(self.frame_bottom); self.frame_log.pack(side="right", fill="both", expand=True, padx=5, pady=5) - # BOTTOM (slider + energía + log) - self.frame_bottom = tk.Frame(self.frame) - self.frame_bottom.pack(side="bottom", fill="both", expand=False) - - # - Izquierda: slider + energía - self.frame_slider_and_energy = tk.Frame(self.frame_bottom) - self.frame_slider_and_energy.pack(side="left", fill="y", padx=5, pady=5) - - self.frame_slider = tk.Frame(self.frame_slider_and_energy) - self.frame_slider.pack(side="top", fill="x", padx=5, pady=5) - - self.frame_energy = tk.Frame(self.frame_slider_and_energy, bd=2, relief="groove") - self.frame_energy.pack(side="bottom", fill="both", expand=False, padx=5, pady=5) - - # - Derecha: log - self.frame_log = tk.Frame(self.frame_bottom) - self.frame_log.pack(side="right", fill="both", expand=True, padx=5, pady=5) - - # ============ Fila superior de widgets ============ tk.Label(self.frame_top, text="Parámetro:").grid(row=0, column=0, sticky="w") self.parametro_var = tk.StringVar() - self.combo_param = ttk.Combobox( - self.frame_top, textvariable=self.parametro_var, - values=["Velocidad (m/s)", "Alcance (m)"], width=15 - ) - self.combo_param.grid(row=0, column=1, padx=5) - self.combo_param.current(0) - - self.entry_v0 = tk.Entry(self.frame_top, width=8) - self.entry_v0.grid(row=0, column=2, padx=5) + self.combo_param = ttk.Combobox(self.frame_top, textvariable=self.parametro_var, values=["Velocidad (m/s)","Alcance (m)"], width=15) + self.combo_param.grid(row=0, column=1, padx=5); self.combo_param.current(0) + self.entry_v0 = tk.Entry(self.frame_top, width=8); self.entry_v0.grid(row=0, column=2, padx=5) tk.Label(self.frame_top, text="Ángulo (grados):").grid(row=0, column=3, sticky="w") - self.entry_alpha = tk.Entry(self.frame_top, width=8) - self.entry_alpha.grid(row=0, column=4, padx=5) + self.entry_alpha = tk.Entry(self.frame_top, width=8); self.entry_alpha.grid(row=0, column=4, padx=5) tk.Label(self.frame_top, text="Masa (kg):").grid(row=0, column=5, sticky="w") - self.entry_masa = tk.Entry(self.frame_top, width=8) - self.entry_masa.grid(row=0, column=6, padx=5) + self.entry_masa = tk.Entry(self.frame_top, width=8); self.entry_masa.grid(row=0, column=6, padx=5) - self.check_rozamiento = tk.BooleanVar() - self.check_rozamiento.set(False) - self.chk = tk.Checkbutton( - self.frame_top, text="Incluir rozamiento", - variable=self.check_rozamiento, - command=self.on_toggle_rozamiento - ) + self.check_rozamiento = tk.BooleanVar(); self.check_rozamiento.set(False) + self.chk = tk.Checkbutton(self.frame_top, text="Incluir rozamiento", variable=self.check_rozamiento, command=self.on_toggle_rozamiento) self.chk.grid(row=0, column=7, padx=15) tk.Label(self.frame_top, text="Coef. (b):").grid(row=0, column=8, sticky="e") - self.entry_b = tk.Entry(self.frame_top, width=8, state="disabled") - self.entry_b.grid(row=0, column=9, padx=5) + self.entry_b = tk.Entry(self.frame_top, width=8, state="disabled"); self.entry_b.grid(row=0, column=9, padx=5) - # Altura inicial (0..2) tk.Label(self.frame_top, text="Altura (m):").grid(row=0, column=10, sticky="e") - self.entry_h0 = tk.Entry(self.frame_top, width=8) - self.entry_h0.grid(row=0, column=11, padx=5) - self.entry_h0.insert(0, "0.0") # por defecto + self.entry_h0 = tk.Entry(self.frame_top, width=8); self.entry_h0.grid(row=0, column=11, padx=5) + self.entry_h0.insert(0, "0.0") - # Botón Calcular - self.button_calcular = tk.Button( - self.frame_top, text="Calcular", - command=self.calcular_trayectoria - ) + self.button_calcular = tk.Button(self.frame_top, text="Calcular", command=self.calcular_trayectoria) self.button_calcular.grid(row=0, column=12, padx=10) - # Cajitas para pos X e Y tk.Label(self.frame_top, text="Pos X (m):").grid(row=0, column=13, padx=5) - self.entry_pos_x = tk.Entry(self.frame_top, width=8) - self.entry_pos_x.grid(row=0, column=14, padx=5) + self.entry_pos_x = tk.Entry(self.frame_top, width=8); self.entry_pos_x.grid(row=0, column=14, padx=5) tk.Label(self.frame_top, text="Pos Y (m):").grid(row=0, column=15, padx=5) - self.entry_pos_y = tk.Entry(self.frame_top, width=8) - self.entry_pos_y.grid(row=0, column=16, padx=5) + self.entry_pos_y = tk.Entry(self.frame_top, width=8); self.entry_pos_y.grid(row=0, column=16, padx=5) - # ============ Canvas ============ self.canvas = tk.Canvas(self.frame_middle, bg="white") self.canvas.pack(fill="both", expand=True) self.canvas.bind("", self.on_resize) - # ============ Slider tiempo ============ - self.slider_time = tk.Scale( - self.frame_slider, from_=0, to=1, resolution=0.01, - orient=tk.HORIZONTAL, label="Tiempo (s):", - command=self.actualizar_posicion - ) + self.slider_time = tk.Scale(self.frame_slider, from_=0, to=1, resolution=0.01, orient=tk.HORIZONTAL, label="Tiempo (s):", command=self.actualizar_posicion) self.slider_time.pack(fill="x") - # ============ Cuadro energía ============ - tk.Label(self.frame_energy, text="Energía mecánica", font=("Arial", 10, "bold")).pack() + tk.Label(self.frame_energy, text="Energía mecánica", font=("Arial",10,"bold")).pack() + self.label_Ec = tk.Label(self.frame_energy, text="Ec: 0.0 J"); self.label_Ec.pack(anchor="w", padx=5) + self.label_Ep = tk.Label(self.frame_energy, text="Ep: 0.0 J"); self.label_Ep.pack(anchor="w", padx=5) + self.label_Etot = tk.Label(self.frame_energy, text="E_total: 0.0 J"); self.label_Etot.pack(anchor="w", padx=5) + self.label_Esobredim = tk.Label(self.frame_energy, text="E_total x1.15: 0.0 J"); self.label_Esobredim.pack(anchor="w", padx=5) - self.label_Ec = tk.Label(self.frame_energy, text="Ec: 0.0 J") - self.label_Ec.pack(anchor="w", padx=5) - - self.label_Ep = tk.Label(self.frame_energy, text="Ep: 0.0 J") - self.label_Ep.pack(anchor="w", padx=5) - - self.label_Etot = tk.Label(self.frame_energy, text="E_total: 0.0 J") - self.label_Etot.pack(anchor="w", padx=5) - - self.label_Esobredim = tk.Label(self.frame_energy, text="E_total x1.15: 0.0 J") - self.label_Esobredim.pack(anchor="w", padx=5) - - self.energy_required = 0.0 - - # Logger self.text_log = tk.Text(self.frame_log, height=2, state="normal") self.text_log.pack(fill="both", expand=True) - def set_log_message(self, mensaje, bg_color="white", fg_color="black"): + def set_log_message(self, msg, bg_color="white", fg_color="black"): self.text_log.config(state="normal", bg=bg_color, fg=fg_color) self.text_log.delete("1.0", tk.END) - self.text_log.insert(tk.END, mensaje + "\n") + self.text_log.insert(tk.END, msg + "\n") self.text_log.config(state="disabled") def set_b_value(self, new_b): @@ -157,7 +97,6 @@ class TabSimulator: self.dibujar_trayectoria() def calcular_trayectoria(self): - # 1) Lee alpha, masa try: alpha_deg = float(self.entry_alpha.get()) self.m = float(self.entry_masa.get()) @@ -165,26 +104,19 @@ class TabSimulator: self.set_log_message("Error: revisa (ángulo, masa).", "red", "white") return - # 2) Altura - try: - h0_val = float(self.entry_h0.get()) - except ValueError: - h0_val = 0.0 - if h0_val < 0: h0_val = 0.0 - if h0_val > 2: h0_val = 2.0 + try: h0_val = float(self.entry_h0.get()) + except ValueError: h0_val = 0.0 + if h0_val<0: h0_val=0.0 + if h0_val>2: h0_val=2.0 self.h0 = h0_val - # 3) Validar ángulo - if alpha_deg < 0 or alpha_deg > 90: + if alpha_deg<0 or alpha_deg>90: self.set_log_message("Introduce un ángulo entre 0 y 90", "red","white") return - alpha_rad = math.radians(alpha_deg) - # 4) Leer param (Vel/Alcance) modo = self.parametro_var.get() - try: - valor = float(self.entry_v0.get()) + try: valor = float(self.entry_v0.get()) except ValueError: self.set_log_message("Error en el valor (vel/alcance).", "red","white") return @@ -193,35 +125,26 @@ class TabSimulator: if modo == "Velocidad (m/s)": v0 = valor else: - # Modo alcance X_final = valor if not self.check_rozamiento.get(): - v0_min=0.0 - v0_max=1000.0 + v0_min, v0_max = 0.0, 1000.0 for _ in range(100): - guess=0.5*(v0_min+v0_max) - dist_alcanzado = self.simular_dist_sin_rozamiento(guess, alpha_rad, self.h0) - if abs(dist_alcanzado - X_final)<0.1: - v0=guess - break - if dist_alcanzado0.01: - break + vy_new = vy - 9.8*dt + x_new = x + vx*dt + y_new = y + vy*dt + t+=dt; vx= vx; vy= vy_new; x= x_new; y= y_new + if y<=0 and t>0.01: break else: - # con rozamiento lineal while True: self.trayectoria.append((t,x,y,vx,vy)) - ax=-(b/self.m)*vx - ay=-9.8-(b/self.m)*vy - vx_new = vx+ax*dt - vy_new = vy+ay*dt - x_new = x+vx_new*dt - y_new = y+vy_new*dt - t+=dt - vx= vx_new - vy= vy_new - x= x_new - y= y_new - if y<=0 and t>0.01: - break + ax = -(b/self.m)*vx + ay = -9.8 - (b/self.m)*vy + vx_new = vx + ax*dt + vy_new = vy + ay*dt + x_new = x + vx_new*dt + y_new = y + vy_new*dt + t+=dt; vx= vx_new; vy= vy_new; x= x_new; y= y_new + if y<=0 and t>0.01: break self.t_final = t self.slider_time.config(from_=0, to=self.t_final) @@ -296,16 +205,11 @@ class TabSimulator: vy=v0_guess*math.sin(alpha_rad) t=0.0 while True: - vy_new= vy-9.8*dt - x_new= x+ vx*dt - y_new= y+ vy*dt - t+=dt - vx= vx - vy= vy_new - x= x_new - y= y_new - if y<=0 and t>0.01: - break + vy_new = vy - 9.8*dt + x_new = x + vx*dt + y_new = y + vy*dt + t+=dt; vx= vx; vy= vy_new; x= x_new; y= y_new + if y<=0 and t>0.01: break return x def simular_dist_con_rozamiento(self, v0_guess, alpha_rad, h0): @@ -315,10 +219,8 @@ class TabSimulator: vx=v0_guess*math.cos(alpha_rad) vy=v0_guess*math.sin(alpha_rad) t=0.0 - try: - b=float(self.entry_b.get()) - except: - b=0.1 + try: b=float(self.entry_b.get()) + except: b=0.1 while True: ax=-(b/self.m)*vx ay=-9.8-(b/self.m)*vy @@ -326,33 +228,22 @@ class TabSimulator: vy_new= vy+ay*dt x_new= x+vx_new*dt y_new= y+vy_new*dt - t+=dt - vx= vx_new - vy= vy_new - x= x_new - y= y_new - if y<=0 and t>0.01: - break + t+=dt; vx= vx_new; vy= vy_new; x= x_new; y= y_new + if y<=0 and t>0.01: break return x def dibujar_trayectoria(self): - if not self.trayectoria: - return - + if not self.trayectoria: return min_x = min(pt[1] for pt in self.trayectoria) max_x = max(pt[1] for pt in self.trayectoria) min_y = min(pt[2] for pt in self.trayectoria) max_y = max(pt[2] for pt in self.trayectoria) - - rx = max_x - min_x - ry = max_y - min_y + rx, ry = max_x - min_x, max_y - min_y if rx<1e-9: rx=1.0 if ry<1e-9: ry=1.0 - - w = self.current_canvas_width - h = self.current_canvas_height + w, h = self.current_canvas_width, self.current_canvas_height margen=20 - scale = min((w-2*margen)/rx, (h-2*margen)/ry) + scale = min((w-2*margen)/rx,(h-2*margen)/ry) self.canvas.delete("all") pts=[] @@ -360,29 +251,25 @@ class TabSimulator: sx = margen + (xx - min_x)*scale sy = (h - margen) - (yy - min_y)*scale pts.append((sx, sy)) - for i in range(len(pts)-1): x1,y1=pts[i] x2,y2=pts[i+1] self.canvas.create_line(x1,y1,x2,y2,fill="blue") if pts: - x0,y0 = pts[0] + x0,y0=pts[0] r=5 - self.proyectil = self.canvas.create_oval(x0-r,y0-r, x0+r,y0+r, fill="red") + self.proyectil = self.canvas.create_oval(x0-r,y0-r,x0+r,y0+r, fill="red") self.vel_text = self.canvas.create_text(x0+15,y0, text="v=0.00 m/s", fill="black") self.scale=scale self.margen=margen self.min_x=min_x self.min_y=min_y - self.actualizar_energia(0) def actualizar_posicion(self, val): - if not self.trayectoria or not self.proyectil: - return - + if not self.trayectoria or not self.proyectil: return t_slider = float(val) if t_slider<=0: x_real=self.trayectoria[0][1] @@ -397,74 +284,54 @@ class TabSimulator: else: tiempos=[p[0] for p in self.trayectoria] idx=0 - while idx=self.t_final: - vx_=self.trayectoria[-1][3] - vy_=self.trayectoria[-1][4] - x_=self.trayectoria[-1][1] - y_=self.trayectoria[-1][2] + vx_, vy_ = self.trayectoria[-1][3], self.trayectoria[-1][4] + x_, y_ = self.trayectoria[-1][1], self.trayectoria[-1][2] else: - tiempos=[p[0] for p in self.trayectoria] - idx=0 - while idx0: - Ep=self.m*9.8*y_ - E_tot=Ec+Ep + Ep = self.m*9.8*y_ if y_>0 else 0.0 + E_tot = Ec + Ep self.energy_required = E_tot E_sobredim=1.15*E_tot @@ -472,6 +339,6 @@ class TabSimulator: self.label_Ep.config(text=f"Ep: {Ep:.2f} J") self.label_Etot.config(text=f"E_total: {E_tot:.2f} J") self.label_Esobredim.config(text=f"E_total x1.15: {E_sobredim:.2f} J") - + def get_energy_required(self): - return self.energy_required \ No newline at end of file + return self.energy_required