Форум программистов, компьютерный форум, киберфорум
Python для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.67/21: Рейтинг темы: голосов - 21, средняя оценка - 4.67
 Аватар для Михалыч
1011 / 355 / 59
Регистрация: 28.02.2013
Сообщений: 939

Взаимное влияние точек

10.06.2021, 16:15. Показов 5164. Ответов 28

Студворк — интернет-сервис помощи студентам
Добрый день! Не знаю как назвать тему, поэтому пусть будет так Давно хотел сделать одну задачу (сам формулирую, поэтому может немного коряво быть):

1. На плоскости расположены 7 точек с координатами [x,y] в пикселях
Python
1
2
3
4
5
6
7
point_1 = [150,150]
point_2 = [90,90]
point_3 = [250,330]
point_4 = [400,300]
point_5 = [100,250]
point_6 = [400,100]
point_7 = [250,400]
2. Каждая точка оказывает условное воздействие вокруг себя с определенной силой, т.е. как взрыв, чем дальше от точки взрыва тем слабее воздействие. В качестве упрощения примем что каждая точка оказывает одинаковое воздействие, на одинаковом расстоянии
Python
1
2
3
4
5
6
7
8
9
10
# сила воздействия от 0,99 до 0
power = [i/100 for i in range(100)]
power.sort(reverse=True) # сила нужна по убыванию, чем дальше от точки воздействия тем меньше сила
probit_point_1 = [power,[i for i in range(100)]] # [[сила воздействия],[на расстоянии от точки]]
probit_point_2 = [power,[i for i in range(100)]]
probit_point_3 = [power,[i for i in range(100)]]
probit_point_4 = [power,[i for i in range(100)]]
probit_point_5 = [power,[i for i in range(100)]]
probit_point_6 = [power,[i for i in range(100)]]
probit_point_7 = [power,[i for i in range(100)]]
3. Воздействие от всех точек одновременное и суммирующееся. Т.е. если на точку [x,y] воздействуют три источника, то в этой точке сила воздействия будет равна сумме сил этих источников, при условии что воздействие источника достает до этой точки.

4. В качестве исследуемой плоскости возьмем плоскость размером 500 на 500 пикселей.

Решение:
1. Что бы потом нагляднее был результат, представим его в градации цветов
Python
1
2
3
4
5
6
7
# цвета для отображения результата
red = (255, 0, 0, 70)
yellow = (255, 255, 0, 70)
light_blue = (0, 255, 255, 70)
green = (0, 255, 0, 70)
blue = (0, 0, 255, 70)
purple = (255, 0, 255, 70)
2. Заранее сделал чистую картинку 500 на 500 пикселей и открыл ее через PIL
Python
1
2
3
4
5
6
# возьмем чистую картинку
im = Image.open('image.jpg')
# измерим размер
width, height = im.size
# загрузим в память
px = im.load()
3. Определим точки их воздействие
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Сделаем несколько точек и покажем их воздействие
# точки с координатами
point_1 = [150,150]
point_2 = [90,90]
point_3 = [250,330]
point_4 = [400,300]
point_5 = [100,250]
point_6 = [400,100]
point_7 = [250,400]
# сила воздействия от 0,99 до 0
power = [i/100 for i in range(100)]
power.sort(reverse=True) # сила нужна по убыванию, чем дальше от точки воздействия тем меньше сила
probit_point_1 = [power,[i for i in range(100)]] # [[сила воздействия],[на расстоянии от точки]]
probit_point_2 = [power,[i for i in range(100)]]
probit_point_3 = [power,[i for i in range(100)]]
probit_point_4 = [power,[i for i in range(100)]]
probit_point_5 = [power,[i for i in range(100)]]
probit_point_6 = [power,[i for i in range(100)]]
probit_point_7 = [power,[i for i in range(100)]]
# список всех точек (их координат) и список их влияния (силы воздействия)
coord_all = [point_1, point_2, point_3, point_4, point_5, point_6, point_7]
probit_all = [probit_point_1, probit_point_2, probit_point_3, probit_point_4,
                  probit_point_5, probit_point_6, probit_point_7]
4. Сделаем матрицу и заполним ее 0
Python
1
2
# сделаем нулевую матрицу по размерам картинки
zeors_array = np.zeros((width, height))
5. Поскольку воздействие источников суммируется, то создадим функцию которая по значению элемента матрицы определит для пикселя свой цвет
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# создадим функцию которая по суммарному воздейсатвию определяет цвет пикселя
def color_px(x,y):
    if zeors_array[x, y] >= 0.9:
        px[x, y] = red
    elif 0.9 > zeors_array[x, y] >= 0.7:
        px[x, y] = yellow
    elif 0.7 > zeors_array[x, y] >= 0.5:
        px[x, y] = light_blue
    elif 0.5 > zeors_array[x, y] >= 0.3:
        px[x, y] = green
    elif 0.3 > zeors_array[x, y] >= 0.2:
        px[x, y] = blue
    elif 0.2 > zeors_array[x, y] >= 0.1:
        px[x, y] = purple
