Волны в антеннах https://vk.com/pobeditelvp
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

260 lines
9.2 KiB

<!-- Copyright 2023 by Alexei Bezborodov <AlexeiBv+mirocod_wave_reflection@narod.ru> -->
<!-- public domain -->
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Переотражение волн</title>
<!--
Загрузка скриптов из интернета
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/brython@3.8.9/brython.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/brython@3.8.9/brython_stdlib.js"></script>
-->
<!--
Загрузка скриптов из локальной папки (рядом с файлом html)
-->
<script type="text/javascript" src="brython.min.js"></script>
<script type="text/javascript" src="brython_stdlib.js"></script>
</head>
<body onload="brython()">
<details open>
<summary>Расчётные данные</summary>
<div>
<p>
<input type="range" id="max_step_range" for="max_step" name="volume" min="10" max="1000" value="100"
oninput='document.getElementById("max_step").value = document.getElementById("max_step_range").value; recalculate();'>
<input id = "max_step" type="number" value="100" step="1"
oninput='recalculate();'/>
<label for="max_step" alt="Количество расчётных точек на всю длину среды">Точность расчёта</label>
</p>
<p>
<input type="checkbox" id="right_refraction" checked
oninput='recalculate();'/>
<label for="right_refraction" alt="">Отражения и переотражения справа</label>
</p>
<p>
<input type="range" id="max_right_refraction_range" for="max_step" name="volume" min="0" max="100" value="3"
oninput='document.getElementById("max_right_refraction").value = document.getElementById("max_right_refraction_range").value; recalculate();'>
<input id = "max_right_refraction" type="number" value="3" step="1"
oninput='recalculate();'/>
<label for="max_right_refraction" alt="">Количество переотражений справа</label>
</p>
<p>
<input type="checkbox" id="left_refraction" checked
oninput='recalculate();'/>
<label for="left_refraction" alt="">Отражения и переотражения слева</label>
</p>
<p>
<input type="range" id="max_left_refraction_range" for="max_step" name="volume" min="0" max="100" value="3"
oninput='document.getElementById("max_left_refraction").value = document.getElementById("max_left_refraction_range").value; recalculate();'>
<input id = "max_left_refraction" type="number" value="3" step="1"
oninput='recalculate();'/>
<label for="max_left_refraction" alt="">Количество переотражений слева</label>
</p>
<p>
<input type="range" id="length_range" for="omega" name="volume" min="0" max="200" value="50"
oninput='document.getElementById("length").value = document.getElementById("length_range").value / 100; recalculate();'>
<input id = "length" type="number" value="0.5" step=".01"
oninput='recalculate();'/>
<label for="length" alt="">Длина среды (в длинах волн)</label>
</p>
<p>
<input type="checkbox" id="invert_phase" checked
oninput='recalculate();'/>
<label for="invert_phase" alt="">Инвертирование волны при отражении</label>
</p>
<p>
<input type="range" id="k_refraction_range" for="omega" name="volume" min="0" max="100" value="60"
oninput='document.getElementById("k_refraction").value = document.getElementById("k_refraction_range").value / 100; recalculate();'>
<input id = "k_refraction" type="number" value="0.6" step=".01"
oninput='recalculate();'/>
<label for="k_refraction" alt="">Коэффициент отражения</label>
</p>
<p>
<input type="range" id="omega_range" for="omega" name="volume" min="-1000" max="1000" value="0"
oninput='document.getElementById("omega").value = document.getElementById("omega_range").value / 100; recalculate();'>
<input id = "omega" type="number" value="0" step=".01"
oninput='recalculate();'/>
<label for="omega" alt="">Начальная фаза главной функции</label>
</p>
<button id="recalculate">Пересчитать</button>
</div>
</details>
<h1 class="text-center">Графики волн</h1>
<canvas id="draw-board" width="1024" height="500"></canvas>
<script type="text/python">
from browser import document, html, window
import random, math
canvas = document["draw-board"]
ctx = canvas.getContext("2d")
x_border = 10
y_border = 10
# Чёрный экран
def DrawBlackScreen():
ctx.fillStyle = "black"
ctx.fillRect(0, 0, canvas.width, canvas.height)
def DrawLine(x1, y1, x2, y2, lineWidth, style):
ctx.strokeStyle = style
ctx.lineWidth = lineWidth
ctx.beginPath()
ctx.moveTo(x1, y1)
ctx.lineTo(x2, y2)
ctx.stroke()
return
def DrawAxesScreen():
ctx.fillRect(0, 0, canvas.width, canvas.height)
x1 = x_border
x2 = canvas.width - x1
y1 = y_border
y2 = canvas.height - y1
ym = canvas.height/2
style = 'red'
lw = 2
DrawLine(x1, ym, x2, ym, lw, style)
DrawLine(x1, y1, x1, y2, lw, style)
DrawLine(x2, y1, x2, y2, lw, style)
def max_step_range(event):
#document["max_step"].value = document["max_step_range"].value
document["max_step"].value = 103
def base_func(x, omega):
return math.sin(x + omega)
def recalculate():
max_step = int(document["max_step"].value)
r = document["invert_phase"].checked
if r:
r = -1
else:
r = 1
k_refraction = float(document["k_refraction"].value)
omega = float(document["omega"].value)
right_refraction = document["right_refraction"].checked
max_right_refraction = int(document["max_right_refraction"].value)
left_refraction = document["left_refraction"].checked
max_left_refraction = int(document["max_left_refraction"].value)
length = float(document["length"].value)
DrawBlackScreen()
DrawAxesScreen()
right_refraction_last_values = [0.0] * max_right_refraction;
left_refraction_last_values = [0.0] * max_left_refraction;
result = 0.0
result_last_value = result
base_func_value = 0.0
base_func_last_value = result
pi = math.pi
x1 = x_border
x2 = canvas.width - x1
y1 = y_border
y2 = canvas.height - y1
ym = canvas.height/2
style = 'white'
style_right = '#FF0000'
style_left = '#00FF00'
style_result = '#00FFFF'
line_width_scale = 4.0
y_scale = 0.3
cur_x = 0
prev_x = cur_x
for i in range(max_step):
result = 0
x = i / max_step * 2.0 * pi * length + 0.0 * omega
cur_x = x1 + (x2 - x1) * i / max_step
omega1 = 1.0 * omega
base_func_value = base_func(x, omega1)
if i > 0:
base_y = ym - (ym - y1) * y_scale * base_func_value
base_y_last = ym - (ym - y1) * y_scale * base_func_last_value
DrawLine(prev_x, base_y_last, cur_x, base_y, 1.0 * line_width_scale, style)
base_func_last_value = base_func_value
result += base_func_value
for r_i in range(max_right_refraction * int(right_refraction) ):
cur_k = k_refraction ** (r_i + 1)
cur_r = r ** (r_i + 1)
cur_znak = (-1) ** r_i
func_value = cur_k * cur_r * base_func( ((r_i + 1) + (r_i + 1) % 2) * length * 2 * pi - cur_znak * x, omega1)
if i > 0:
base_y = ym - (ym - y1) * y_scale * func_value
base_y_last = ym - (ym - y1) * y_scale * right_refraction_last_values[r_i]
DrawLine(prev_x, base_y_last, cur_x, base_y, cur_k * line_width_scale, style_right)
right_refraction_last_values[r_i] = func_value
result += func_value
for r_i in range(max_left_refraction * int(left_refraction) ):
cur_k = k_refraction ** (r_i + 1)
cur_r = r ** (r_i + 1)
cur_znak = (-1) ** r_i
func_value = cur_k * cur_r * base_func( -((r_i + 1) - (r_i + 1) % 2) * length * 2 * pi - cur_znak * x, omega1)
if i > 0:
base_y = ym - (ym - y1) * y_scale * func_value
base_y_last = ym - (ym - y1) * y_scale * left_refraction_last_values[r_i]
DrawLine(prev_x, base_y_last, cur_x, base_y, cur_k * line_width_scale, style_left)
left_refraction_last_values[r_i] = func_value
result += func_value
if i > 0:
base_y = ym - (ym - y1) * y_scale * result
base_y_last = ym - (ym - y1) * y_scale * result_last_value
DrawLine(prev_x, base_y_last, cur_x, base_y, 2.0 * line_width_scale, style_result)
result_last_value = result
prev_x = cur_x
def recalculate_event(event):
recalculate()
window.recalculate = recalculate
document["recalculate"].bind("click", recalculate_event)
</script>
</body>
</html>