Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Ада и другие языки _ Игра "Солнечная система"

Автор: Account 17.07.2011 21:42

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

Моделируется движение планет в солнечной системе и прохождение комет через нее. В упрощенной модели не следует соблюдать реальные пропорции размеров планет, Солнца и расстояний между ними. В данной модели все планеты движутся вокруг Солнца в одной плоскости но с разной скоростью. У планет, Солнца и комет есть определенные размеры и масса, пропорциональная кубу линейного размера. В одном из углов "Солнечной системы" в случайные моменты времени генерируются кометы, летящие в произвольном направлении. Комета и планета престают существовать при столкновении. При столкновении кометы о Солнцем исчезает только комета. На кометы действуют силы притяжения планет и Солнца в соответствии с законом всемирного тяготения, что изменяет их траекторию. Комета вышедшая за пределы "Солнечной системы* исчезает на всегда. У комет есть хвост, направленный в сторону от Солнца, Управление моделью : при помощи клавиш: начать, закончить.

Итак, делаться будет на с++, с помощью псевдографики как в этой http://forum.pascal.net.ru/index.php?showtopic=28554.
Как изначально представляю себе это. Будет базовый класс фигура, который будет иметь такие показатели. как радиус планеты, масса, сила притяжения, радиус орбиты. Каждая планета наследник от этого класса.
Не понял вот этого в задании

Цитата
масса, пропорциональная кубу линейного размера
Так же пока не представляю как в случайном какого-либо конца экрана запустить комету в каком то направлении, рисовать ей хвост(какми способом) от солнца, ну и физику притяжения с изменением траектории.

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

Автор: sheka 18.07.2011 3:12

Цитата
с помощью псевдографики как в этой теме.
Что-то не нашел там псевдографики.
Цитата
Не понял вот этого в задании
Цитата
масса, пропорциональная кубу линейного размера
m = p * v;
v = 4 / 3 * Pi * r3
в данной модели нужна имитация только кубической зависимости т.к. коэффициент все равно не правильный будет).
Цитата
как в случайном какого-либо конца экрана запустить комету в каком то направлении
rand()
Цитата
рисовать ей хвост(какми способом) от солнца
Например так: ищешь вектор через центр солнца и центр кометы, нормируешь его, умножаешь вектор на длину хвоста, прибавляешь координаты центра кометы. Это конец хвоста. Соединяешь найденную точку с телом кометы помощью касательных к окружности. Вызываешь FloodFill с координатами центра этого треугольника либо рандомно выводишь пиксели в эту область. Представить можешь или нарисовать?
Цитата
ну и физику притяжения с изменением траектории.
F = G * m1 * m2 / r2
Учитывая, что центр масс системы без данной планеты в упрощенной схеме вряд ли искать надо + от ц. солнца он не сильно отличаться будет, тогда принимаем массу другого тела как ц.м солнца:
vпланеты = sqrt (G * mсолнца / rдо солнца)

Автор: IUnknown 18.07.2011 3:59

Цитата
Будет базовый класс фигура, который будет иметь такие показатели. как радиус планеты, масса, сила притяжения, радиус орбиты. Каждая планета наследник от этого класса.
Наследование в таком виде здесь напрочь не нужно... Меркурий, Венера, ... (и т.д. по списку) - это не подвиды планет, а экземпляры класса Планета...

Возможно, ты унаследуешься от единого предка НебесноеТело, от которого пойдет Звезда, Планета, Комета, чтобы во-первых, иметь возможность их единообразно отображать, во-вторых, чтобы реализовать для каждого из них функции, характерные только для этого класса (скажем, Звезда вообще не двигается, Планета движется по эллиптической орбите, а орбита Кометы зависит от многих факторов, в частности - от размера планеты, рядом с которой она в данный момент пролетает), но в том виде, в котором его описываешь ты - наследование бессмысленно...

Автор: TarasBer 18.07.2011 13:12

> Каждая планета наследник от этого класса.

Такой ООП нам не нужен.

> Возможно, ты унаследуешься от единого предка НебесноеТело, от которого пойдет Звезда, Планета, Комета

Я бы сделал единый класс НебесноеТело с полем типа (Звезда, Планета, Комета). Этого часто хватает с лихвой, а код проще и читаемей, чем с иерархиями.

> Итак, делаться будет на с++

Так можно наследование на шаблончиках сделать...

Автор: Account 18.07.2011 20:54

Цитата(sheka @ 18.07.2011 0:12) *

Что-то не нашел там псевдографики.

sheka,я не шарю в этом , а по поводу хвоста не совсем понялblush.gif
Цитата
Наследование в таком виде здесь напрочь не нужно... Меркурий, Венера, ... (и т.д. по списку) - это не подвиды планет, а экземпляры класса Планета...

Возможно, ты унаследуешься от единого предка НебесноеТело, от которого пойдет Звезда, Планета, Комета, чтобы во-первых, иметь возможность их единообразно отображать, во-вторых, чтобы реализовать для каждого из них функции, характерные только для этого класса (скажем, Звезда вообще не двигается, Планета движется по эллиптической орбите, а орбита Кометы зависит от многих факторов, в частности - от размера планеты, рядом с которой она в данный момент пролетает), но в том виде, в котором его описываешь ты - наследование бессмысленно...

Что то не догоняю.blush.gif Сделать три класса Звезда, Планета, Комета, а планеты просто создавать как экземпляры класса планета?
Цитата
Так можно наследование на шаблончиках сделать...

Раньше что то читал, но в данной ситуации пока не догоняю как применить.


Автор: TarasBer 18.07.2011 20:59

> а планеты просто создавать как экземпляры класса планета?

Ты хотел программу без экземпляров классов?

> Раньше что то читал, но в данной ситуации пока не догоняю как применить

Шаблон "небесное тело", параметр - перечислимого типа (звезда, планета, комета). Для каждого значения параметра определяешь шаблон по-своему.

Автор: Account 18.07.2011 21:17

Цитата(TarasBer @ 18.07.2011 17:59) *

> а планеты просто создавать как экземпляры класса планета?

Ты хотел программу без экземпляров классов?

> Раньше что то читал, но в данной ситуации пока не догоняю как применить

Шаблон "небесное тело", параметр - перечислимого типа (звезда, планета, комета). Для каждого значения параметра определяешь шаблон по-своему.


Вопрос в тупик загнал, так как я спросил (приведенная цитата ) про реализацию, знаний то у меня не много. Поэтому спрашиваю и советуюсь, как сделать лучше. ))))
Про шаблоны теоретически понял, на практике пока все сложновато. Так как в примерах наблюдал и делали только с базовыми типами int, float, а не с перечисляемыми.

Автор: sheka 19.07.2011 0:20

Вот псевдографика http://txtart.ru/index.html
Вот случайный хвост Прикрепленное изображение

Автор: IUnknown 19.07.2011 0:32

Цитата
Шаблон "небесное тело", параметр - перечислимого типа (звезда, планета, комета). Для каждого значения параметра определяешь шаблон по-своему.
Для этого надо, чтобы компилятор поддерживал частичную специализацию. Турбо С++, о котором шла речь раньше, ее не поддерживает...

