Добавил:
serega_ovc
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:lab3 / lab3
.pyfrom functools import reduce
from math import *
import matplotlib.pyplot as plt
import numpy as np
# рассчёт растояния между точками
def calc_r(x, y, point_x, point_y):
return sqrt((point_x - x) ** 2 + (point_y - y) ** 2)
# рассчёт растояния между точками
def calc_alpha(x, y, point_x, point_y):
dx = point_x - x
dy = point_y - y
alpha = 0
if dy:
alpha = atan(dx / dy)
if dx < 0 and dy == 0:
alpha += pi
if dy < 0:
alpha += pi
if alpha > pi:
alpha -= 2 * pi
return alpha
# проверочная функция выхода за пределы поля электродов
def not_touch(x, y):
if 0.4 * x + 6.2 > y and 0 < x < 14:
return True
else:
return False
# расчёт напряжённости поля в точке
def calc_e(r, alpha, sign):
if r == 0:
return 0, 0
return sign * sin(alpha) / r ** 2, sign * cos(alpha) / r ** 2
# расчёт линий
def calc_new_points(pos_line, s_p, s_n):
line_points = [[] for el in pos_line]
# цикл для каждого отрезка с зарядом
for i, point in enumerate(pos_line):
x = point[0]
y = point[1] + 0.1
res_x = [x]
res_y = [y]
# считаем пока не выйдем за пределы
while not_touch(x, y):
Ep = []
En = []
# расчёт плдя элементарных зарядов
for dp, dn in list(zip(s_p, s_n)):
r_p = calc_r(dp[0], dp[1], x, y)
r_n = calc_r(dn[0], dn[1], x, y)
alpha_p = calc_alpha(dp[0], dp[1], x, y)
alpha_n = calc_alpha(dn[0], dn[1], x, y)
Ep += [calc_e(r_p, alpha_p, 1)]
En += [calc_e(r_n, alpha_n, -1)]
# суммирование элементарных полей
Ep = reduce(lambda el1, el2: (el1[0] + el2[0], el1[1] + el2[1]), Ep)
En = reduce(lambda el1, el2: (el1[0] + el2[0], el1[1] + el2[1]), En)
# новые координаты линии
x += (Ep[0] + En[0]) * 0.0001
y += (Ep[1] + En[1]) * 0.0001 # 0.00005
res_x += [x]
res_y += [y]
print(f'progress {(i + 1) * 100 / len(pos_line)}')
line_points[i] = (res_x[:len(res_x) - 1], res_y[:len(res_y) - 1])
return line_points
# =========================================================================
N = 100
lines_count = 20
# линия с зарядом -Q
Qn_coord = [(2, 7), (12, 11)]
# половина окружности с зарядом +Q
Qз_r = 5
Qp_center = (7, 6)
Qp_angles = np.linspace(pi, 2 * pi, N)
dx = (Qn_coord[1][0] - Qn_coord[0][0]) / N
dy = (Qn_coord[1][1] - Qn_coord[0][1]) / N
sQp = []
sQn = []
# Разбиение электрода на элементарные заряды
for i in range(N):
sQn += [(Qn_coord[0][0] + dx * i, Qn_coord[0][1] + dy * i)]
for angle in Qp_angles:
sQp += [(Qp_center[0] + Qз_r * cos(angle), Qp_center[1] + Qз_r * sin(angle))]
# выберем сколько элментарных отрезков приходиться на линию
dq_to_line = np.array_split(sQp, lines_count)
# выберем средний отрезок
line_pos = [x[len(x) // 2] for x in dq_to_line]
# вызовем функцию расчёта линий
lines_points = calc_new_points(line_pos, sQp, sQn)
# отображение линий
for line in lines_points:
plt.plot(line[0], line[1], '--', color="gray")
dx = line[0][len(line[0]) // 2 + 1] - line[0][len(line[0]) // 2]
dy = line[1][len(line[1]) // 2 + 1] - line[1][len(line[1]) // 2]
plt.arrow(line[0][len(line[0]) // 2], line[1][len(line[1]) // 2], dx * 10, dy * 10, head_width=0.2, head_length=0.3,
color="gray")
# данные для окружности
circle_plot_x = [i[0] for i in sQp]
circle_plot_y = [i[1] for i in sQp]
# печать линий зарядов
plt.plot(circle_plot_x, circle_plot_y, linewidth=2, label='+Q', color='red')
plt.plot([Qn_coord[0][0], Qn_coord[1][0]], [Qn_coord[0][1], Qn_coord[1][1]], linewidth=2, label='-Q', color='black')
plt.savefig("graf.jpg")
plt.show()