6. Пробежимся по всем элементам матрицы и запишем воздействие, если элемент != 0 то просуммируем.

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# создадим функцию которая принимает высоту, ширину картинки, список координат,
# координаты точек и силу их воздействия вокруг себя
def calc_el_zeors_array_for_point(width, height, coord, probit):
    # для каждой точки картинки определим силу воздействия заданных точек
    for x in range(width):
        for y in range(height):
            # определим расстояние от перебираемой точки картинки до
            # заданной точки coord
            dist = round(Point(x, y).distance(Point(coord[0], coord[1])))
            # крайний случай, когда перебираемая точка и заданная точка coord равны
            # тогда воздействие максимально
            if dist == 0:
                zeors_array[x, y] = zeors_array[x, y] + probit[0][0]
                color_px(x,y)
            # если расстояние есть в дистанции силы воздействия
            elif dist in probit[1]:
                # найдем индекс
                find_index = probit[1].index(dist)
                # запишем силу воздействия в матрицу (т.е. если в этой точке воздействие от другой точки уже
                # было, то воздействия суммируются)
                zeors_array[x, y] = zeors_array[x, y] + probit[0][find_index]
                color_px(x, y)
7. Переберем все точки

Python
1
2
3
4
5
6
# переберем все точки
for elem in coord_all:
    # определим индекс
    find_index = coord_all.index(elem)
    # вызовем функцию суммарного воздействия
    calc_el_zeors_array_for_point(width, height, coord_all[find_index], probit_all[find_index])
8. Выведем результат как картинку
# выведем результат как картинку
im.save('res.png')

Файл с результирующей картинкой и архивом программы прикрепил.
Миниатюры
Взаимное влияние точек  
Вложения
Тип файла: rar tst_shapely.rar (15.2 Кб, 16 просмотров)
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
10.06.2021, 16:15
Ответы с готовыми решениями:

Непонятное взаимное влияние интеловских сетевух
Добрый день. Не могу разобраться в странном поведении интеловских сетевых карт (on-board). Дано: 1. Домашний сервер (Debian 11) с...

PCI Express разный, взаимное влияние
Вопрос заключается в следующем. Влияют ли подключённые устройства PCI Express взаимно? Например имеем плату Gigabyte B550M Aorus Elit и...

Взаимное влияние двух таймеров друг на друга
Добрый день, участок кода, состоящий из работы нескольких таймеров почему-то начинает работать не совсем корректно при их одновременной...

28
5531 / 2884 / 573
Регистрация: 07.11.2019
Сообщений: 4,802
25.03.2023, 11:55
Студворк — интернет-сервис помощи студентам
Михалыч, вариант с линией, не очень красиво, но идея, думаю, понятна.
Кликните здесь для просмотра всего текста
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import numpy as np
from scipy.signal import fftconvolve
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from PIL import Image, ImageDraw
lines=((10, 20), (50,10)) 
points=np.array([[150,150],[90,90], [250,330], [400,300], [100,250],[400,100],[250,400]])
width, height = 500,500
im = Image.new('1', (width, height), (0))
draw = ImageDraw.Draw(im)
draw.line(xy=lines, fill='white')  #draw line
im=np.asarray(im, dtype=np.uint8)
#im=np.zeros((width, height))
im[points[:,1], points[:,0]]=1.0 # set points
x=np.arange(0, 201)
y=np.arange(0, 201)
X,Y=np.meshgrid(x,y)
distance=((X-100)**2+(Y-100)**2)**.5
power=1-distance/100
power[power<0]=0 # cut off power function
my_cmap = ListedColormap(["#ffffff", "#ff00ff", '#0000ff', '#00ff00', "#00ff00",
                       '#00ffff', '#00ffff', '#ffff00', '#ffff00', '#ff0000'])
result=fftconvolve(im, power, mode='same') # convolutions
plt.imshow(result, cmap=my_cmap, aspect='equal', vmin=0, vmax=1)
1
 Аватар для Михалыч