Account, чтоб было понятно, о чем говорит Тарас - вот такой код будет прекрасно работать при использовании любого современного компилятора:
Пример (Показать/Скрыть)
, однако в досовском Турбо С++ ты этот пример работать не заставишь... А в других компиляторах нет поддержки graphics. Замкнутый круг.

P.S. Кстати... Я бы начинал написание программы именно с такого вот текстового "каркаса". Который будет тебе сообщать, что там инициализировалось, что в какой позиции находится, и что с чем взаимодействует. А вот когда это все будет нормально работать - тогда просто будешь заменять методы, печатающие информацию, на методы, отображающие ее графически. По крайней мере, я всегда делаю именно так. А то начнешь, сделаешь уже достаточно много, и красиво, и в самый ответственный момент вдруг выяснится, что вот именно то, что тебе сейчас нужно, компилятор не поддерживает. Ощущение не из приятных - все (или многое) переписывать заново... А с текстом ты сделаешь каркас гораздо быстрее, потеряешь меньше времени, и будет не так обидно.

Автор: Account 19.07.2011 0:51

sheka,спасибо за ссылку и за расчеты хвоста, как доберусь, попробую)))

IUnknown, так же спасибо за наглядный пример. Насчет компилятора тут вот как раз загвоздка, нужно именно на досовском(((

Так что буду делать))) Солнце + одну планету нарисовал, как ее запущу так выложу первые наработки)))

Автор: Lapp 19.07.2011 2:20

Забавная тема smile.gif.
С псевдографикой действительно неясно - Account, что же ты все-таки имел в виду? Кстати, подумалось, что та борландовская графика уже вполне заслуженно может переехать в раздел "псевдо" и гордо носить эту приставку к слову "графика" smile.gif. Sheka, суперская ссылка, просто шедевр, я с удовольствием разглядывал, спасибо, +1.

Все же я полагаю, что тут предполагается не текстовая мода, а графическая - в текстовой делать такую задачу все же странно. НО! Но по-хорошему-то (вау! я не припоминаю, чтоб я раньше встречал слова с двумя дефисами, кроме сложносоставных..), по-хорошему-то, надо писать основной код БЕЗ ГРАФИКИ вообще, а визуализацию всю поместить в отдельный модуль. Тогда графика будет, какая захочешь ("брюки превращаются.. брюки превращаются.. в элегантные шорты!" (С) smile.gif). Более того - то, что предлагал volvo877 (весьма ценный совет, на мой взгляд), легко реализуется в рамках этой же модели (как текстовые сообщения вместо графики).

Что касается хвоста (вроде - мелкая деталь, но вызывает большой интерес)), то я бы делал не так, как Шека предлагает (кстати, Шека, не совсем натурально вышло: хвост не сужается на удалении от кометы, а расширяется, хоть и бледнеет). Я бы описывал хвост тоже как потомок все того же самого небесного тела. Точнее - не весь хвост, а его частицы. По физике дела они такие и есть. То есть, примерно так..

Комета испускает частицы очень малой массы, которые имеют разброс скоростей. Интенсивность этого испускания и диапазон скоростей зависят он нагрева кометы, то есть от ее расстояния до Солнца (это все делается в одну строчку). Отделившись, частица летит сама, как все остальные небесные тела. Но есть одно отличие: она испытывает на себе дополнительную (т.е. кроме гравитации) силу - давление солнечного ветра. Эта сила совсем небольшая (поэтому при расчете движения остальных тел ее можно не учитывать), и действует она по радиусу от Солнца. Частицы хвоста можно изображать точками темного цвета (на фоне черного неба). И, наконец, эти частицы должны иметь некоторое конечное время жизни (это неверно по физике, но для модели сгодится). Вот, как-то так smile.gif.

Добавлено через 10 мин.
Такая модель хвоста на первый взгляд кажется сложнее, но на самом деле она даже проще, т.к. используется уже имеющийся механизм движения. Главное, чтоб вычислительных ресурсов компа хватило.. А это большой вопрос, поскольку добавляется немалое число небесных тел (заметно превосходящее число планет).

Добавлено через 13 мин.
Вот небольшая иллюстрация: Прикрепленное изображение
(взято http://luxaur.narod.ru/rubrika04/ris/11205.jpg). Хвост расширяется и немного загибается (благодаря сохранению момента импульса и увеличению расстояния до Солнца). Оба эти эффекта должны естественным образом получиться в описанной мной модели.

Автор: Account 20.07.2011 0:06

Lapp, да просто как то не воспринимается эта досовская графика как полноценная. вот и обозвал ее псевдо)

Итак, вот что сотворил, сильно не пинайте только))

games (Показать/Скрыть)



Не нравиться дергание при отрисовке на концах радиуса орбиты по оси х, но я так понял убрать это не возможно , так как в координатах используются только целые значения?
Цикл для рисовки естественно потом уберу из метода Move. просто для проверки загнал пока.

Автор: IUnknown 20.07.2011 0:54

Цитата
//подставлять неопределенные заранее значения не дает(((
Можно посмотреть, как пробовал?

Цитата
int ix=getmaxx()/2+orbp;
int iy=getmaxy()/2;
xy[0][0]=ix;
xy--[1][0]=iy; // <--- Вот это компилироваться не должно
Неужели TC пропускает такое?

Автор: Account 20.07.2011 1:09

Цитата(IUnknown @ 19.07.2011 21:54) *

Можно посмотреть, как пробовал?

Неужели TC пропускает такое?


Пробовал так
int xy[2][(orbp*4)];// и даже через дополнительную переменную
// Error: Constant expression recuired


По поводу второго, я при набирании поста просто накосячил)
конечно вот так на деле
xy[1][0]=iy;

Просто на ноуте иногда попадаю на доп. функциональные клавиши, в итоге курсор перепрыгивает + как всегда тороплюсь, невнимателен.

Автор: IUnknown 20.07.2011 1:38

Чтобы передавать в класс размер массива надо сделать немного другое описание класса:

template <int orbp>
class Planeta
{
// вот тут все так же, как и раньше, кроме того, что orb не должно быть в конструкторе
public:
Planeta(int r, int clr, int svr): rp®, clrp(clr), svrp(svr)
{ cout<<"Create Planeta\n"; }

// дальше без изменений
};

template <int orbp>
void Planeta<orbp>::Move()
{
int xy[2][orbp]; // Чудо? Ошибки нет...
int ix=getmaxx()/2+orbp; // Здесь тоже...

// ...
}

// Ну, а создавать объект - так:
Planeta<70> P1(10, 11, 10);
Чувствуешь разницу? Передаешь радиус орбиты как константное выражение, и использовать его уже можно... Ну, или простым new выделять память под двумерный массив xy, если тебе так проще...

Попробуй, должно и на TC компилироваться такое...

Автор: TarasBer 20.07.2011 13:04

Если нужен массив неизвестной при компиляции длины, используй векторы.
Или alloca.
Или чистую сишку без плюсов, в новом стандарте там это есть.
Или другие языки.

Автор: IUnknown 20.07.2011 14:37

Тарас, еще раз: чтобы что-то использовать - оно должно поддерживаться компилятором. Турбо С не знает ни про какие векторы. И про новые стандарты тоже. Отсюда и подобные решения проблем вместо решения задач...

Автор: TarasBer 20.07.2011 15:52

