Волны в антеннах
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
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>
|
|
|