Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Движеня шариков 
:(
    Опции темы
Elfet
Дата 5.6.2004, 21:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



А у меня примоугольник 4 и 5 , а шары 30-50 так что незаметно smile.gif


--------------------
PM MAIL WWW Skype   Вверх
student0511
Дата 22.5.2008, 21:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 26.3.2006

Репутация: нет
Всего: нет



      А как лучше всего написать обработку движения шариков, если их не 2, а, предположим, 10 или 16, как сделать чтобы они не пересекались? Я написал функцию, которая не даёт пересечься 2 шарикам при их независимом движении: скажем, один летит под углом 30 гр, а другой 210, если они должны пересечься, то они попросту друг друга обходят.
      Вот функция, которая преобразует координаты, если шар 1 должен пересечься с шаром 2:
Код

void BALL::cross(HDC hdc, BALL* ball, bool& f)
{
 double S = 0.0, alpha = 0.0, beta = 0.0;
 int dX = 0, dY = 0;
 POINT A;
 char buff[256];

 if((ball->Xc) >= Xc && (ball->Yc) < Yc)
 {
  //I)case
  dX = (ball->Xc) - Xc;
  dY = Yc - (ball->Yc);
  S = pow((dX*dX + dY*dY),0.5);

  alpha = atan((double)(dY)/(double)(dX));
  beta = (double)(PI) + atan((double)(dY)/(double)(dX));
 }
 
 if((ball->Xc) < Xc && (ball->Yc) <= Yc)
 {
  //II)case
  dX = Xc - (ball->Xc);
  dY = Yc - (ball->Yc);
  S = pow((dX*dX + dY*dY),0.5);

  alpha = (double)(PI) - atan((double)(dY)/(double)(dX));
  beta = (double)(2*PI) - atan((double)(dY)/(double)(dX));
 }

 if((ball->Xc) <= Xc && (ball->Yc) > Yc)
 {
  //III)case
  dX = Xc - (ball->Xc);
  dY = (ball->Yc) - Yc;
  S = pow((dX*dX + dY*dY),0.5);

  alpha = (double)(PI) + atan((double)(dY)/(double)(dX));
  beta = atan((double)(dY)/(double)(dX));
 }

 if((ball->Xc) > Xc && (ball->Yc) >= Yc)
 {
  //IV)case
  dX = (ball->Xc) - Xc;
  dY = (ball->Yc) - Yc;
  S = pow((dX*dX + dY*dY),0.5);
  
  alpha = (double)(2*PI) - atan((double)(dY)/(double)(dX));
  beta = (double)(PI) - atan((double)(dY)/(double)(dX));
 }

 if(S < (double)((Radius) + (ball->Radius)))
 {  
    TextOut(hdc, 3*cxClient/4, cyClient/2, "Collision", sizeof("Collision") - 1); 
             
    A.x = Xc + (int)((double)(Radius)*cos(alpha));
    A.y = Yc - (int)((double)(Radius)*sin(alpha));

    (ball->Xc) = A.x - (int)((double)(ball->Radius)*cos(beta));
    (ball->Yc) = A.y + (int)((double)(ball->Radius)*sin(beta));
    if(((ball->Xc) + Radius) >= cxClient)
        (ball->Xc) = cxClient - (ball->Radius);
    if(((ball->Xc) - Radius) <= 0)
        (ball->Xc) = (ball->Radius);
    if(((ball->Yc) - Radius) <= 0)
        (ball->Yc) = (ball->Radius);
    if(((ball->Yc) + Radius) >= cyClient)
        (ball->Yc) = cyClient - (ball->Radius);
   
    if(alpha >= double(2*PI))
       alpha -= double(2*PI);

    if(beta >= double(2*PI))
       beta -= double(2*PI);
    
    f = true;
 }
 else
     f = false;
}

       Переменная S отвечает за расстояние м/у центрами, угол alpha - это угол, через который я определяю точку пересечения прямой с 1 шаром, соединяющую центр 1-ого и 2-ого, соответственно beta - это то же самое, но по отношению ко 2-ому шарику. Точка A -  точка пересечения вышеупомянутой прямой с  1-ым шариком, соответственно, в ней и будет пересекаться шарики. Далее, используя точку A, я сдвигаю центр второго шара. Переменные cxClient - ширина экрана, cyClient - высота. Вообщем, будет 4 случая: шар 2 находится либо в 1-ой четверти, либо во 2-ой, либо в 3-ей, либо в 4-ой отностительно 1-ого шара, либо на одном и том же уровне с ним по y-координате или по x-координате. 
        Итак, а как терь лучше, используя данную функцию написать случай с более, чем 2-мя шарами, нужно, чтобы их было > 10 хотя бы. 
        Пока я обрабатываю сообщение WM_PAINT по нажатию клавиатуры вот так:
Код

case WM_PAINT:
     hdc = BeginPaint(hwnd, &ps);
     if(count > 0)
     {
      for(i = 0; i<count; i++)
      {
      B[i]->calc();
       for(k = 0; k<count; k++)
           for(j = 0; j<count; j++)
               if(j != k)
                  B[k]->cross(hdc, B[j], f);
                 //Prn = k;
       B[i]->draw(hdc, i);
      }
     }
     EndPaint(hwnd, &ps);
 return 0;

         Где void BALL::calc() вычисляет координаты шаров, void BALL::draw(HDC, const int) рисует i шар, count - это текущее количество шаров (count < 16), которое увеличивается при нажатии пробела и уменьшается при использовании VK_DELETE:
Код

case WM_KEYDOWN:
     InvalidateRect(hwnd, NULL, true);
     switch(wParam)
     {
      case VK_SPACE:
          if(count < NUM)
              count++;
      return 0;

      case VK_DELETE:
          if(count > 1)
              count--;
      return 0;

      default:
          break;
     }
     return 0;

         Вообщем, если таким образом обрабатывать WM_PAINT, то при большом скоплении шаров некоторые заступают друга на друга, что не есть гуд  smile 
         Может проблема в cross'е?
         Надеюсь на вашу помощь, а то курсач на след. недели сдавать, а ещё надо описать столкновение... Заведомо благодарен, сильно не пинайте за корявый код smile 

Это сообщение отредактировал(а) student0511 - 22.5.2008, 21:31

Присоединённый файл ( Кол-во скачиваний: 2 )
Присоединённый файл  Balls.rar 3,33 Kb
PM MAIL   Вверх
student0511
  Дата 23.5.2008, 04:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 26.3.2006

Репутация: нет
Всего: нет



Неужели никто не писал что-то подобное? ведь должны же быть подобные работы.
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Алгоритмы"

maxim1000

Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Алгоритмы | Следующая тема »


 




[ Время генерации скрипта: 0.0581 ]   [ Использовано запросов: 20 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.