> Турбо С не знает ни про какие векторы.

Ну тогда да, проще передать размер в шаблоне, чем с нуля писать код вектора (хоть его и не так много надо для данной задачи).

Автор: IUnknown 20.07.2011 18:44

Итак, Account, пре-альфа хвоста кометы. Сделано на основе системы частиц, т.е., particle system, как и предлагал Lapp (в принципе, тут других вариантов и быть не могло, все эти генерации точек в конусах и трапециях выглядят уж слишком неестественно). Более того, я дам тебе еще одну идею: я когда-то делал подобную вещь (но не с настолько упрощенной физикой, а с более приближенной к реальности), так там для достоверности еще при удалении от кометы цвет частички менялся. От белого через желтый, через ярко-красный, потом темно-красный, потом коричневый к черному. Как только цвет становился черным - частица удалялась (здесь сделано чуть-чуть по другому, частица удаляется, когда она дальше 40 радиусов от кометы, но принцип тот же, и там и там при некотором удалении от кометы на частицу можно перестать обращать внимание)... Ну, в принципе, тут можно много чего сделать, все ограничено только твоей фантазией...

P.S. Да, я знаю, планета не двигается, код не вычищен, память не освобождается, можно еще кое-что выделить в методы и будет проще. Но на то и пре-альфа: оценка возможностей.


Прикрепленные файлы
Прикрепленный файл  SOLARSYS.CPP ( 6.76 килобайт ) Кол-во скачиваний: 415

Автор: Account 20.07.2011 20:58

IUnknown, вчерашний предложенный код с шаблоном еще не опробовал. только с работы пришел, отдохну попробую.

По поводу пре-альфа хвоста кометы, посмотрел, понравилось, сам код мне еще надо разобрать, так как бегло просмотрел, пока не догнал принцип вычисления от солнца и полностью вывод частичек, надо бы поподробней разобраться в коде. За исходник и за то что тратишь время отдельное спасибо. Только я теперь не знаю за что взяться, то ли продолжать свой код (выдрать у тебя только комету с хвостом) , то ли твой исходник переделывать, прям меня в тупик вогнал)

Автор: IUnknown 20.07.2011 22:56

Цитата
пока не догнал принцип вычисления от солнца
За это отвечает

вот этот кусок кода: (Показать/Скрыть)
, и аналогичный чуть ниже в Recalc...

Цитата
Только я теперь не знаю за что взяться, то ли продолжать свой код (выдрать у тебя только комету с хвостом) , то ли твой исходник переделывать
Ну, это уже тебе решать. Я только показал пример реализации. Справишься с написанием всей программы в подобном стиле - бери и дорабатывай мой каркас. Не справишься - продолжай свою программу.

Автор: Account 20.07.2011 23:35

Цитата(IUnknown @ 20.07.2011 19:56) *

За это отвечает

вот этот кусок кода: (Показать/Скрыть)
, и аналогичный чуть ниже в Recalc...

Ну, это уже тебе решать. Я только показал пример реализации. Справишься с написанием всей программы в подобном стиле - бери и дорабатывай мой каркас. Не справишься - продолжай свою программу.


Вряд ли справлюсь , за пример спасибо, покапаюсь конечно в нем)))
Вот сегодня запустил несколько планет)))) Код конечно плохой, но уж строго не суди, не программист)

И у меня вопрос, можно ли как-нибудь мерцания избежать и перепрыжку рисовки планет через ось по Y ( Если взять центр координат середину экрана)
код: (Показать/Скрыть)

Автор: IUnknown 21.07.2011 0:10

Цитата
и перепрыжку рисовки планет через ось по Y
А ты понимаешь причину такой перепрыжки? smile.gif Хочешь я добавлю к твоему коду 3 строки и ты сразу поймешь в чем дело? Смотри:

for(int dv = 0; dv <= 4 * orbp; dv++) {
putpixel(xy[0][dv], xy[1][dv], LIGHTGRAY);
}
Вот это добавь в самый конец Set(). Так сказать, чтобы очертить орбиту. И обрати внимание, с какой частотой у тебя точки стоят в одном месте, и насколько они редко расположены в другом (вот там где они реже всего и будет "перепрыжка". Но на самом то деле я бы это "перепрыжкой" не называл. Это то, как должно быть, именно там ведь у тебя и нет мерцания, правда? Мерцает в других местах траектории, потому что там обновление происходит слишком часто). Если б мне понадобилось запомнить координаты точек орбиты, я бы прошелся одним циклом от 0 до 359 градусов + sin и cos, и все точки были бы с одинаковой частотой. И тогда не будет вот этих "перепрыжек", и (скорее всего) уменьшится мерцание, ибо перерисовываться-то оно будет, но насколько реже - ты даже не представляешь smile.gif Если же тебе надо не круговую, а эллиптическую орбиту... Ну что ж, уравнение эллипса тоже не является секретом, точки вычисляются ненамного сложнее чем орбита круговая.

Автор: Account 21.07.2011 1:44

Сделал для проверки отдельно

#include <iostream.h>
#include <conio.h>
#include <stdlib.h>
#include <dos.h>
#include <graphics.h>
#include <math.h>
int main()
{
int gdriver = DETECT, gmode, errorcode;
initgraph(&gdriver, &gmode,
"../BGI");
errorcode = graphresult();
if (errorcode != grOk)
{
cerr<<"Graphics error";
cerr<<grapherrormsg(errorcode);
exit(1);

}
for(int i=0;i<6;i++)
{putpixel((getmaxx()/2+70*cos(i)), (getmaxy()/2+70*sin(i)), LIGHTGRAY);delay(200);}
getch();
return 0;
}


Точки не последовательно расположены, что то ни как не догоню. как упорядочить потом координаты?

Автор: IUnknown 21.07.2011 1:58

Ууу... Как все запущено. Радианы и градусы - разные вещи, правда? Вот библиотека math подразумевает, что тригонометрические функции работают с радианами. Делаем проще:

  // Не надо каждый градус, при таком маленьком радиусе достаточно каждого четвертого
for(int i = 0; i < 360; i += 4)
{
putpixel( (getmaxx()/2 + 70*cos(i*M_PI/180)),
(getmaxy()/2 + 70*sin(i*M_PI/180)),
LIGHTGRAY );
delay(50);
}

Автор: Account 21.07.2011 2:20

Цитата(IUnknown @ 20.07.2011 22:58) *

Ууу... Как все запущено. Радианы и градусы - разные вещи, правда? Вот библиотека math подразумевает, что тригонометрические функции работают с радианами. Делаем проще:
  // Не надо каждый градус, при таком маленьком радиусе достаточно каждого четвертого
for(int i = 0; i < 360; i += 4)
{
putpixel( (getmaxx()/2 + 70*cos(i*M_PI/180)),
(getmaxy()/2 + 70*sin(i*M_PI/180)),
LIGHTGRAY );
delay(50);
}



