Не понимаю... Причины такого поведения программы - не понимаю. Знаешь, почему? Потому что я, чтоб было проще отлаживать, безо всяких 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, которое проассоциировалось у меня с кометами, и я послушал.. Оказывается, название песни переводится (с испанского) как "я делаю ошибку" . Я только потом понял, что слово "комета" действительно похоже на англ. "to commit" - совершать. Интересно также, что в испанской его версии только одно m, и за ним следует e, что делает его еще больше похожим на русское "комета". Я не знаком с этимологией слова "комета" (может, кто-нить что-нить нароет?) - возможно, тут есть смысловая связь.. Но! Но я не нашел никаких упоминаний о кометах в видео Account'а.. Что-это - совпадение? Если да, то сразу по нескольким пунктам (ибо есть возможность, что ошибка все же делается..)) Не знаю уж, есть ли тут какой-то скрытый смысл [/offtop]
Lapp
24.07.2011 5:27
Кометы выглядят замечательно.. Но я не понимаю, почему они не притягиваются ни к Солнцу, ни к планетам? Некоторые проходят прямо через Солнце - и ничего! ) Притяжение еще не реализовано?
IUnknown
24.07.2011 5:43
Цитата
Притяжение еще не реализовано?
Нет еще, ищем пока ошибку, которая приводит к вылету программы у Account-а.
Присоединяйся, если есть желание У тебя ж есть компилятор который умеет работать с GLUT-ом? Присоединяю получившийся у меня "комбайн", который компилируется и в GCC, и в Турбо-Сях, и ведет себя одинаково, ибо отличается только сама отрисовка. Где может сбоить - ума не приложу.
Присоединяйся, если есть желание У тебя ж есть компилятор который умеет работать с GLUT-ом?
Спасибо - боюсь, поздновато, но я попробую (кстати, с той эмуляцией bgi-графики я не особо преуспел, хотя и пытался - в лом стало тратить на это время). GLUT не пользовал, сейчас пробую SDL - его должно с лихвой хватать для 2D.
Вечером посижу, попробую вникнуть..
Добавлено через 12 мин.
Цитата(IUnknown @ 24.07.2011 2:43)
Нет еще, ...
Мне это немного странно.. Я бы с этого начал, потому что если его сделать - ВСЕ объекты будут двигаться единым способом. Ведь, если посмотреть с общей точки зрения - это просто система нескольких гравитирующих тел. В общем случае их движение представляет полный хаос, но в рассматриваемом случае (супермассивная звезда, массивные планеты, легкие кометы) мы просто знаем (глядя на небо)), что порядок возможен . То есть, не нужно отдельно делать движение планет по кругу - просто нужно задать подходящую массу и вектор скорости. Проблема будет только в том, как "отладить" всю систему, чтоб она не разваливалась из-за межпланетного взаимодействия (впрочем, вот его-то можно и "выключить" для простоты)).
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; }
Пока думаю как лучше организовать проверку на столкновение и выход кометы за систему, ведь в одном случе уничтожаются два объекта в другом только комета и при обоих комета заново создается.
IUnknown
24.07.2011 20:42
Цитата
но в рассматриваемом случае (супермассивная звезда, массивные планеты, легкие кометы) мы просто знаем (глядя на небо)), что порядок возможен . То есть, не нужно отдельно делать движение планет по кругу - просто нужно задать подходящую массу и вектор скорости.
Да, да... Теоретически - так оно и есть. Как только дело доходит до практики... Попробовал я реализовать то же самое с использованием сил гравитации. Вот так и есть, реальная орбитальная скорость, реальная масса Солнца и планет, реальное расстояние между планетами и Солнцем + масштабирование, чтоб не было необходимости в мониторе с диагональю около 30 а.е.
Так вот, взаимодействие Солнца и планет отрабатывают на ура, все движется, да не по окружностям, а по эллиптическим орбитам. Красота... Вот, думаю, сейчас добавлю сюда комету, и посмотрю, как она будет двигаться. Так вот комете (при реальной же массе, которая на 16 порядков меньше массы Солнца - скажем, масса кометы Галлея = 2.2×1014 кг. против 2.0×1030 кг. солнечной массы) крышу сносит на первой же секунде, её солнце притягивает и выстреливает ей куда-то в неизвестном направлении как из пращи, со скоростью порядка 1000 км/сек (при том, что реальная орбитальная скорость Меркурия, как самой быстрой планеты, не превышает 50 км/сек). Начинаю увеличивать массу кометы - все постепенно начинает приходить в норму, скорость выброса из системы уменьшается, а когда масса кометы становится соизмерима с массами планет - то комета переходит на гелиоцентрическую орбиту... Я явно что-то упускаю, а вот что - пока сообразить не могу...
Account
25.07.2011 0:44
Вот что пытался сделать для столкновения, но что то не работает так как надо
if (!(c_01->OutOfSystem())) // Проверяем, если вышли за пределы - то пересоздаем комету... { for(int i=0;i<2;i++) {if (boom(*planets[i],*c_01)) {delete planets[i];delete c_01;c_01 = new Comet(rand()%maxx, maxy, 2, 5, -5);} else planets[i]->Update();} } else { delete c_01; c_01 = new Comet(rand()%maxx, maxy, 2, 5, -5); }
delay(50); } } int main() { Observer obj; sun = new Star(10); 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"); c_01 = new Comet(rand()%maxx, maxy, 2, 5, -5); obj.Run(); return 0; }
Lapp
26.07.2011 10:00
Спасибо, IUnknown, с удовольствием читал )), +1.
Цитата(IUnknown @ 24.07.2011 17:42)
чтоб не было необходимости в мониторе с диагональю около 30 а.е.
А фактически, он у нас есть - один на всех, но зато с самым совершенным компьютером, какой только можно придумать . Правда, программа в нем тоже только одна, и варировать условия слохновато.. ))
Цитата
Так вот, взаимодействие Солнца и планет отрабатывают на ура, все движется, да не по окружностям, а по эллиптическим орбитам. Красота... Вот, думаю, сейчас добавлю сюда комету, и посмотрю, как она будет двигаться. Так вот комете (при реальной же массе, которая на 16 порядков меньше массы Солнца - скажем, масса кометы Галлея = 2.2×1014 кг. против 2.0×1030 кг. солнечной массы) крышу сносит на первой же секунде, её солнце притягивает и выстреливает ей куда-то в неизвестном направлении как из пращи, со скоростью порядка 1000 км/сек (при том, что реальная орбитальная скорость Меркурия, как самой быстрой планеты, не превышает 50 км/сек). Начинаю увеличивать массу кометы - все постепенно начинает приходить в норму, скорость выброса из системы уменьшается, а когда масса кометы становится соизмерима с массами планет - то комета переходит на гелиоцентрическую орбиту... Я явно что-то упускаю, а вот что - пока сообразить не могу...
Я все никак не выберу момент поглубже въехать в эту кухню (со временем туго, как никогда). Но могу ответить из общих соображений, что не вижу в этом ничего такого плохого. Вопрос - как ты решаешь диффур? Достаточная ли точность? Кометы (реальные) движутся по ооочень вытянутым эллипсам. При этом в момент близости к Солнцу точность обычных к-р схем резко падает. Там нужно сильно дробить шаг. Это первое. Второе - таки да, система _должна_ быть чувствительна к возмущениям. СОстояние, которое мы видим на небе кажется стабильным, но область его устойчивости на самом деле невелика. Поэтому (я уже писал раньше тоже) нужно крайне тщательно подходить к выбору начальных условий. Та схема, которая фигурирует в условии задачи, со случайным запусканием комет - хотя и выглядит вполне разумной, на самом деле таковой не является. Движение комет (реальных) отлажено за миллионы лет (в основном, посредством ЕО им. Дарвина)). И это "выстреливание" нужно делать с бооооооольшой оглядкой - то есть, варьировать начальные данные в очень небольшом диапазоне. Задача трех и более тел - жутко сложная штука. Область устойчивости в фазовом пространстве представляет собой, имхо, некий фрактал (может, не везде). Так что, то, что ты наблюдаешь, Володь, это вполне может быть проекцией реального положения дел, но через конечно-разностный фильтр еще.
Я бы не отказался от кратких инструкций по GLUTу - чтоб ускорить старт; это было бы в любом случае мне полезно. Самых кратких )). ПОтому что если самому, то мне сейчас проще все же под SDL. Но попробовать glut тоже хочется .
Гость
26.07.2011 13:19
> Так вот комете (при реальной же массе, которая на 16 порядков меньше массы Солнца - скажем, масса кометы Галлея = 2.2×1014 кг. против 2.0×1030 кг. солнечной массы) крышу сносит на первой же секунде, её солнце притягивает и выстреливает ей куда-то в неизвестном направлении как из пращи, со скоростью порядка 1000 км/сек
Это дискретность времени так проявляется. Вблизи Солнца, когда скорость большая, а гравитационное поле меняется очень резко, надо такт симуляции сделать соизмерымим с размером этой окрестности, делённой на эту скорость (то есть должен быть очень маленьким). В реальной жизни такие же эффекты наблюдаются на микрообъектах (квантовые эффекты). То есть мы живём в Матрице.
IUnknown
27.07.2011 5:34
Цитата
Я бы не отказался от кратких инструкций по GLUTу - чтоб ускорить старт;
GLUT - он тем и хорош, что не надо практически никаких инструкций, чтобы начать работать с ним. Ну, скажем, вот пример простой программы (используется обычная двумерная графика, то есть, рабочая область ничем не отличается от той, которая есть при использовании BGI) с комментариями... Мне в свое время было достаточно нескольких таких несложных программ, чтобы начать понимать, что происходит и писать простые примеры (а для поставленной ТС задачи ничего более сложного, чем 2D и не нужно).
Как-то вот так:(Показать/Скрыть)
За сам пример - не пинать... Что пришло в голову, то и написал...
#include "glut.h"
const int maxx = 640; const int maxy = 480;
float posx, posy;
// Это функция, в которой будет рисоваться картинка void display() { // Очистка экрана glClear(GL_COLOR_BUFFER_BIT);
// Между glBegin(тип_примитива) и glEnd - отображение // примитивов: точек, линий, трех- (и более) -угольников glBegin(GL_POINTS); glVertex2f(posx, posy); // 2f - ибо 2 вещественных параметра... Есть много // других вариантов: 2d, 3f, 3d, 4f, 4d, ... glEnd();
// Поменяли видимый и невидимый буфер. Все, что было // нарисовано выше по тексту - появилось на экране... glutSwapBuffers(); }
// Это, как понятно, таймер, для выполнения цикличных действий void timer(int = 0 ) { // Пересчитываем координаты, делаем все, что нужно ... posx += 1; if(posx > maxx) posx = maxx/2.0;
// А теперь - чтобы отобразить изменения - вызываем перерисовку окна glutPostRedisplay(); // И переустанавливаем таймер, чтобы сработал через 1 мсек. Это надо // делать каждый раз, таймеры тут одноразовые. Выстрелил и все. glutTimerFunc(1, timer, 0); }
// Ну, и основная функция - тут все по названиям понятно int main(int argc, char** argv) { // Здесь можно проинициализировать начальными значениями // какие-то переменные posx = maxx/2.0; posy = maxy/2.0;
// Инициализируем GLUT glutInit(&argc, argv); // В каком режиме будем работать : 2 буфера и цветное изображение glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
// Инициализируем граф. окно нужного размера в нужном месте ... glutInitWindowSize(maxx, maxy); glutInitWindowPosition(100, 100); // ... с нужным заголовком glutCreateWindow("Solar System");
// Задаем, какого цвета будет фон. Я выбрал черный: RGBA glClearColor(0, 0, 0, 1.0);
// Ну, и, наконец, опишем матрицу // параллельного проецирования
// Первые два параметра - отсечение слева/справа, // следующие 2 - отсечение снизу/сверху, // завершают - отсечение ближнее/дальнее
// Поскольку мне 3D не нужно, и все координаты Z=0, // то третья пара просто устанавливает минимально // возможные значения. // А первые 2 пары создают матрицу на весь экран glOrtho(0, maxx, maxy, 0, -1, 1);
// Теперь установим все callback-функции, здесь может описываться // и та функция, которая будет вызываться при простое (glutIdleFunc), // и та, которая будет вызываться при изменении размеров окна // пользователем (glutReshapeFunc), и реакция на клавиатуру, и на мышь... // Для простых приложений достаточно зарегистрировать функцию отображения glutDisplayFunc(display);
// запустим таймер timer();
// Вот и все, подготовка окончена, запускаем основной обработчик событий GLUT-а glutMainLoop();
return 0; // Это чтоб компилятор не вякал }
Вся работа по отображению - в функции display(), между очисткой буфера и glutSwapBuffers(), или в подпрограммах/методах, что там у тебя используется для решения задачи, вызываемых из display(). Все вычисления - либо прямо в самой функции timer(), если их немного, или опять же, оттуда вызываются подпрограммы, производящие вычисления. С BGI на построение аналогичных программ под GLUT-ом перейти можно за один день.
Да, еще... Надо подключить к проекту библиотеки: glut32.lib, libglu32.a и libopengl32.a, иначе линкер будет бить тревогу...
Цитата
Вблизи Солнца, когда скорость большая, а гравитационное поле меняется очень резко, надо такт симуляции сделать соизмерымим с размером этой окрестности, делённой на эту скорость (то есть должен быть очень маленьким).
Да, похоже, мне этого и не хватало... Попробовал уменьшить вообще такт симуляции для кометы - становится более приемлемо. Попробую потом уменьшать именно при приближении к Солнцу. Когда время будет, что-то сразу так все навалилось...
Account
31.07.2011 21:37
Извиняюсь что молчал, работал во вторую смену и проблемы на работе. На этой неделе продолжу заниматься программой.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.