Форум программистов, компьютерный форум, киберфорум
Python для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.86/29: Рейтинг темы: голосов - 29, средняя оценка - 4.86
1 / 1 / 0
Регистрация: 14.08.2012
Сообщений: 14

Задача отталкивания друг от друга хаотически движущихся прямоугольников

15.08.2012, 15:43. Показов 6292. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день, семпаи. Есть программа, код которой я приведу ниже, где с помощью одного класса описано создание заданного количества случайного размера и цвета прямоугольников, которые хаотически движутся и отталкиваются от границ окна. Нужно доработать программу так, чтобы прямоугольники отталкивались ещё и друг от друга.
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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#!/usr/bin/env python
#coding=utf-8
 
import pygame
import sys
import random
 
 
class Rect:
    
#Создание случайного прямоугольника
    def __init__(self, screenSize):
        self.screenSize=screenSize
        self.xSize=random.randint(25, screenSize[0]/6)
        self.ySize=random.randint(25, screenSize[1]/6)
        self.x = random.randint(0, screenSize[0]-self.xSize)
        self.y = random.randint(0, screenSize[1]-self.ySize)
        self.rectColor = (random.randint(0,255),random.randint(0,10),random.randint(0,10))
        self.xSpeed=random.randint(-100,100)
        self.ySpeed=random.randint(-100,100)
 
#функция проверки на попадание клика мыши по прямоугольнику
 
    def contain(self, xx, yy):
        if self.x <= xx <= self.x + self.xSize:
            if self.y<= yy <= self.y + self.ySize:
                return True
        return False
    
#Описание хаотического движения прямоугольников, с учетом отталкивания от границ окна
 
    def move(self, sec):
        self.x+=sec*self.xSpeed
        self.y+=sec*self.ySpeed
        
        if self.x + self.xSize > self.screenSize[0]:
            self.xSpeed=-self.xSpeed
            self.x=self.screenSize[0]-self.xSize
        if self.x<0:
           self.xSpeed=-self.xSpeed
           self.x=0
        if self.y + self.ySize > self.screenSize[1]:
           self.ySpeed=-self.ySpeed
           self.y=self.screenSize[1]-self.ySize
        if self.y<0:
           self.ySpeed=-self.ySpeed
           self.y=0
 
#Отрисовка созданного прямоугольника
    def draw(self,screen):
       pygame.draw.rect (screen, self.rectColor, pygame.Rect((self.x,self.y), (self.xSize,self.ySize) ))
       
 
pygame.init()
timer = pygame.time.Clock()
 
screenSize = (800,600)
screenColor = (255,255,255)
screen = pygame.display.set_mode (screenSize)
 
#создание массивва прмоуголников, с помощью переменной n регулируется количество
n=5
 
rectList=[]
for i in range(n):
    rect = Rect(screenSize)
    rectList.append(rect)
 
while 1:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if (event.type == pygame.KEYDOWN):
            if (event.key == pygame.K_ESCAPE):
                pygame.quit()
                sys.exit()
        if event.type == pygame.MOUSEBUTTONDOWN:    #Проверка на попадаие клика в прямоугольник из масива прямоугольников
            xx,yy = pygame.mouse.get_pos()
            for i in range(len(rectList)):
                if rectList[i].contain(xx,yy):
                    rectList[i]=Rect(screenSize)    #При попадании клика создать новый прямоугольник
 
 
    sec = timer.tick() / 1000.  
    for rect in rectList:
        rect.move(sec)
 
 
    screen.lock()
    pygame.draw.rect (screen, screenColor, pygame.Rect((0,0), screenSize))
    for rect in rectList:
        rect.draw(screen)
    screen.unlock()
    
    pygame.display.update()
Алгоритм я придумал следующий:
а) Проверяем на столкновение по горизонтали: В цикле проверяем на равенство координаты x каждого прямоугольника с координатой xSize всех других прямоугольников.
б) При обнаружении равенства проверяем на истинность следующие неравенства
y2 < y1 < ySize2
или
y2 < ySize1 < ySize2
Где y1 и y2 координаты соответствующих прямоугольников.

Если хоть одно из неравенств выполняется, учитывая условие 1, значит прямоугольники столкнулись и получают отрицательную скорость.

Это что касается горизонтального столкновения. Вертикальное столкновение проверяем в аналогичном цикле только с координатами по оси y.

Такой вот алгоритм, но я не могу написать его в синтаксисе Питона, я не знаю как из массива rectList извлекать координаты конкретных объектов класса Rect, чтобы их сравнивать.

Кроме того, мне кажется, должен быть алгоритм и попроще просто я его не вижу.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
15.08.2012, 15:43
Ответы с готовыми решениями:

Сила отталкивания двух магнитов друг от друга
Добрый день. Имеются два неодимовых дисковых магнита N35, направленные друг на друга южными полюсами. Размеры: диаметр 20 мм, толщина...