Я и забыл про это blush.gif Стыдно даже(((

Автор: Lapp 21.07.2011 2:55

Вопрос такой..
Тема вызывает интерес, и это понятно. Но BC у меня (и не только, думаю) нет. Можно ли и накормить волков (то есть преподавателей топикстартера), и сохранить овец (чтоб я и остальные могли компилировать прогу)? Я, конечно, могу переделать всю графику.. Но делать так с каждой новой версией кода по мере развития темы - извините, в лом. Есть ли более простой способ обеспечить совместимость?

Добавлено через 4 мин.
P.S.
Я использую gnu в основном.

Автор: IUnknown 21.07.2011 3:37

Можно попробовать воспользоваться вот этим:
http://codecutter.org/tools/winbgim/index.html (сразу говорю: я не пробовал, но положительные отзывы присутствуют. Насколько я помню, даже здесь я приводил эту ссылку уже).

Есть еще вот этот проект: http://sourceforge.net/projects/openbgi/ - он начинался на Сурсах, года три назад, вроде под Билдером и Dev C++ работала графика...

Или написать переходники к основным функциям именно под свой компилятор и под ОС (что там используется из BGI-шного - putpixel и circle? Пока вроде и все)

Но есть еще вероятность, что не все конструкции, пропускаемые TurboC, другие компиляторы будут компилировать (обратное тоже верно, примеры я приводил в начале этой темы). Что с этим делать?

Автор: Account 21.07.2011 22:42

IUnknown, добавил в твой код следующее,глобальную переменную

int dc=1; 


В метод Update в конце добавил строку

if (X>maxx+5 || Y<-5) {delete this;dc=0;}


и в цикл запуска всего, просто условие проверки переменной dc и если 0 то заново создать такую же комету, сначала прога работает нормально, но потом через некоторое время вылетает с ненормальным завершением, в чем причина?

Автор: IUnknown 21.07.2011 23:10

Хм... Не знаю, не пробовал делать так, как ты предлагаешь, ибо удалять объект там, где это делаешь ты - не очень хорошая идея. Сделал так: дописал еще один метод в класс Comet:

class Comet : public Celestial
{
// Все то, что и было, но в public-секции еще:

int OutOfSystem()
{
return (X < -5 || X > maxx + 5 || Y < -5 || Y > maxy + 5) ? 1 : 0;
}

};

// И вот это изменение в Run()

// ...

c_01->Update();

if(c_01->OutOfSystem()) // Проверяем, если вышли за пределы - то пересоздаем комету...
{
delete c_01;
c_01 = new Comet(maxx / 2. - 50, maxy, 2, 0, -5);
}

if(kbhit()) ...
, никаких лишних глобальных переменных, ничего больше. Только эти 2 фрагмента. Запустил, уже 20 минут летает, ничего не завершается... smile.gif

Автор: Account 21.07.2011 23:30

Цитата(IUnknown @ 21.07.2011 20:10) *

Хм... Не знаю, не пробовал делать так, как ты предлагаешь, ибо удалять объект там, где это делаешь ты - не очень хорошая идея. Сделал так: дописал еще один метод в класс Comet:

class Comet : public Celestial
{
// Все то, что и было, но в public-секции еще:

int OutOfSystem()
{
return (X < -5 || X > maxx + 5 || Y < -5 || Y > maxy + 5) ? 1 : 0;
}

};

// И вот это изменение в Run()

// ...

c_01->Update();

if(c_01->OutOfSystem()) // Проверяем, если вышли за пределы - то пересоздаем комету...
{
delete c_01;
c_01 = new Comet(maxx / 2. - 50, maxy, 2, 0, -5);
}

if(kbhit()) ...
, никаких лишних глобальных переменных, ничего больше. Только эти 2 фрагмента. Запустил, уже 20 минут летает, ничего не завершается... smile.gif

В одном из фильмов один из героев произнес фразу:"Чувствую себя богом...". А вот моя фраза:"Чувствую себя ЛОХОМ"))))

Спасибо за решение. Твой код почти разобрал. Что не до конца догоню потом спрошу. Жду завтрашнего дня, там выходные можно будет спокойно позаниматься. Буду опять через одно место делать движение планет(в твоем коде)))) После чего только столкновение останется и изменение траектории кометы из за силы притяжения)))

Автор: Account 22.07.2011 22:53

Вот жалкая попытка заставить двигаться планету, и опять вылет с ненормальным завершением выполнения(((

код (Показать/Скрыть)

Автор: IUnknown 23.07.2011 1:00

Что именно приводит к вылету программы, добавление движения планеты, или совместное движение планеты и кометы? Я вот сейчас попробовал запустить твою программу, закомментировав в Run() все, что касается кометы - прекрасно крутится зеленый кружок (хотя мне, например, непонятно твое желание просчитать сразу все точки и хранить массив из 720 int-ов, почему не хранить текущий угол поворота, и по нему рассчитывать координаты на каждой итерации?).

Только вот непорядок получается при переходе X от 359 к нулю. Остается артефакт, половина зеленой окружности (нижняя половина) остается на экране. Я бы сделал все-таки вот так:

   if (bShow)
{
if(X == 359) X = Y = 0;
Y = X++;
}
, тогда по крайней мере артефактов не остается. А вообще - непонятно, почему ты
1) не догадался эти действия производить в методе Recalc(), он же для этого и предназначен: посмотри на Update самого базового класса: сначала гасим изображение, потом пересчитываем то, что нужно пересчитать, и, наконец, проявляем изображение в новом месте.
2) почему до сих пор не догадался, как снять постоянное мерцание Солнца? Оно не должно перерисовываться, у тебя оно все время гасится, потом вызывается пустой Recalc(), потом опять появляется - зачем? Должно быть так: нужно его отобразить один раз, и после этого не гасить и не перерисовывать. Попробуй сделать подобное поведение сам, если не получится - я помогу.

Автор: Account 23.07.2011 1:45

Цитата(IUnknown @ 22.07.2011 22:00) *

Что именно приводит к вылету программы, добавление движения планеты, или совместное движение планеты и кометы? Я вот сейчас попробовал запустить твою программу, закомментировав в Run() все, что касается кометы - прекрасно крутится зеленый кружок (хотя мне, например, непонятно твое желание просчитать сразу все точки и хранить массив из 720 int-ов, почему не хранить текущий угол поворота, и по нему рассчитывать координаты на каждой итерации?).

Только вот непорядок получается при переходе X от 359 к нулю. Остается артефакт, половина зеленой окружности (нижняя половина) остается на экране. Я бы сделал все-таки вот так:

   if (bShow)
{
if(X == 359) X = Y = 0;
Y = X++;
}
, тогда по крайней мере артефактов не остается. А вообще - непонятно, почему ты
1) не догадался эти действия производить в методе Recalc(), он же для этого и предназначен: посмотри на Update самого базового класса: сначала гасим изображение, потом пересчитываем то, что нужно пересчитать, и, наконец, проявляем изображение в новом месте.
2) почему до сих пор не догадался, как снять постоянное мерцание Солнца? Оно не должно перерисовываться, у тебя оно все время гасится, потом вызывается пустой Recalc(), потом опять появляется - зачем? Должно быть так: нужно его отобразить один раз, и после этого не гасить и не перерисовывать. Попробуй сделать подобное поведение сам, если не получится - я помогу.


Наверное второе. Хотя заметил так же происходит вылет при столкновении. По поводу хранения угла, как сделаю отпишусь. У меня не доходит до указанного перехода вылетает с Abnormal programm terminated ( заранее извиняюсь за возможно неправильное написание на английском, не владею). По поводу артефакта понял, поправку принял.

