Real MK Club Unofficial Community
    Головна  |  Статті  |  Форум  |  Галерея  |  Файли  |  Сайти  |  Огляди  |    
Ласкаво просимо, Гість. Будь ласка, увійдіть або зареєструйтеся.
Вам не прийшов лист із кодом активації?
09 Вер. 2010, 08:11:22

Увійти
Останні надходження до статей: Blender. Урок Перший
Останні опитування: Яка тематика статей вам більш цікава?

ПочатокПочаток ДопомогаДопомога ПошукПошук КалендарКалендар УвійтиУвійти РеєстраціяРеєстрація
Real MKClub Unofficial Community Комп’ютерний світ Програмування (Модератори: valxp, Jolly Roger) Тема: броунівський рух 0 Користувачів й 1 Гість дивляться цю тему. « попередня тема наступна тема »
Сторінок: [1] Униз Друк
Автор Тема: броунівський рух  (Прочитано 864 раз)
Offline andy
No avatar!
Новачок
*
Повідомлень: 39
не все так як є... як здається
Карма: +0/-0
Стать: Чоловіча
WWW
  « : 04 Бер. 2010, 20:38:07 »
 
Написати імітаційну програму з застосуванням афінних перетворень, яка дозволяє в
автоматичному режимі та при ручному керуванні створювати динамічно змінну
візуалізацію при якій моделюється наступний вид „броуновского руху”. Набір малих
об’єктів (пікселів) рухається без втрат на тертя з відбиттям від границь екрана. Кожен
піксел має випадкову початкову швидкість і напрямок під кутом 45 градусів – одне з
чотирьох можливих. Піксели взаємодіють з об’єктом у виді відрізка – відбиваються від
нього і передають йому при ударах складову горизонтальної швидкості. Відрізок
стійкий до обертання і вертикального зсуву, і також відбивається від бічних границь
екрана при їхньому досягненні.


* 11.jpg (73.71 Кб, 697x490 - переглянуто 82 раз.)

комп*ютер, сів... і не встав, бо затягує...
Offline Sergey K
UltraUser
*
Повідомлень: 2311
Карма: +5/-0
Стать: Чоловіча
WWW
  « Відповідь #1 : 04 Бер. 2010, 22:17:42 »
 
а чого 45 градусів? Це як у мультику!
Довільний кут згідно кута, під яким стикаються молекули. Подальша швидкість обох молекул залежить від енергій обох молекул до співударяння.
Offline Jolly Roger
*
Повідомлень: 1559
Дезінформатор
Карма: +12/-2
Стать: Чоловіча
WWW
  « Відповідь #2 : 06 Бер. 2010, 17:33:54 »
 
Погоджуюся з Сергієм.
Задача без відрізка зводиться до ітеративної моделі.
Дано:
 * масив початкових координат пікселів
 * масив початкових векторів швидкостей пікселів

Записується закон руху у вигляді «положення пікселя = попереднє положення пікселя + функція інкремента, що залежить від зовнішніх чинників»
Тобто, фактично, тобі лишилося записати цю функцію інкременту, і на цьому задача вирішена. Лишається тільки запускати моделювання по таймеру.
« Останнє редагування: 06 Бер. 2010, 17:40:29 від Jolly Roger »

Когда у общества нет цветовой дифференциации штанов, то нет цели, а когда нет цели…
Offline andy
No avatar!
Новачок
*
Повідомлень: 39
не все так як є... як здається
Карма: +0/-0
Стать: Чоловіча
WWW
  « Відповідь #3 : 06 Бер. 2010, 21:24:57 »
 
найшов шось подібне:  а як тут додати дошку ще? допоможіть кому не ліньки  Ops!
Код:
Uses Graph,Crt;
 
