Алексей Безбородов
2 years ago
commit
0267c8ae70
5 changed files with 307 additions and 0 deletions
@ -0,0 +1,24 @@
|
||||
This is free and unencumbered software released into the public domain. |
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or |
||||
distribute this software, either in source code form or as a compiled |
||||
binary, for any purpose, commercial or non-commercial, and by any |
||||
means. |
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors |
||||
of this software dedicate any and all copyright interest in the |
||||
software to the public domain. We make this dedication for the benefit |
||||
of the public at large and to the detriment of our heirs and |
||||
successors. We intend this dedication to be an overt act of |
||||
relinquishment in perpetuity of all present and future rights to this |
||||
software under copyright law. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
||||
OTHER DEALINGS IN THE SOFTWARE. |
||||
|
||||
For more information, please refer to <https://unlicense.org> |
@ -0,0 +1,8 @@
|
||||
# Программа распределения участников форума по столам |
||||
|
||||
<img src="https://www.romanovles.ru/upload/iblock/22a/22a396f30e4afd5d76ff53f32834289b.jpg"/> |
||||
|
||||
* Каждому участнику на бейджике пишется номер, у каждого стола есть буква. |
||||
* После доклада оглашается распределение по столам: какой номер, за какой стол садится. |
||||
* Каждый раз по разному. |
||||
* Программа старается сделать так, чтобы каждый посидел за столом с максимально возможным числом различных участников или чтобы все познакомились со всеми. |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,264 @@
|
||||
<!-- Copyright 2023 by Alexei Bezborodov <AlexeiBv+mirocod_wave_refraction@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 + omega |
||||
|
||||
cur_x = x1 + (x2 - x1) * i / max_step |
||||
|
||||
omega1 = 0.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) |
||||
|
||||
#document["omega"].bind("onchange", recalculate) |
||||
|
||||
|
||||
|
||||
</script> |
||||
|
||||
</body> |
||||
|
||||
</html> |
Loading…
Reference in new issue