По 1) Как переделаю выложу.
По 2)
код (Показать/Скрыть)


P.S. Вот только не пойму как еще сделать в данном коде разную скорость у планет.

Автор: IUnknown 23.07.2011 2:52

Цитата
По 2)
Хм... Хитрый, да? Это не совсем правильное решение smile.gif Объяснить? Объясняю... Вот этот код, который в Run, нужно будет слегка модифицировать, чтобы отслеживать взаимодействие объектов по схеме "каждое крупное небесное тело с каждой кометой". Для этого удобнее всего будет описать Солнце и планеты не как отдельные экземпляры, а как массив указателей на базовый класс, чтобы потом просто пройти по всему массиву и проверить, как очередной объект взаимодействует с кометой/кометами (если их будет больше одной на экране).

То, что ты сделал - выбивает объект класса Звезда из такой модели. То есть, ты не сможешь просто вызвать Update() в цикле для всех элементов массива КрупныеОбъекты, тебе придется исключать из этого процесса элемент массива, являющийся Солнцем, но проверять на взаимодействие придется со всеми... Опять лишние конструкции, опять if-ы, зачем тебе это? Нужно так модифицировать Star::Show(), чтобы при постоянном вызове Update() не происходило перерисовки объекта smile.gif

Цитата
Вот только не пойму как еще сделать в данном коде разную скорость у планет.
Вот как переделаешь перемещение планеты через угол (только угол не делай целочисленным, сделай вещественным) - поймешь... Будешь задавать для каждой планеты разное приращение угла - будет разная скорость вращения...

Цитата
У меня не доходит до указанного перехода вылетает с Abnormal programm terminated
Это уже я только завтра/послезавтра смогу потестировать, ноут с Windows уже забрали. Если б тебе хотя бы удалось выяснить, где происходит ошибка - было бы проще...

Автор: Account 23.07.2011 3:48

По солнцу сделал вот так, но не уверен что правильно, так как рисоваться то все равно будет, просто наложение так сказать.

void Star :: Show(int)
{
setcolor( YELLOW );
circle((int)X, (int)Y, Size);
}


По поводу вылетов. Закоментировал как и ты все что относилось к комете, в run(). Вылетов не стало.

Автор: Account 23.07.2011 13:07

Вот, что у меня теперь с использованием угла

код (Показать/Скрыть)

Автор: IUnknown 23.07.2011 14:19

Я бы все-таки сделал так:

Прикрепленный файл  SOLAR03.CPP ( 7.13 килобайт ) Кол-во скачиваний: 667


Обрати внимание на следующие вещи:
1. Все-таки, пересчет планеты я вынес в Recalc()
2. Celestial::Recalc() сделал не чисто виртуальным, а просто пустым, это дало возможность вообще отказаться от реализации этого метода в классе Star, будет использоваться унаследованный из предка.
3. Я не передаю в конструктор планеты начальный угол, пусть все планеты начинают вращение с одним углом (хотя, есть и другие варианты), но я передаю ΔAngle, на который изменяется угол каждую итерацию. Это дает возможность элементарно реализовать не то что разные скорости вращения, а практически реальные, то, что есть на самом деле в Солнечной системе. Просто делишь те самые 360 градусов, которые предстоит пройти планете на ее реальный период обращения в сутках, и получаешь то, что получаешь, я добавил Марс для примера - он, как и положено, вращается один раз, пока Земля делает почти два оборота. Теперь ты понимаешь, зачем я уточнил, что лучше сделать угол вещественным? smile.gif
4. Что касается Солнца - я тоже сделал так, как задумывалось изначально, чтоб вообще никакого обновления после первого показа не было.

Вроде все, больше ничего не менял.

Ах, да... Мне не удалось дождаться вылета программы: я раскомментировал все строки, касающиеся отображения кометы, и запустил программу. Генерация 30 (тридцати) комет при одновременном вращении двух планет - это достаточное время, чтобы вылет произошел, или надо ждать дольше? Вылета не было...

Автор: Account 23.07.2011 17:54

Цитата(IUnknown @ 23.07.2011 11:19) *

Я бы все-таки сделал так:

Прикрепленный файл  SOLAR03.CPP ( 7.13 килобайт ) Кол-во скачиваний: 667


Обрати внимание на следующие вещи:
1. Все-таки, пересчет планеты я вынес в Recalc()
2. Celestial::Recalc() сделал не чисто виртуальным, а просто пустым, это дало возможность вообще отказаться от реализации этого метода в классе Star, будет использоваться унаследованный из предка.
3. Я не передаю в конструктор планеты начальный угол, пусть все планеты начинают вращение с одним углом (хотя, есть и другие варианты), но я передаю ΔAngle, на который изменяется угол каждую итерацию. Это дает возможность элементарно реализовать не то что разные скорости вращения, а практически реальные, то, что есть на самом деле в Солнечной системе. Просто делишь те самые 360 градусов, которые предстоит пройти планете на ее реальный период обращения в сутках, и получаешь то, что получаешь, я добавил Марс для примера - он, как и положено, вращается один раз, пока Земля делает почти два оборота. Теперь ты понимаешь, зачем я уточнил, что лучше сделать угол вещественным? smile.gif
4. Что касается Солнца - я тоже сделал так, как задумывалось изначально, чтоб вообще никакого обновления после первого показа не было.

Вроде все, больше ничего не менял.

Ах, да... Мне не удалось дождаться вылета программы: я раскомментировал все строки, касающиеся отображения кометы, и запустил программу. Генерация 30 (тридцати) комет при одновременном вращении двух планет - это достаточное время, чтобы вылет произошел, или надо ждать дольше? Вылета не было...