const MaxShar=10;
type shar = object
  { переменные }
  x,y:integer; { текущие координаты шара }
  r:word;      { радиус }
  color:byte;  { цвет шара }
  dx,dy:shortint; { скорость. задается значениями
                    перемещения на каждом шаге (в точках) }
  hits:set of byte; { множество шаров с которыми данный шар уже
  столкнулся и с которыми не надо обсчитывать столкновение еще раз }
  { методы }
  constructor initShar(x0,y0:integer; r0:word; color0:byte; dx0,dy0:shortint);
  procedure Move; { двигаем }
  procedure Show; { показываем }
  procedure Hide; { прячем }
  procedure CheckBorder; { проверяем на выход за границы экрана }
  procedure CheckHit(k:byte); { проверяем на столкновение с другим шаром }
  procedure revertXDirection; { поменять Х/Y-составляющую скорости }
  procedure revertYDirection; { на противоположную }
  procedure TurnAfterHit(k:byte); { вычислить новые значения
               скорости двух шаров после удара. Первый шар - шар
               данного объекта, второй - с индексом k в массиве }
  function Value:real; { вычислить объем шара. Нужно для вычисления
       скорости. Вообще-то там масса нужна, но учитывая, что плотность
       все-равно сократиться при делении, используем объем }
  {procedure PrintState;} { отладочные печати }
  end;
var bgColor,i:byte;
    x,y,dx,dy,ErrCode:integer;
    r:word;
    shars: array[1..MaxShar] of shar; { массив шаров }
    sh:shar;
    f:text; { файл для отладочных печатей }
Procedure shar.Move;
  begin
  x:=x+dx;
  y:=y+dy;
  end;
Procedure shar.Show;
  begin
  setColor(color);
  circle(x, y, r);
  {PutPixel(x,y,color);} { уберите комментарий чтобы увидеть траекторию }
  end;
Procedure shar.Hide;
  begin
  setColor(bgColor);
  circle(x, y, r);
  end;
procedure shar.revertXDirection;
  begin
  dx:=-dx;
  x:=x+dx;
  end;
procedure shar.revertYDirection;
  begin
  dy:=-dy;
  y:=y+dy;
  end;
Constructor shar.initShar(x0, y0 :integer; r0 :word; color0 :byte; dx0, dy0 :shortint);
  begin
  x:=x0;
  y:=y0;
  r:=r0;
  color:=color0;
  dx:=dx0;
  dy:=dy0;
  hits:=[];
  end;
procedure shar.CheckBorder;
  begin
  if (r+x>=GetMaxX-1) or (x-r<=1) then revertXDirection;
  if (y+r>=GetMaxY-1) or (y-r<=1) then revertYDirection
  end;
{procedure shar.PrintState;
  begin
  writeln(f,'x=',x:3,' y=',y:3,' r=',r:3,' dx=',dx:3,' dy=',dy:3);
  end;}