1011 / 355 / 59
Регистрация: 28.02.2013
Сообщений: 939
31.03.2023, 22:39  [ТС]
Цитата Сообщение от u235 Посмотреть сообщение
но идея, думаю, понятна.
u235, идея классная) Я её по разному пробовал приспособить, но у меня что то не получилось
Получается что линия разбивается на точки и каждая точка линии имеет свое воздействие (т.е. на линии они начинают суммироваться, а это совсем то чего хочется), а после линии надо добавить еще многоугольники и что бы внутри многоугольника было максимальное воздействие и что бы от него было воздействие как от линии или точки... В общем я пока ваш вариант оставил на изучение (потом я к нему вернусь ), для практики вернулся к первоначальному варианту, немного его усовершенствовав.
1. Добавил PySide (QRunnable, QThreadPool) что бы каждый объект (точка, линия, многоугольник) считался в отдельном потоке
2. Убрал "решение в лоб", а именно перебор всех точек через цикл.
Заменил на:
а) разбиваем область картинки на квадраты по 50 пикселей
б) определяем расстояние до объекта
в) если расстояние меньше силы воздействия, то запоминаем его (если наоборот, то смысла его подробно обсчитывать нет)
г) квадраты по 50 пикселей разбиваем на более мелкие и повторяем с п."б"
...
Таким образом как бы сгущая расчетную сетку вокруг объекта и только потом считаем воздействие вокруг.
В общем получается красивая картинка с точками, линией и многоугольником всего за 1-1,5 минуты
0
 Аватар для Михалыч
1011 / 355 / 59
Регистрация: 28.02.2013
Сообщений: 939
31.03.2023, 22:41  [ТС]
Вот такая картинка)
Миниатюры
Взаимное влияние точек  
0
5531 / 2884 / 573
Регистрация: 07.11.2019
Сообщений: 4,802
02.04.2023, 22:03
Цитата Сообщение от Михалыч Посмотреть сообщение
т.е. на линии они начинают суммироваться, а это совсем то чего хочется
А чего хочется? разве не так должно быть? Возможно, что и точки и линии и полигоны должны иметь свои значения мощности (веса)? Это просто, вобщем. Точки и линии на im рисуются не белым (255), а оттенками серого, пропорционально мощности.

Добавлено через 2 минуты
Цитата Сообщение от Михалыч Посмотреть сообщение
Вот такая картинка
Какие задавались координаты линии, точек и прямоугольника?
Картинка очень похожа на морфологические преобразования с круглыми структурными элементами разного радиуса.
0
 Аватар для Михалыч
1011 / 355 / 59
Регистрация: 28.02.2013
Сообщений: 939
03.04.2023, 18:21  [ТС]
Цитата Сообщение от u235 Посмотреть сообщение
Возможно, что и точки и линии и полигоны должны иметь свои значения мощности (веса)?
Да, именно так) У точки своя мощность излучения, у линии своя, у полигона своя (причем внутри полигона она принимает максимальное значение для этого полигона).
Всё тоже самое как в моем первоначальном варианте для точек, только добавляются еще линии и полигоны.
И замеряется расстояние (для оценки мощности) до точки, до линии, до полигона.

Схематично выглядит так:
Есть объекты: точка А, отрезок (он может быть ломанной) СD, и полигон (тут квадрат для упрощения).
И дальше я что бы построить картинку выше перебираю множество точек P, замеряя при этом расстояние до вышеуказанных объектов (L1, L2, L3). Получив расстояние я смотрю какое воздействие (мощность) оказывает объект на эту точку. Если точка поиска попадает на объект/лежит внутри него то воздействие (мощность принимается максимальным).

Цитата Сообщение от u235 Посмотреть сообщение
Это просто, в общем.
Для меня это next level когда циклы перерасту


Цитата Сообщение от u235 Посмотреть сообщение
Какие задавались координаты линии, точек и прямоугольника?
Можно произвольно) у меня пока такие (соответственно три точки, линия и полигон):
Python
1
2
# Координаты объектов
OBJECTS = [(500, 100), (400, 200), (250, 500), (100, 150, 300, 300), (500, 500, 500, 400, 400, 400, 400, 500)]
Значение мощности у каждого разное бывает, но поставил всем 100.
Миниатюры
Взаимное влияние точек  
0
 Аватар для Михалыч
1011 / 355 / 59
Регистрация: 28.02.2013
Сообщений: 939
03.04.2023, 18:32  [ТС]
Я силы воздействия так задавал:
Python
1
2
3
4
# сила воздействия от 0,99 до 0
power = [i/100 for i in range(100)]
power.sort(reverse=True) # сила нужна по убыванию, чем дальше от объекта воздействия тем меньше сила
probit = [power,[i for i in range(100)]] # [[сила воздействия],[на расстоянии от объекта]]
0
5531 / 2884 / 573
Регистрация: 07.11.2019
Сообщений: 4,802
03.04.2023, 21:21
Михалыч, еще вопрос: как связаны сила, от растояния до объектов:
Т.е. получили мы для точки P значения l1,l2,l3 в пикселях, как на рисунке, дальше как силу считаем?