Разобрал. спасибо. По солнцу, жалко что сам не догадался (.
Только не пойму вот что, в чем вот разница объявлений(присваивание 0),
virtual void Show(int) = 0;
virtual void Recalc()

Забыл еще спросить по частицам, массив размерностью определенный переменный const int parrSize = 1500;
а используется только 100 ?
maxParticles(100)

Ну и нужен совет как дальше делать, столкновение кометы с планетами и солнцем.
По поводу вылетов, происходят, может что с ОС на этом ноуте. Хочу потестировать на нетбуке, к вечеру отпишусь

Автор: Account 23.07.2011 18:57

Попробовал на нетбуке, тоже вылет, пишется Abnormal program termination.

На ноуте и нетбуке стоят WinXP Zver. Даже как то не посебе, раз у тебя все номрально, а у меня вылетает.

Автор: IUnknown 23.07.2011 19:06

Цитата(Account @ 23.07.2011 13:54) *
Только не пойму вот что, в чем вот разница объявлений(присваивание 0),
virtual void Show(int) = 0;
virtual void Recalc()
Присвоивание нуля методу делает его чисто виртуальным, ты не сможешь создать экземпляр класса Celestial (только потомки, да и то - чтобы их создать, надо чтоб потомок переопределял чисто виртуальную функцию, делал ее просто виртуальной). То есть, пока в классе есть хоть одна чисто виртуальная функция (неважно, описанная в этом классе или унаследованная от любого предка и не перекрытая) - он является абстрактным. Он как бы есть (наследоваться от него можно), но его в то же время и нет (создать экземпляр нельзя). В Паскале, кстати, такие методы как раз и называются Абстрактными...


Цитата(Account @ 23.07.2011 13:54) *
Забыл еще спросить по частицам, массив размерностью определенный переменный const int parrSize = 1500;
а используется только 100 ?
maxParticles(100)
Ага... Тут дело вот в чем: если взять просто массив из 100 частичек, инициализировать их, и потом, когда частички удалятся от кометы, переинициализировать опять рядом с кометой - то будет очень своеобразное поведение? то есть, хвост будет "фонтанировать": он будет создаваться, потом частички будут удаляться все дальше и дальше (при этом ни одна из них еще не уйдет слишком далеко, следовательно, новых-то частиц рядом с кометой не будет), пока не начнут уходить из области влияния комету, тогда она начнет испускать новую порцию частичек. Я попробовал - выглядит ужасно. Поэтому я решил пойти другим путем: я на каждой итерации добавляю по StepParticles - Count новых частичек рядом с кометой (где Count - счетчик удалившихся старых частиц), чтобы выброс шел постоянно. Естественно, что общее число частиц начинает возрастать. И возрастает до тех пор, пока длина хвоста не установится, потом возрастание прекращается. Так вот, для этого и нужно место под 1500 частичек, чтобы массив не переполнялся. Хотя, возможно, это я чересчур загнул, надо гонять программу и проверять, сколько максимально частичек присутствует в хвосте. Хочешь - сделай такую проверку. Мне лень было, я выделил место под 1500 элементов, так сказать, с запасом. Все равно, если б я делал для себя, я б не стал использовать массив, написал бы класс связного списка, и все... Сколько засунешь в него - столько он и будет хранить. Новые будут прибывать, старые - удаляться... Но тебе, чтоб не перегружать программу, я этого делать не стал.

Цитата(Account @ 23.07.2011 13:54) *
Ну и нужен совет как дальше делать, столкновение кометы с планетами и солнцем.
Я тебе уже говорил выше: проверяй комету с каждым телом, если Расстояние(Комета, НебесноеТело) меньше чем RКомета + RНебесноеТело, значит, произошло столкновение... Но тебе до этого надо еще принимать меры, когда комета слишком близко подходит к планете - это будет менять ее траекторию. Принцип - то же самый: проверять на каждом шаге расстояние, и если оно меньше какого-то расстояния, вычисленного по массе планеты (там Шека тебе чего-то писал) - то менять Vx и Vy кометы...

Цитата
Попробовал на нетбуке, тоже вылет, пишется Abnormal program termination.
Значит, запускай трассировку, и смотри, на какой именно строке программа вылетает. Возможно для этого придется перед каждой строкой в Comet::Recalc, Comet::Show и всех вызываемых оттуда функциях выводить тестовое сообщение, и потом смотреть, какое именно из них вывелось последним, значит, на последующей строке произошел вылет. Возможно - будет достаточно просто запустить отладку программы (F7 в IDE), поставить курсор на строку, скажем, с closegraph(), и нажать F4. При вылете программы курсор может быть установлен на строку с ошибкой. Так что ищи, где ошибка, коли она только у тебя воспроизводится...

Автор: Account 23.07.2011 19:42

IUnknown, а можешь скинуть свой компилятор, на какой-нито файлообменник?
В нем проверю.
По F4 ошибок не выдает, по F7 что то при создании частиц слишком долго) но постараюсь сделать

Автор: IUnknown 23.07.2011 20:02

Вот тут мой компилятор валяется: http://vlady.uzelok.net/progs/Tc30.exe
Просто запускай его, он сам распакуется куда скажешь...

Автор: Account 23.07.2011 20:13

Цитата(IUnknown @ 23.07.2011 17:02) *

Вот тут мой компилятор валяется: http://vlady.uzelok.net/progs/Tc30.exe
Просто запускай его, он сам распакуется куда скажешь...


Спасибо. Блин вылет имеется. Буду пробовать по F7.