Отталкивание движущихся кнопок друг об друга
Здравствуйте. Я тут писал программу, где требуется сделать кнопки, которые бегают по форме и отталкиваются от друг друга и границ. От...

Нарисовать 5 прямоугольников и 5 треугольников, вписанных друг в друга
Нарисовать 5 прямоугольников и 5 треугольников, вписанных друг в друга.Модуль graph.

4
 Аватар для Buckstabue
179 / 127 / 25
Регистрация: 12.01.2012
Сообщений: 623
19.08.2012, 06:24
Я не совсем понял ваш алгоритм, но может несколько производительнее было бы при проверке двух фигур вначале проверять проекции на ось OX и OY, если хотя бы одна пара проекций не персекается(не имеет общих точек), то дальнейшую более глубокую проверку можно не производить - прямоугольники 100 процентов не пересекаются. Вообще алгоритмов очень много, гуглите pygame collision detection. На русском языке нашел такую статью, правда она для флэша, но там больше теории
http://noregret.org/tutor/n/collision/#start
1
1 / 1 / 0
Регистрация: 14.08.2012
Сообщений: 14
23.08.2012, 04:03  [ТС]
Цитата Сообщение от Buckstabue Посмотреть сообщение
Я не совсем понял ваш алгоритм, но может несколько производительнее было бы при проверке двух фигур вначале проверять проекции на ось OX и OY, если хотя бы одна пара проекций не персекается(не имеет общих точек), то дальнейшую более глубокую проверку можно не производить - прямоугольники 100 процентов не пересекаются. Вообще алгоритмов очень много, гуглите pygame collision detection. На русском языке нашел такую статью, правда она для флэша, но там больше теории
http://noregret.org/tutor/n/collision/#start
Алгоритм в питоновом коде выглядит так:

Python
1
2
3
4
5
6
7
8
9
10
    
def colide(self, coord):
        x = coord[0]
        y = coord[1]
        xSize = coord[2]
        ySize = coord[3]  
        if (self.x <= x <= self.x + self.xSize or self.x <= x + xSize <= self.x + self.xSize):
            if (self.y <= y <= self.y + self.ySize or self.y <= y + ySize <= self.y + self.ySize):
                return True
        return False
self.x - левая сторона прямоугольника
x - левая сторона другого прямоугольника
self.xSize - Правая сторона прямоугольника
xSize - правая сторона другого прямоугольника

Координаты с "y" - это верх и низ

Затем в цикле проверяем функцию столкновения и меняем скорость прямоугольников.

Python
1
2
3
4
5
6
while 1:
    for i in range(len(rectList)):
        for j in range(i,len(rectList)):
            if rectList[i].colide(rectList[j].getCoordinates()):
                rectList[i].changeSpeed()
                rectList[j].changeSpeed()
Правда в таком случае они периодически застревают друг в друге . И тут не обнулишь значения координат, как при столкновении с границами окна
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
   def move(self, sec):
        self.x+=sec*self.xSpeed
        self.y+=sec*self.ySpeed
        
        if self.x + self.xSize > self.screenSize[0]:
            self.xSpeed=-self.xSpeed
            self.x=self.screenSize[0]-self.xSize
        if self.x<0:
           self.xSpeed=-self.xSpeed
           self.x=0
        if self.y + self.ySize > self.screenSize[1]:
           self.ySpeed=-self.ySpeed
           self.y=self.screenSize[1]-self.ySize
        if self.y<0:
           self.ySpeed=-self.ySpeed
           self.y=0
0
0 / 0 / 0
Регистрация: 09.04.2009
Сообщений: 7
14.09.2012, 21:52
В pygame есть функция которая отдает список спрайтов которые в данный момент перекрылись координатами. Простейшее решение: если перекрыто, то скорость и направление спрайта меняется. Все.
Сейчас под рукой нет книги где алгоритм прописан. Ищите.
0
 Аватар для Buckstabue
179 / 127 / 25
Регистрация: 12.01.2012
Сообщений: 623
15.09.2012, 10:54
Bulkin, здесь не спрайты, а голое рисование на канве
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
15.09.2012, 10:54
Помогаю со студенческими работами здесь

Вывести на экран 10 вложенных в друг друга закрашенных прямоугольников
вывести на экран 10 вложенных в друг друга закрашенных прямоугольников. в паскале

Определить число прямоугольников, которые не накладываются друг на друга
На квадратном листе бумаги в клетку размером 8х8 ячеек. Изображено несколько прямоугольников. Каждый прямоугольник состоит из ячеек. ...

Нарисовать в центре экрана десять вложенных друг в друга прямоугольников.
Помогите пожалуйста написать программу. Задание: Программа должна состоять как минимум из двух частей – основной программы и модуля...

Нарисовать на экране несколько вложенных друг в друга разноцветных прямоугольников
Зараннее сасибо)

Нарисовать в центре экрана десять вложенных друг в друга прямоугольников
Нарисовать в центре экрана десять вложенных друг в друга пря- моугольников


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru