IPB
ЛогинПароль:

> Шарики, ООП
Bokul
сообщение 22.12.2006 1:44
Сообщение #1


Гуру
*****

Группа: Пользователи
Сообщений: 1 117
Пол: Мужской
Реальное имя: Богдан

Репутация: -  11  +


Тема зародилась Задачник по ООП, а это ее продолжения.
Вот структура того, что я написал (измененная)

1 TGObject -// движущейся графический объект, умеет:
// - инитиализировать себя
constructor init(speed,color:byte; angle,time:real);
// - двигаться
procedure moveto;
//- высчитывать свое новое положение, перекрывается в наследниках
procedure calculation; virtual; //abstract;
//- вызывается с Supervisor, только в случае столкновения.
// Меняем скорость и угол полета.
procedure ChangeDirection(speed:byte; angle:real);
// рисуем себя, перекрывается в наследниках
procedure show; virtual; // abstract;
// стираем себя, перекрывается в наследниках
procedure hide; virtual; // abstract;
// стирает себя с экрана
destructor done; virtual;

2 TBall - наследник TGObject, теперь это движущейся шарик
// - добавили новое поле r -радиус, инициализацию остальных полей наследуем
constructor init(x,y:integer; speed,color:byte; angle,time:real; r:byte);
procedure moveto;// перекрываем, наслудуем
procedure calculation; virtual;// перекрываем
procedure show; virtual; // тоже перекрываем
procedure hide; virtual; // тоже перекрываем
destructor done; virtual; // перекрываем, наслудуем


3 TItem - элемент списка указателей на объекты TBall
// инициализирует свою информационную часть
constructor constructor init(Info:TPGObject; Sled:TPItem);
destructor done;// удаляем информационную часть

4 TList - содержит список указателей на объеты типа TBall
constructor init;//-инициализирует список
function AddItem(Data:TPGObject):boolean; // добавляем новый элемент
function DeleteItem(pdel:TPItem):boolean; // удаляем элемент
destructor done;//удаляем весь список


Исходники в виде модулей для FPC - Прикрепленный файл  Balls.rar ( 15.06 килобайт ) Кол-во скачиваний: 503



Возникли затруднения в написания модуля TSupervisor, а именно с главным циклом и наследием этого объекта.
Вот, что я написал

uses objects,graphl,UnitTGObject,UnitList;
const
background=black;
ballcolor=red;


{------------------------TSupervisor------------------}
type
TPSuperVisor=^TSuperVisor;
TSuperVisor=object
GObjectsList:TList;
Rect:TRect;
constructor init(xa,ya,xb,yb:integer);
function AddGObject(p:TPGObject):boolean;
function DeleteGObject(p:TPGObject):boolean;
function ChangeDirection;
function Calculation;
function WriteResults;
procedure main;
destructor done;
end;
constructor TSuperVisor.init;
begin
GObjectsList.init;
Rect.assign(xa,ya,xb,yb);
SetColor(white);
Rectangle(xa,ya,xb,yb);
end;

function TSuperVisor.AddGObject(p:TPGObject);
begin
AddGObject:=GObjectsList.AddItem(p);
end;

function TSuperVisor.DeleteGObject(p:TPGObject):boolean;
begin
DeleteTPGObject:=GObjectsList.DeleteItem(p);
end;

procedure TSuperVisor.main;
begin
end;

destructor TSuperVisor.done;
begin
GObjectsList.done;
ClearDevice;
end;



--------------------
Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов
volvo
сообщение 25.12.2006 21:47
Сообщение #2


Гость






Будет тормозить, конечно... Представь, что у тебя, скажем, 4, а лучше - 8 точек в модели (еще лучше - 16/32, ибо это будет еще ближе к "шару", но тогда процессор просто повесится). И 100 шариков... И каждый раз ты будешь проверять, 4 (или 8) точек, "а одна из этих точек не внутри ли какого-нибудь из оставшихся 99 шаров?"... Представляешь себе объемы вычислений? 100*100 - сразу 10000 проверок (даже по одной точке, по 4-м будет уже с полсотни тысяч) А ведь еще надо отрисовывать картинку, да и проверять столкновение со стенками... Да и сами проверки - не просто 2+2, а нечто более сложное...

Придется принимать доп. меры для сокращения объемов вычислений...

Как вариант - могу предложить следующее (просто набросок, возможно это будет не очень эффективно, на какой-то прирост производительности, определенно даст):
Хранить не 1, а 2 списка объектов... Да, да, именно 2 (если даже не больше)... Смотри, что я имею в виду: Когда объект A может столкнуться с объектом B? Только тогда, когда Sign(A.Vx) <> Sign(B.Vx), т.е. проекции оббъектов на ось OX приближаются друг к другу... Вот тебе и задумка: хранить в списке ListOne только те объекты, которые движутся слева направо или по вертикали, т.е. Vx неотрицательна, а в ListTwo - все остальные... Преимущества - для каждого объекта из ListOne надо проверять на коллизии только объекты из ListTwo, в среднем - 2-х кратное уменьшение числа вычислений...

Теперь ты меня, конечно, спросишь: а что будем делать, когда Vx меняет знак (отскок от стены млм друг от друга)? А ничего особенного. Все равно есть вот этот кусок кода:

p := GObjectsList.List;
while p <> nil do begin
p^.data^.moveto;
p := p^.next;
end;

Вот, после MoveTo и проверять, изменился ли знак Vx... Если изменился - то удалить указатель на объект из одного списка, и добавить в другой... Для обоих списков (в худшем случае) "+200" операций... По сравнению с экономией примерно 20000-25000, о чем я говорил выше - будет ускорение обработки...

НО: для этого во-первых надо будет перейти на представление скорости через Vx/Vy, о чем я уже тебе говорил, а во-вторых - в класс TItem придется добавить флажок типа Boolean, чтобы для того объекта, для которого уже вызывалась MoveTo, не вызвать ее еще раз... И тогда:

// Вначале, конечно, идем по одному списку
p := GFirstObjectsList.List;
while p <> nil do begin
p^.data^.moveto;
// если знак p^.data^.Vx изменился (вполне возможно, что об этом может
// сигнализировать и сама moveto, которую просто переделать в функцию)
// - то скопировать p^.data в список GSecondObjectsList, и удалить из текущего
// !!! special_flag (что это - см. ниже) для перенесенного объекта установить в True

p := p^.next;
end;

// А теперь, собственно, по второму:
p := GSecondObjectsList.List;
while p <> nil do begin

// вот это - тот самый флажок, о котором я говорил
// установленный в True он запретил вызывать moveto для объекта, если был
// False - то все в порядке, это НЕ только что добавленное в этот список значение

if NOT p^.data^.special_flag then begin { <--- Исправлено !!! }
p^.data^.moveto
// если знак p^.data^.Vx изменился - все с точностью "до наоборот" тому,
// что написано выше - переносим из Second в First список, только special_flag
// оставляем False
end
else p^.data^.special_flag := false;
// Все, теперь это - полноценный объект, и к нему будут применяться
// все операции, что и к остальным

p := p^.next;
end;
Мне такая идея отсечения нравится - как я раньше не додумался, надо будет как-нибудь попробовать... smile.gif

Сообщение отредактировано: volvo - 3.01.2007 12:13
 К началу страницы 
+ Ответить 

Сообщений в этой теме
Bokul   Шарики   22.12.2006 1:44
volvo   Так... Ну, у меня после прочтения программы тоже ш...   22.12.2006 3:21
Bokul   :respect: :ROFL: :lol: Спасибо! Буду ...   22.12.2006 3:25
volvo   :) Значит, так... По порядку: С такой реализацией...   22.12.2006 16:07
Bokul   Спасибо! :) Учел все замечания, исправил, из...   23.12.2006 2:33
volvo   А вот с этого места - поподробнее... Что это будут...   23.12.2006 3:19
Bokul   :lol: Думал наследием воспользоваться как инс...   23.12.2006 3:50
volvo   :no1: Совершенно не обязательно... Хочешь способ,...   23.12.2006 4:19
Bokul   Пересчет идет где? В TGObject? Для квадрата у...   23.12.2006 4:29
volvo   Зачем? Прямо в ComputeCollision - у тебя же ...   23.12.2006 4:38
Bokul   Спасибо! :) Извиняюсь, что заставил себя жда...   24.12.2006 3:49
volvo   Понаблюдав чуть-чуть за шариками, можно увидеть си...   24.12.2006 21:43
volvo   Реализация TSupervisor осталась за кадром, ты не п...   24.12.2006 9:33
Bokul   Да я вроде все модули прикреплял :blink: , вот TSu...   24.12.2006 18:26
Bokul   Да ты - прав, выигрыш видно сразу, особенно ког...   24.12.2006 22:39
volvo   А именно - вот что (эту картинку я наблюдал сам): ...   24.12.2006 22:59
Bokul   Не выходит спроектировать тоже самое (хотя, ког...   25.12.2006 0:09
volvo   Ты не забыл, что у каждого объекта есть вектор ско...   25.12.2006 0:40
Bokul   :yes2: Ты предлагаешь передавать объекту точк...   25.12.2006 1:16
volvo   Что-то обсуждение зацикливается... Я же написал те...   25.12.2006 1:59
Bokul   Ага, просто надо разобраться до конца и потом у...   25.12.2006 2:17
volvo   :blink: Var v, v1, v2: TVector; ... v := k * (k...   25.12.2006 2:29
Bokul   Мысли в слух: Ведь мы полностью не сможем скопиро...   25.12.2006 20:48
Bokul   Какие преимущества: больше не надо мучится со спос...   25.12.2006 21:01
volvo   Будет тормозить, конечно... Представь, что у тебя,...   25.12.2006 21:47
volvo   Сорри, ошибочка... Не будет работать для двух объе...   25.12.2006 21:59
Bokul   Уже сделано :) Правда я оставил угол L для совм...   25.12.2006 22:19
volvo   :no1: Ты не понял... Еще раз перечитай... Флажок ...   25.12.2006 23:00
Bokul   Реализация Многоугольник окончена. Возник вопрос -...   31.12.2006 19:48


 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 28.07.2025 5:22
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"