procedure shar.TurnAfterHit(k:byte);
{ формулы для движения шаров взяты здесь:
  [url]http://ferro.phys.msu.ru/prak/PDF/01-mechanics/07.pdf[/url] }
var m1, m2 :real;
    vx10,vy10,vx20,vy20:integer;
  begin
  m1 := Value;            { массы }
  m2 := shars[k].Value;
  vx10 := dx;             { начальные значения скоростей }
  vy10 := dy;
  vx20 := shars[k].dx;
  vy20 := shars[k].dy;
  { скорость первого шара после удара }
  dx := round((2*m2*vx20 + (m1-m2)*vx10)/(m1+m2));
  dy := round((2*m2*vy20 + (m1-m2)*vy10)/(m1+m2));
  { скорость второго шара после удара }
  shars[k].dx := round((2*m1*vx10 + (m2-m1)*vx20)/(m1+m2));
  shars[k].dy := round((2*m1*vy10 + (m2-m1)*vy20)/(m1+m2));
  end;
function shar.Value:real;
  begin { возвращает объем шара }
  Value:=4*Pi*r*r*r/3;
  end;
procedure shar.CheckHit(k:byte);
var i1:byte;
    dist:longint;
  begin
  for i1:=1 to MaxShar do if ((i1<>k) and not(k in hits)) then
    begin
    shars[i1].hits:=shars[i1].hits+[k];
    dist:=round(sqrt(sqr(1.0*x-shars[i1].x)+sqr(1.0*y-shars[i1].y)));
    if (dist<r+shars[i1].r) then
      begin
      TurnAfterHit(i1);
 
      CheckBorder;
      Move;
      shars[i1].CheckBorder;
      shars[i1].Move;
 
      { скорость задается значениеми dx и dy - шагами движения. Таким
      образом она дискретна. Момент столкновения определяется по
      расстоянию между шарами. Но запросто может случиться, что шары
      на каком-то шаге пересекутся и в этом случае необходимо их
      развести в разные стороны перед тем как высчитывать расстояние на
      следуещем шаге, иначе они могут пребывать в состоянии постоянного
      столкновения }
      dist:=round(sqrt(sqr(1.0*x-shars[i1].x)+sqr(1.0*y-shars[i1].y)));
      while (dist<r+shars[i1].r) do
        begin
        CheckBorder;
        Move;
        shars[i1].CheckBorder;
        shars[i1].Move;
        dist:=round(sqrt(sqr(1.0*x-shars[i1].x)+sqr(1.0*y-shars[i1].y)));
        end;
      end;
    end;
  end;
 
function initializeGraph:integer;
var grDriver : Integer;
      grMode : Integer;
  begin
  grDriver:=Detect;
  InitGraph(grDriver, grMode, '');
  initializeGraph:=GraphResult;
  end;
 
begin
ErrCode:=initializeGraph;
if ErrCode <> grOk then
   WriteLn('Ошибка инициализации графики:', GraphErrorMsg(ErrCode))
else
  begin
  assign(f,'log.txt');
  rewrite(f);
  bgColor:=0;
  rectangle(1,1,GetMaxX-1,GetMaxY-1);
 
  {shars[1].initShar(100,100,50,3,6,-3);
  shars[2].initShar(100,200,40,4,5,3);
  shars[3].initShar(200,200,20,5,-7,-4);
  shars[4].initShar(400,300,25,2,-9,-1);
  shars[5].initShar(500,200,35,14,-5,-8);
  if (MaxShar>5) then}
 
  { инициализация шаров случайным образом }
  for i:=1 to MaxShar do
    begin
    r:=20+random(10);
    shars[i].initShar(1+r+random(GetMaxX-2*r),
      1+r+random(GetMaxY-2*r),r,1+random(GetMaxColor-1),
      random(15)-7,random(12)-6);
    end;
  { обсчитываем движение пока не нажата какая-либо клавиша }
  repeat
    { показываем все шары }
    for i:=1 to MaxShar do
      shars[i].Show;
    { временная задержка - установите свое значение для вашего компьютера }
    Delay(580);
    { убираем с экрана все шары }
    for i:=1 to MaxShar do
      shars[i].Hide;
    { просчитываем следующий шаг }
    for i:=1 to MaxShar do
      begin
      shars[i].Move;
      shars[i].CheckBorder;
      shars[i].CheckHit(i);
      end;
    for i:=1 to MaxShar do
      shars[i].hits:=[];
  until keyPressed;
  CloseGraph;
  close(f);
  end
end.

комп*ютер, сів... і не встав, бо затягує...
Offline Sergey K
UltraUser
*
Повідомлень: 2311
Карма: +5/-0
Стать: Чоловіча
WWW
  « Відповідь #4 : 12 Бер. 2010, 22:27:20 »
 
Дошка - це набір тих же пікселів, які стоять в один ряд, не змініють своє положення. Відбивають 100% прикладеної сили.
Offline andy
No avatar!
Новачок
*
Повідомлень: 39
не все так як є... як здається
Карма: +0/-0
Стать: Чоловіча
WWW
  « Відповідь #5 : 13 Бер. 2010, 15:58:33 »
 
Sergey K,   ну я це розумію. треба якусь функцію додати,  яку?  треба шо б ця дошка ще переміщалась вправо і в ліво.

комп*ютер, сів... і не встав, бо затягує...
Сторінок: [1] Нагору Друк 
Real MKClub Unofficial Community Комп’ютерний світ Програмування (Модератори: valxp, Jolly Roger) Тема: броунівський рух « попередня тема наступна тема »
Перейти в:  

Powered by SMF 1.1.11 | SMF © 2006, Simple Machines LLC
bigmir)net TOP 100