Автор: IUnknown 23.07.2011 20:33

   for(i = 0; i <= stepParticles - count; i++)
{
// Вот отсюда ...
if(maxParticles + i >= parrSize)
{
cout << "Oops..." << endl;
}
// ... до сюда
trace[maxParticles + i] = new Particle((int)(getX()) - 1 + random(2), (int)(getY()) - 1 + random(2),
Vx + Cvt((int)((getX() - sun->getX()) / Ex)) - 1 + random(2),
Vy + Cvt((int)((getY() - sun->getY()) / Ey)) - 1 + random(2));
// ...
Попробуй добавить вот этот кусок, поставить на вывод Oops курсор и нажать на F4... Если оно туда придет, значит, как я и предполагаю, у тебя по какой-то причине генерируется слишком много частичек и происходит вылет за границы массива. Если нет - то я вообще не понимаю, в чем дело, больше просто негде ошибаться... Вообще-то обычно есть сообщение, по какой причине Abnormal programm termination. Либо Floating point error: Domain, либо еще что-то. Почему у тебя этого не показывает - непонятно...

Тебе сейчас главное - локализовать место, где происходит вылет. Через F7 это на самом деле будет долго, для первого раза выполняй методы не заходя в них, то есть, по F8 на имени метода... Потом, когда будешь знать, в каком именно методе происходит вылет - зайдешь в него и там уже жми на F8... Так каждый раз будешь подбираться все ближе и ближе, пока не найдешь, что именно глючит... Найдешь - говори...

Автор: Account 23.07.2011 21:13

Цитата(IUnknown @ 23.07.2011 17:33) *

код (Показать/Скрыть)
Попробуй добавить вот этот кусок, поставить на вывод Oops курсор и нажать на F4... Если оно туда придет, значит, как я и предполагаю, у тебя по какой-то причине генерируется слишком много частичек и происходит вылет за границы массива. Если нет - то я вообще не понимаю, в чем дело, больше просто негде ошибаться... Вообще-то обычно есть сообщение, по какой причине Abnormal programm termination. Либо Floating point error: Domain, либо еще что-то. Почему у тебя этого не показывает - непонятно...

Тебе сейчас главное - локализовать место, где происходит вылет. Через F7 это на самом деле будет долго, для первого раза выполняй методы не заходя в них, то есть, по F8 на имени метода... Потом, когда будешь знать, в каком именно методе происходит вылет - зайдешь в него и там уже жми на F8... Так каждый раз будешь подбираться все ближе и ближе, пока не найдешь, что именно глючит... Найдешь - говори...

Итак сидел и держал F8, вроде на апдейте кометы, подозреваю на ее recalc(), НО хочу дать потестить кому-ни то из знакомыx, так же было бы не плохо если бы кто-ни то из здешних у себя запустил и протестил. Вдруг может что из-за видео дров, у меня тут периодически вылет их был, когда возвращался из IDE (дос режима)

Автор: Account 23.07.2011 22:09

Итак, дал погонять еще двоим, у одного вылет через 3 секунды, у другого не так быстро но также вылет, с тем же сообщением что я выше писал(((

Что то в комете. Буду искать по возможности.

Автор: IUnknown 23.07.2011 22:34

Ау!!! Почему у меня (ноут с WinXP SP3, запускается через DosBox 0.74, мне на фиг не нужно смотреть на это все в полноэкранном режиме) нет никаких вылетов при том же коде, работающем с кометой ( видео прилагается: http://www.youtube.com/watch?v=PzSfcH3jBEE )? Это что, карма?

Автор: Account 23.07.2011 22:40

Да уж, возможно и карма, а скинь досбокс, я у себя через него запущу. Так же если что установлю uvScreenCamera_4.6.0.100, если будет ошибка попробую записать.

Автор: IUnknown 23.07.2011 22:42

Где-то вот тут: http://www.dosbox.com/download.php?main=1 smile.gif

Автор: Account 23.07.2011 23:23

Цитата(IUnknown @ 23.07.2011 19:42) *

Где-то вот тут: http://www.dosbox.com/download.php?main=1 smile.gif

Все запустил)) Вот скрин и http://www.youtube.com/watch?v=rXIfwEvxWjY


Эскизы прикрепленных изображений
Прикрепленное изображение

Автор: IUnknown 24.07.2011 2:37

Не понимаю... Причины такого поведения программы - не понимаю. Знаешь, почему? Потому что я, чтоб было проще отлаживать, безо всяких DosBox-ов, даже без Windows, переписал программу с использованием GLUT (там переделывать-то ничего не пришлось, только чуть-чуть перегруппировать методы и добавить условную компиляцию для двух графических примитивов - для putpixel и для circle - типа, это для ДОС, а это для glut) и запустил ее под Code::Blocks у себя на компьютере (не на ноуте, а именно на десктопе). Ты будешь смеяться, но оно не вылетает. Если уж и GCC ошибки не ловит - я не знаю, что еще делать...

Автор: Account 24.07.2011 2:56

Цитата(IUnknown @ 23.07.2011 23:37) *

Не понимаю... Причины такого поведения программы - не понимаю. Знаешь, почему? Потому что я, чтоб было проще отлаживать, безо всяких DosBox-ов, даже без Windows, переписал программу с использованием GLUT (там переделывать-то ничего не пришлось, только чуть-чуть перегруппировать методы и добавить условную компиляцию для двух графических примитивов - для putpixel и для circle - типа, это для ДОС, а это для glut) и запустил ее под Code::Blocks у себя на компьютере (не на ноуте, а именно на десктопе). Ты будешь смеяться, но оно не вылетает. Если уж и GCC ошибки не ловит - я не знаю, что еще делать...


У меня есть стационарный комп, но на нем стоит фряха, проверить пока больше нигде не могу. Как представиться возможность где-нито еще погонять. отпишусь по результатам. А пока займусь столкновением.
Я так понимаю, как ты предлагал что планеты буду как массив типа класса планета, чтобы можно было в цикле потом сравнить растояние каждой с кометой, только вот вычисления эти производить в Run() или как лучьше?

Автор: Lapp 24.07.2011 4:58

[offtop]
Посмотрел видео, а после него, как обычно, выскакивает еще несколько "похожих" видео. Среди них песня некоей CINDY SANCHEZ, COMETI UN ERROR.avi. Меня привлекло слово cometi, которое проассоциировалось у меня с кометами, и я послушал.. Оказывается, название песни переводится (с испанского) как "я делаю ошибку" smile.gif. Я только потом понял, что слово "комета" действительно похоже на англ. "to commit" - совершать. Интересно также, что в испанской его версии только одно m, и за ним следует e, что делает его еще больше похожим на русское "комета". Я не знаком с этимологией слова "комета" (может, кто-нить что-нить нароет?) - возможно, тут есть смысловая связь.. Но! Но я не нашел никаких упоминаний о кометах в видео Account'а.. Что-это - совпадение? Если да, то сразу по нескольким пунктам (ибо есть возможность, что ошибка все же делается..)) Не знаю уж, есть ли тут какой-то скрытый смысл lol.gif
[/offtop]

Автор: Lapp 24.07.2011 5:27

Кометы выглядят замечательно.. Но я не понимаю, почему они не притягиваются ни к Солнцу, ни к планетам? Некоторые проходят прямо через Солнце - и ничего! smile.gif)
Притяжение еще не реализовано?

Автор: IUnknown 24.07.2011 5:43

Цитата
Притяжение еще не реализовано?
Нет еще, ищем пока ошибку, которая приводит к вылету программы у Account-а.

Присоединяйся, если есть желание smile.gif У тебя ж есть компилятор который умеет работать с GLUT-ом? Присоединяю получившийся у меня "комбайн", который компилируется и в GCC, и в Турбо-Сях, и ведет себя одинаково, ибо отличается только сама отрисовка. Где может сбоить - ума не приложу.

Прикрепленный файл  main.cpp ( 8.89 килобайт ) Кол-во скачиваний: 579

(сохранено в UTF8)

Автор: Lapp 24.07.2011 6:00

Цитата(IUnknown @ 24.07.2011 2:43) *
Присоединяйся, если есть желание smile.gif У тебя ж есть компилятор который умеет работать с GLUT-ом?

Спасибо - боюсь, поздновато, но я попробую (кстати, с той эмуляцией bgi-графики я не особо преуспел, хотя и пытался - в лом стало тратить на это время). GLUT не пользовал, сейчас пробую SDL - его должно с лихвой хватать для 2D.

Вечером посижу, попробую вникнуть..

Добавлено через 12 мин.
Цитата(IUnknown @ 24.07.2011 2:43) *
Нет еще, ...

Мне это немного странно.. Я бы с этого начал, потому что если его сделать - ВСЕ объекты будут двигаться единым способом. Ведь, если посмотреть с общей точки зрения - это просто система нескольких гравитирующих тел. В общем случае их движение представляет полный хаос, но в рассматриваемом случае (супермассивная звезда, массивные планеты, легкие кометы) мы просто знаем (глядя на небо)), что порядок возможен yes2.gif. То есть, не нужно отдельно делать движение планет по кругу - просто нужно задать подходящую массу и вектор скорости. Проблема будет только в том, как "отладить" всю систему, чтоб она не разваливалась из-за межпланетного взаимодействия (впрочем, вот его-то можно и "выключить" для простоты)).

Автор: Account 24.07.2011 17:46

IUnknown, сделал вот что. Взяв за пример функцию dist() вот вставил вот такую boom() для проверки расположения кометы и каждой планеты

int boom(Celestial &a, Celestial &b)
{
double dx =abs (a.getX() - b.getX());
double dy =abs( a.getY() - b.getY());
if ((dx<(a.getSize()+3)) || (dy<(a.getSize()+3)))
return 1;
return 0;
}

Далее переправил такие места

//.....
Planet *planets[2];

//....
planets[0]->Update();
planets[1]->Update();
//....
planets[0] = new Planet(maxx / 2.+ 3 * 20, maxy / 2., 3,60, 360./365., "earth");
planets[1] = new Planet(maxx / 2.+ 4 * 20, maxy / 2., 3,80, 360./687., "mars");
//.....

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

Автор: IUnknown 24.07.2011 20:42

Цитата
но в рассматриваемом случае (супермассивная звезда, массивные планеты, легкие кометы) мы просто знаем (глядя на небо)), что порядок возможен yes2.gif . То есть, не нужно отдельно делать движение планет по кругу - просто нужно задать подходящую массу и вектор скорости.
Да, да... Теоретически - так оно и есть. Как только дело доходит до практики... Попробовал я реализовать то же самое с использованием сил гравитации. Вот так и есть, реальная орбитальная скорость, реальная масса Солнца и планет, реальное расстояние между планетами и Солнцем + масштабирование, чтоб не было необходимости в мониторе с диагональю около 30 а.е. smile.gif

Так вот, взаимодействие Солнца и планет отрабатывают на ура, все движется, да не по окружностям, а по эллиптическим орбитам. Красота... Вот, думаю, сейчас добавлю сюда комету, и посмотрю, как она будет двигаться. Так вот комете (при реальной же массе, которая на 16 порядков меньше массы Солнца - скажем, масса кометы Галлея = 2.2×1014 кг. против 2.0×1030 кг. солнечной массы) крышу сносит на первой же секунде, её солнце притягивает и выстреливает ей куда-то в неизвестном направлении как из пращи, со скоростью порядка 1000 км/сек smile.gif (при том, что реальная орбитальная скорость Меркурия, как самой быстрой планеты, не превышает 50 км/сек). Начинаю увеличивать массу кометы - все постепенно начинает приходить в норму, скорость выброса из системы уменьшается, а когда масса кометы становится соизмерима с массами планет - то комета переходит на гелиоцентрическую орбиту... Я явно что-то упускаю, а вот что - пока сообразить не могу...

Автор: Account 25.07.2011 0:44

Вот что пытался сделать для столкновения, но что то не работает так как надо

код (Показать/Скрыть)

Автор: Lapp 26.07.2011 10:00

Спасибо, IUnknown, с удовольствием читал )), +1.

Цитата(IUnknown @ 24.07.2011 17:42) *
чтоб не было необходимости в мониторе с диагональю около 30 а.е. smile.gif
А фактически, он у нас есть - один на всех, но зато с самым совершенным компьютером, какой только можно придумать smile.gif. Правда, программа в нем тоже только одна, и варировать условия слохновато.. ))

Цитата
Так вот, взаимодействие Солнца и планет отрабатывают на ура, все движется, да не по окружностям, а по эллиптическим орбитам. Красота... Вот, думаю, сейчас добавлю сюда комету, и посмотрю, как она будет двигаться. Так вот комете (при реальной же массе, которая на 16 порядков меньше массы Солнца - скажем, масса кометы Галлея = 2.2×1014 кг. против 2.0×1030 кг. солнечной массы) крышу сносит на первой же секунде, её солнце притягивает и выстреливает ей куда-то в неизвестном направлении как из пращи, со скоростью порядка 1000 км/сек smile.gif (при том, что реальная орбитальная скорость Меркурия, как самой быстрой планеты, не превышает 50 км/сек). Начинаю увеличивать массу кометы - все постепенно начинает приходить в норму, скорость выброса из системы уменьшается, а когда масса кометы становится соизмерима с массами планет - то комета переходит на гелиоцентрическую орбиту... Я явно что-то упускаю, а вот что - пока сообразить не могу...
Я все никак не выберу момент поглубже въехать в эту кухню (со временем туго, как никогда). Но могу ответить из общих соображений, что не вижу в этом ничего такого плохого. Вопрос - как ты решаешь диффур? Достаточная ли точность? Кометы (реальные) движутся по ооочень вытянутым эллипсам. При этом в момент близости к Солнцу точность обычных к-р схем резко падает. Там нужно сильно дробить шаг. Это первое. Второе - таки да, система _должна_ быть чувствительна к возмущениям. СОстояние, которое мы видим на небе кажется стабильным, но область его устойчивости на самом деле невелика. Поэтому (я уже писал раньше тоже) нужно крайне тщательно подходить к выбору начальных условий. Та схема, которая фигурирует в условии задачи, со случайным запусканием комет - хотя и выглядит вполне разумной, на самом деле таковой не является. Движение комет (реальных) отлажено за миллионы лет (в основном, посредством ЕО им. Дарвина)). И это "выстреливание" нужно делать с бооооооольшой оглядкой - то есть, варьировать начальные данные в очень небольшом диапазоне. Задача трех и более тел - жутко сложная штука. Область устойчивости в фазовом пространстве представляет собой, имхо, некий фрактал (может, не везде). Так что, то, что ты наблюдаешь, Володь, это вполне может быть проекцией реального положения дел, но через конечно-разностный фильтр еще.

Я бы не отказался от кратких инструкций по GLUTу - чтоб ускорить старт; это было бы в любом случае мне полезно. Самых кратких )). ПОтому что если самому, то мне сейчас проще все же под SDL. Но попробовать glut тоже хочется smile.gif.

Автор: Гость 26.07.2011 13:19

> Так вот комете (при реальной же массе, которая на 16 порядков меньше массы Солнца - скажем, масса кометы Галлея = 2.2×1014 кг. против 2.0×1030 кг. солнечной массы) крышу сносит на первой же секунде, её солнце притягивает и выстреливает ей куда-то в неизвестном направлении как из пращи, со скоростью порядка 1000 км/сек

Это дискретность времени так проявляется.
Вблизи Солнца, когда скорость большая, а гравитационное поле меняется очень резко, надо такт симуляции сделать соизмерымим с размером этой окрестности, делённой на эту скорость (то есть должен быть очень маленьким).
В реальной жизни такие же эффекты наблюдаются на микрообъектах (квантовые эффекты). То есть мы живём в Матрице.

Автор: IUnknown 27.07.2011 5:34

Цитата
Я бы не отказался от кратких инструкций по GLUTу - чтоб ускорить старт;
GLUT - он тем и хорош, что не надо практически никаких инструкций, чтобы начать работать с ним. Ну, скажем, вот пример простой программы (используется обычная двумерная графика, то есть, рабочая область ничем не отличается от той, которая есть при использовании BGI) с комментариями... Мне в свое время было достаточно нескольких таких несложных программ, чтобы начать понимать, что происходит и писать простые примеры (а для поставленной ТС задачи ничего более сложного, чем 2D и не нужно).

Как-то вот так: (Показать/Скрыть)
Вся работа по отображению - в функции display(), между очисткой буфера и glutSwapBuffers(), или в подпрограммах/методах, что там у тебя используется для решения задачи, вызываемых из display(). Все вычисления - либо прямо в самой функции timer(), если их немного, или опять же, оттуда вызываются подпрограммы, производящие вычисления. С BGI на построение аналогичных программ под GLUT-ом перейти можно за один день.

Да, еще... Надо подключить к проекту библиотеки: glut32.lib, libglu32.a и libopengl32.a, иначе линкер будет бить тревогу...

Цитата
Вблизи Солнца, когда скорость большая, а гравитационное поле меняется очень резко, надо такт симуляции сделать соизмерымим с размером этой окрестности, делённой на эту скорость (то есть должен быть очень маленьким).
Да, похоже, мне этого и не хватало... Попробовал уменьшить вообще такт симуляции для кометы - становится более приемлемо. Попробую потом уменьшать именно при приближении к Солнцу. Когда время будет, что-то сразу так все навалилось... sad.gif

Автор: Account 31.07.2011 21:37

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