Добавлено через 17 минут
Михалыч, т.е. на расстоянии 0 сила 1, а на расстоянии 100 сила становится равна 0? И уменьшение линейное? Если точка находится на расстоянии 70 пикселей от линии и 50 пикселей от точечного источника, то сила будет 0.3+0.5=0.8?
0
5531 / 2884 / 573
Регистрация: 07.11.2019
Сообщений: 4,802
03.04.2023, 22:31
Лучший ответ Сообщение было отмечено Михалыч как решение

Решение

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import cv2
import numpy as np
import matplotlib.pyplot as plt
OBJECTS = [(500, 100), (400, 200), (250, 500), (100, 150, 300, 300), (500, 500, 500, 400, 400, 400, 400, 500)]
w,h=640,640
res=np.zeros((w,h))
for item in OBJECTS:
    im=np.zeros((w,h), dtype=np.uint8)
    if len(item)==2:
        im[item]=255
    elif len(item)==4: 
        cv2.line(im,item[0:2],item[2:4],(255,),1)
    else:
        cv2.fillPoly(im,[np.array(item).reshape(-1,1,2)],(255,))
    im=~im
    dist=cv2.distanceTransform(im, distanceType=cv2.DIST_L2, maskSize=cv2.DIST_MASK_PRECISE)
    dist=(100-dist)/100
    dist=np.clip(dist, 0,1)
    res+=dist
plt.imshow(res, cmap='jet', vmin=0, vmax=1)
plt.gca().invert_yaxis()
plt.colorbar()
У меня картинка 4640х4640 считается за 1.7 сек.
Миниатюры
Взаимное влияние точек  
1
 Аватар для Михалыч
1011 / 355 / 59
Регистрация: 28.02.2013
Сообщений: 939
04.04.2023, 10:26  [ТС]
Цитата Сообщение от u235 Посмотреть сообщение
т.е. на расстоянии 0 сила 1, а на расстоянии 100 сила становится равна 0?
Да.
Цитата Сообщение от u235 Посмотреть сообщение
И уменьшение линейное? Если точка находится на расстоянии 70 пикселей от линии и 50 пикселей от точечного источника, то сила будет 0.3+0.5=0.8?
Да)

Цитата Сообщение от u235 Посмотреть сообщение
У меня картинка 4640х4640 считается за 1.7 сек.
Это шикарное решение
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
04.04.2023, 10:26

Взаимное влияние двух конкурирующих видов биологических популяций
Взаимное влияние двух конкурирующих видов биологических популяций на их количества X, Y, в n-ом году описывается такой системой уравнений: ...

Userform Взаимное влияние нескольких ToggleButton друг на друга
Здравствуйте. В своей форме я сделал несколько зависимых друг от друга кнопок ToggleButton, цель сделать так, чтобы при нажатии одной, из...

Взаимное расположение трех точек (x1,y1), (x2,y2), (x3,y3)
Даны три точки (x1,y1), (x2,y2), (x3,y3). Определить их взаимное расположение: а) все точки совпадают; б) все точки различны; в) две точки...

Определить взаимное расположение точек (x3,y3) и (x4,y4)
Определить взаимное расположение точек (x3,y3) и (x4,y4)относительно прямой, проходящей через точки (x1,y1) и (x2,y2).

Определить взаимное положение К точек в пространстве (c++)
Заданы К точек своими координатами в пространстве. Определить их взаимное положение: принадлежность одной и той же плоскости, расположение...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
29
Ответ Создать тему
Новые блоги и статьи
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
Модель по догадкам
anaschu 25.08.2026
Прошло две недели. Я уже рассказывал, как разговаривал с сотрудниками у сортировки и как понял, что главная ветка — не про приёмку, а про отбор. Но тогда я думал, что понял механику. На этой неделе я. . .
Запись в регистр сведений независимо от заполненности табличной части
Maks 25.08.2026
Реализация из решения ниже выполнена на нетиповом документе с несколькими табличными частями, разработанного в КА2. Задача: Обеспечить запись документа в регистр сведений независимо от. . .
Ноутбук Альфария
kumehtar 24.08.2026
Встретился тут в сети ноутбук Альфария, примарха Альфа-Легиона. Хотя возможно, это ноутбук Омегона, разумеется. Ну как вам?
Мастера простых решений
DevAlt 23.08.2026
В сишарп стэках winforms, да и wpf существует сложная система связывания источниках данных и элементов формы(текстовые поля и метки), опирается все это на технологию событий и мета. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru