import solara as sol
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import plotly.express as px
import leafmap
from datetime import datetime
value1 = sol.reactive(5)
value2 = sol.reactive(1)
value3 = sol.reactive(1.5)
value4 = sol.reactive(1)
value5 = sol.reactive(30)
value6 = sol.reactive(0.1)
value7 = sol.reactive(0.002)
value8 = sol.reactive(0.005)
value9 = sol.reactive(0)
value10 = sol.reactive(-16.4024)
value11 = sol.reactive(-71.5378)
value12 = sol.reactive(datetime.strptime('2024-06-28', '%Y-%m-%d'))
value13 = sol.reactive(13)
value14 = sol.reactive(43)
class Map(leafmap.Map):
def __init__(self, **kwargs):
super().__init__(**kwargs)
# self.add_marker(location = (value10.value, value11.value))
def mirror(x1, x2):
x3 = 2 * x1 - x2
return x3
def rotation(xor, yor, xar, yar, ang): # xor y yor son las coordenadas del centro de rotacion
ang = ang * (np.pi / 180)
cor = np.column_stack((xar - xor, yar - yor))
mor = np.array([[np.cos(ang), - np.sin(ang)], [np.sin(ang), np.cos(ang)]])
cro = np.dot(cor, mor.T)
xro = cro[:, 0] + xor
yro = cro[:, 1] + yor
return xro, yro
@sol.component
def Page():
sol.lab.theme.dark = False
sol.lab.theme.themes.light.primary = "#fa8b02"
sol.Title('Proyecto Solaris')
with sol.AppBar():
sol.Markdown('*Desarrollado por Junior Aguilar*')
with sol.Sidebar():
with sol.Columns([1, 1]):
with sol.Column(gap = '20px', margin = 0):
sol.InputFloat('Latitud', value = value10)
sol.SliderInt('Hora', value = value13, min = 0, max = 24, step = 1)
with sol.Column(gap = '20px', margin = 0):
sol.InputFloat('Longitud', value = value11)
sol.SliderInt('Minutos', value = value14, min = 0, max = 60, step = 1)
Map.element(
center = ((value10.value, value11.value)),
zoom = 18,
draw_control = False,
measure_control = False,
fullscreen_control = False,
attribution_control = True,
height = '200px',
)
sol.lab.InputDate(value12)
with sol.Columns([1, 1, 1]):
with sol.Column(gap = '20px', margin = 0):
sol.InputFloat('Foco Y', value = value1)
sol.InputFloat('Foco Z', value = value2)
with sol.Column(gap = '20px', margin = 0):
sol.InputFloat('Diámetro de la circunferencia', value = value3)
sol.InputFloat('Altura de la circunferencia', value = value4)
with sol.Column(gap = '20px', margin = 0):
sol.InputFloat('Espesor del espejo', value = value7)
sol.InputFloat('Espesor del marco', value = value8)
sol.SliderInt('Ángulo de rotación', value = value9, min = -90, max = 90, step = 1)
with sol.Card(title = 'Esquema de perfil', subtitle = 'A ' + str(value9.value) + ' grados', elevation = 5):
with sol.Column(align = 'center'):
fig1, axe1 = plt.subplots()
c1 = (8 * value1.value ** 2 * (value4.value - value2.value) + 2 * value3.value ** 2 * (value4.value + value2.value) + (4 * value1.value ** 2 - value3.value ** 2) * np.sqrt(4 * (value4.value - value2.value) ** 2 + value3.value ** 2)) / (4 * value3.value ** 2)
a1 = ((c1 - value2.value) + np.sqrt((value2.value - c1) ** 2 + value1.value ** 2)) / (2 * value1.value ** 2)
b1 = ((value2.value - c1) - np.sqrt((value2.value - c1) ** 2 + value1.value ** 2)) / value1.value
s1 = value1.value - value3.value / 2
s2 = value1.value + value3.value / 2
y1 = np.linspace(s1, s2, 50)
z1 = a1 * y1 ** 2 + b1 * y1 + c1
y1, z1 = rotation(value1.value, value2.value, y1, z1, value9.value)
axe1.plot(y1, z1, '--k', alpha = 0.35)
verti_y = - b1 / (2 * a1)
verti_z = - (b1 ** 2 - 4 * a1 * c1) / (4 * a1)
circl_1 = np.linspace(np.pi, 2 * np.pi, 50)
y2 = (value2.value - verti_z) * np.cos(circl_1) + value1.value
z2 = (value2.value - verti_z) * np.sin(circl_1) + value2.value
axe1.plot(y2, z2, '--k', alpha = 0.35)
m1 = 2 * a1 * s1 + b1
t1 = (m1) ** 2 + 1
t2 = (4 * a1 * s1 + 2 * b1) * (c1 - value4.value) - 2 * s1 * (2 * a1 ** 2 * s1 ** 2 + a1 * b1 * s1 + 1)
t3 = s1 ** 2 * (a1 ** 2 * s1 ** 2 + 1) + (value4.value - c1) * (2 * a1 * s1 ** 2 + value4.value - c1) - (value6.value / 2) ** 2
p1y = (- t2 + np.sqrt(t2 ** 2 - 4 * t1 * t3)) / (2 * t1)
p1z = (m1) * p1y + (c1 - a1 * s1 ** 2)
p2y = (- t2 - np.sqrt(t2 ** 2 - 4 * t1 * t3)) / (2 * t1)
p2z = (m1) * p2y + (c1 - a1 * s1 ** 2)
p3y = p2y - abs(m1 * value7.value) / np.sqrt(m1 ** 2 + 1)
p3z = p2z - value7.value / np.sqrt(m1 ** 2 + 1)
p4y = p1y - abs(m1 * value7.value) / np.sqrt(m1 ** 2 + 1)
p4z = p1z - value7.value / np.sqrt(m1 ** 2 + 1)
l1 = (abs(m1) * value7.value + value6.value) / np.sqrt(m1 ** 2 + 1)
radio_o = value3.value / 2
radio_i = abs(radio_o - value6.value / (2 * np.sqrt(m1 ** 2 + 1)))
radio_e = np.sqrt((radio_i + l1) ** 2 + (radio_i * np.tan((180 / value5.value) * (np.pi / 180))) ** 2)
print(radio_e - radio_o)
punye_i = np.array([p1y, p2y, p3y, p4y])
punze_i = np.array([p1z, p2z, p3z, p4z])
punye_i, punze_i = rotation(value1.value, value2.value, punye_i, punze_i, value9.value)
axe1.fill(punye_i, punze_i, color = 'blue')
punym_i = np.array([p2y + value8.value, p2y + value8.value, value1.value - radio_e - value8.value, value1.value - radio_e - value8.value, p1y + value8.value, p1y + value8.value, p1y, p1y, value1.value - radio_e, value1.value - radio_e])
punzm_i = np.array([p2z, p2z + value8.value, p2z + value8.value, p4z - value8.value, p4z - value8.value, p1z + value8.value, p1z + value8.value, p4z, p4z, p2z])
punym_i, punzm_i = rotation(value1.value, value2.value, punym_i, punzm_i, value9.value)
axe1.fill(punym_i, punzm_i, color = 'cyan')
punye_d = mirror(value1.value, np.array([p1y, p2y, p3y, p4y]))
punye_d, punze_i = rotation(value1.value, value2.value, punye_d, np.array([p1z, p2z, p3z, p4z]), value9.value)
axe1.fill(punye_d, punze_i, color = 'blue')
punym_d = mirror(value1.value, np.array([p2y + value8.value, p2y + value8.value, value1.value - radio_e - value8.value, value1.value - radio_e - value8.value, p1y + value8.value, p1y + value8.value, p1y, p1y, value1.value - radio_e, value1.value - radio_e]))
punym_d, punzm_i = rotation(value1.value, value2.value, punym_d, np.array([p2z, p2z + value8.value, p2z + value8.value, p4z - value8.value, p4z - value8.value, p1z + value8.value, p1z + value8.value, p4z, p4z, p2z]), value9.value)
axe1.fill(punym_d, punzm_i, color = 'cyan')
m2 = 2 * np.arctan(m1) + np.pi / 2
d1 = value6.value * np.sin(np.arctan(m1) + np.pi - m2) / np.cos(m2)
d2 = np.sqrt((value1.value - p1y) ** 2 + (value2.value - d1 / 2 - p1z) ** 2)
d3 = np.sqrt((value1.value - p2y) ** 2 + (value2.value + d1 / 2 - p2z) ** 2)
y3 = np.array([p1y, p1y + d2 * np.cos(m2), p2y + d3 * np.cos(m2), p2y])
z3 = np.array([p1z, p1z + d2 * np.sin(m2), p2z + d3 * np.sin(m2), p2z])
y8, z8 = rotation(value1.value, value2.value, y3, z3, value9.value)
axe1.fill(y8, z8, color = 'yellow', alpha = 0.35)
y9, z9 = rotation(value1.value, value2.value, mirror(value1.value, y3), z3, value9.value)
axe1.fill(y9, z9, color = 'yellow', alpha = 0.35)
axe1.axis('equal')
axe1.grid(alpha = 0.35)
axe1.set_xlabel('Y')
axe1.set_ylabel('Z')
sol.FigureMatplotlib(fig1)
with sol.Columns([1, 1]):
with sol.Column(align = 'stretch'):
sol.SliderInt('Número de espejos', value = value5, min = 3, max = 100, step = 1, thumb_label = False)
with sol.Card(title = 'Esquema de planta', subtitle = str(value5.value) + ' espejos con una inclinación respecto a la horizontal de ' + str(round(abs(np.arctan(m1) * (180 / np.pi)), 2)) + ' grados', elevation = 5):
fig2, axe2 = plt.subplots()
y4 = radio_i * np.cos(circl_1) + value1.value
x4 = radio_i * np.sin(circl_1)
y5 = radio_o * np.cos(circl_1) + value1.value
x5 = radio_o * np.sin(circl_1)
y6 = radio_e * np.cos(circl_1) + value1.value
x6 = radio_e * np.sin(circl_1)
verty_e = value1.value + radio_i * abs(np.tan((180 / value5.value) * (np.pi / 180)))
y7 = np.array([verty_e, verty_e, mirror(value1.value, verty_e), mirror(value1.value, verty_e)])
x7 = np.array([radio_i, radio_i + l1, radio_i + l1, radio_i])
y10 = np.array([verty_e, mirror(value1.value, verty_e), mirror(value1.value, verty_e), verty_e])
x10 = np.array([radio_i, radio_i, 0, 0])
axe2.plot(y4, x4, linestyle = 'dashed', color = 'black')
axe2.plot(y5, x5, linestyle = 'dashed', color = 'black')
axe2.plot(y6, x6, linestyle = 'dashed', color = 'black')
axe2.fill(y7, x7, color = 'blue', edgecolor = 'cyan')
axe2.fill(y10, x10, color = 'yellow', alpha = 0.5)
for i in range(1, int(value5.value)):
xi, yi = rotation(value1.value, 0, y7, x7, (360 / value5.value) * i)
axe2.fill(xi, yi, color = 'blue', edgecolor = 'cyan')
xi, yi = rotation(value1.value, 0, y10, x10, (360 / value5.value) * i)
axe2.fill(xi, yi, color = 'yellow', alpha = 0.1)
axe2.axis('equal')
axe2.grid(alpha = 0.35)
axe2.set_xlabel('Y')
axe2.set_ylabel('X')
sol.FigureMatplotlib(fig2)
with sol.Column(align = 'stretch'):
sol.SliderFloat('Largo del espejo', value = value6, min = 0.05, max = 0.5, step = 0.005, thumb_label = False)
with sol.Card(title = 'Esquema de detalle', subtitle = 'Espejos con altura de ' + str(value6.value) + ' m y ancho de ' + str(round(2 * radio_i * abs(np.tan((180 / value5.value) * (np.pi / 180))), 4)) + ' m', elevation = 5):
fig3, axe3 = plt.subplots()
axe3.fill(np.array([p1y, p2y, p3y, p4y]), np.array([p1z, p2z, p3z, p4z]), color = 'blue')
axe3.fill(np.array([p2y + value8.value, p2y + value8.value, value1.value - radio_e - value8.value, value1.value - radio_e - value8.value, p1y + value8.value, p1y + value8.value, p1y, p1y, value1.value - radio_e, value1.value - radio_e]), np.array([p2z, p2z + value8.value, p2z + value8.value, p4z - value8.value, p4z - value8.value, p1z + value8.value, p1z + value8.value, p4z, p4z, p2z]), color = 'cyan')
axe3.scatter([value1.value - radio_i, value1.value - radio_o, value1.value - radio_e], [value4.value, value4.value, value4.value], 50, color = 'black')
axe3.axis('equal')
axe3.grid(alpha = 0.35)
axe3.set_xlabel('Y')
axe3.set_ylabel('Z')
sol.FigureMatplotlib(fig3)
with sol.Columns([1, 1]):
with sol.Column(align = 'stretch'):
numer_e = np.arange(3, 101, 1)
varia_l = np.arange(0.05, 0.505, 0.005)
areat_r = []
for i in numer_e:
ancho_e = np.round(2 * radio_i * abs(np.tan((180 / i) * (np.pi / 180))), decimals = 4)
areaf_l = np.round(ancho_e * varia_l * i, decimals = 4)
areaf_l = areaf_l.tolist()
areaf_l.insert(0, ancho_e)
areaf_l.insert(0, i)
areat_r.append(areaf_l)
varia_l = list(map(str, np.round(varia_l, 3).tolist()))
varia_l.insert(0, 'A / L')
varia_l.insert(0, 'E')
areat_r = pd.DataFrame(areat_r, columns = varia_l)
sol.DataFrame(areat_r.iloc[17:48, :33], items_per_page = 19, scrollable = True)
with sol.Column(align = 'stretch'):
x11 = []
y11 = []
z11 = []
for i in range(len(numer_e)):
for j in range(len(varia_l) - 2):
x11.append(areat_r.iat[i, 1])
y11.append(varia_l[j + 2])
z11.append(areat_r.iloc[i, j + 2])
xyz11 = pd.DataFrame({'Ancho': x11, 'Largo': y11, 'Area total': z11})
fig = px.scatter_3d(xyz11, x = 'Ancho', y = 'Largo', z = 'Area total', color = 'Area total', opacity = 0.9)
fig.update_traces(marker = dict(size = 2))
fig.update_layout(
margin = dict(l = 0, r = 0, t = 0, b = 0),
scene = dict(
xaxis_title = 'Ancho del espejo',
yaxis_title = 'Largo del espejo',
zaxis_title = 'Area total de reflexión'
),
# title = 'Area total de reflexión en función de las dimensiones de los espejos'
)
fig.show()
plt.close('all')