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

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

Форум «Всё о Паскале» _ Задачи _ Угол

Автор: Shaienn 14.02.2003 17:51

Здравствуйте программеры...
Подскажите, если кто сталкивался, как реализовать в графической программе правило "Угол падения равен углу отражения"... Вот сижу, думаю, а ничего не идет..

Автор: Some1 15.02.2003 4:34

Ну что значит как реализовать задачу ? В каком виде реализовать ? Угол падения чего и куда ?
Если у тебя по условию заданы прямые, то должны быть заданы уравнения прямых. (Той, по которой идёт "луч" и той, от которой отражается)...

Автор: ___ALex___ 15.02.2003 19:29

вот посмотри этот код.
условие задачи: две точки движутся в разных направлениях упруго отражаясь от краёв экрана
при этом движется линия их соединяющая. Удачи

Код

program Lab2;
uses Crt, Graph, Dos;
type
 NaprType = (lup, ldown, rup, rdown);
var
 GrDriver, GrMode, ErrCode: Integer;
 x1, y1, x2, y2: Integer;
 NaprP1, NaprP2: NaprType;
 h, m, s, s100, sec: Word;

procedure SelectNapr(var Napr1, Napr2: NaprType);
begin

 case Random(4) of
  0: Napr1 := lup;
  1: Napr1 := ldown;
  2: Napr1 := rup;
  3: Napr1 := rdown;
 end;

 case Random(4) of
  0: Napr2 := lup;
  1: Napr2 := ldown;
  2: Napr2 := rup;
  3: Napr2 := rdown;
 end;

 if Napr1 = Napr2 then SelectNapr(Napr1, Napr2);

end;

procedure MovPoint(var x, y: Integer; var Napr: NaprType);
begin

 case Napr of
  lup     : begin x := x - 2; y := y - 1; end;
  ldown   : begin x := x - 2; y := y + 1; end;
  rup     : begin x := x + 2; y := y - 1; end;
  rdown   : begin x := x + 2; y := y + 1; end;
 end;

if x <= 0 then
 begin
  case Napr of
   lup  : Napr := rup;
   ldown: Napr := rdown;
  end;
  MovPoint(x, y, Napr);
 end else
if y <= 0 then
 begin
  case Napr of
   lup: Napr := ldown;
   rup: Napr := rdown;
  end;
  MovPoint(x, y, Napr);
 end else
if x >= 639 then
 begin
  case Napr of
   rup  : Napr := lup;
   rdown: Napr := ldown;
  end;
  MovPoint(x, y, Napr);
 end else
if y >= 479 then
 begin
  case Napr of
   ldown: Napr := lup;
   rdown: Napr := rup;
  end;
  MovPoint(x, y, Napr);
 end;

end;

Begin

 ClrScr;
 GrDriver := VGA;
 GrMode := VGAHi;
 InitGraph(GrDriver, GrMode, 'C:TPBGI');
 ErrCode := GraphResult;
 if ErrCode <> grOk then
  begin
   Write('Ошибка инициализации графики: ', GraphErrorMsg(ErrCode));
   repeat until KeyPressed;
   Halt(0);
  end;

 Randomize;
 x1 := Random(GetMaxX + 1);
 y1 := Random(GetMaxY + 1);
 x2 := Random(GetMaxX + 1);
 y2 := Random(GetMaxY + 1);
 SelectNapr(NaprP1, NaprP2);
 GetTime(h, m, s, s100);
 sec := s;
 SetColor(Random(GetMaxColor) + 1);
 SetWriteMode(XorPut);

 repeat
  GetTime(h, m, s, s100);
  if sec <> s  then
   begin
    sec := s;
    SetColor(Random(GetMaxColor) + 1);
   end;
  Line(x1, y1, x2, y2);
  Delay(50);
  Line(x1, y1, x2, y2);
  MovPoint(x1, y1, NaprP1);
  MovPoint(x2, y2, NaprP2);
 until KeyPressed;

 CloseGraph;

End.

Автор: Shaienn 15.02.2003 20:10

Вы меня маленько не поняли...
Задача такая, летит шарик, ударяется о стенку и отражается... Под каким углом ударился, под таким и отражается и летит до другой стенки...и т.д.

Всем спасибо

Автор: dark0ut 15.02.2003 23:01

Ну это вот так:
здесь даже цвет менять можно smile.gif

Код

uses crt,graph;
var
 gd,gm:integer;
 x,y,r,metod:integer;
 minx,miny,maxx,maxy:integer;
 ch:char;
 zvetm,zvetgr:integer;
 pause:integer;

begin
 gd:=detect;
 initGraph(gd,gm,'D:bpbgi');

 delay(10000);

 zvetgr:=1;

 x:=320;
 y:=240;
 metod:=0;

 minx:=0;
 miny:=0;
 maxx:=639;
 maxy:=479;

 r:=10;

 pause:=150;

 setcolor(zvetgr);
 line(minx,0,minx,480);
 line(maxx,0,maxx,480);
 line(0,miny,640,miny);
 line(0,maxy,640,maxy);

 zvetm:=14;


 while ch<>#27 do
 begin
   setcolor(zvetgr);
   line(minx,0,minx,480);
   line(maxx,0,maxx,480);
   line(0,miny,640,miny);
   line(0,maxy,640,maxy);


   setcolor(zvetm);
   circle(x,y,r);
   delay(pause);
   setcolor(0);
   circle(x,y,r);

   if (metod=0) then
   begin
     x:=x+1;
     y:=y+1;
   end;
   if (metod=1) then
   begin
     x:=x+1;
     y:=y-1;
   end;
   if (metod=2) then
   begin
     x:=x-1;
     y:=y-1;
   end;
   if (metod=3) then
   begin
     x:=x-1;
     y:=y+1;
   end;

   if (x<=minx+r+1) and (metod=2) then metod:=1;
   if (x<=minx+r+1) and (metod=3) then metod:=0;
   if (x>=maxx-r-1) and (metod=1) then metod:=2;
   if (x>=maxx-r-1) and (metod=0) then metod:=3;
   if (y<=miny+r+1) and (metod=1) then metod:=0;
   if (y<=miny+r+1) and (metod=2) then metod:=3;
   if (y>=maxy-r-1) and (metod=3) then metod:=2;
   if (y>=maxy-r-1) and (metod=0) then metod:=1;

   if keypressed then ch:=readkey;


   if (ch='+') and (r<230) and ((2*r)<(maxx-minx-5)) and ((2*r)<(maxy-miny-10)) then
   begin
     r:=r+5;
     ch:=#0;
   end;
   if (ch='-') and (r>10) and ((2*r)<(maxx-minx)) and ((2*r)<(maxy-miny-10)) then
   begin
     r:=r-5;
     ch:=#0;
   end;

   if (ch='a') and ((minx+10)<maxx) and ((2*r)<(maxx-minx-10)) and (minx<640-2*r) and ((x-r)>minx+10)

then
   begin
     setcolor(0);
     line(minx,0,minx,480);
     minx:=minx+10;
     setcolor(zvetgr);
     line(minx,0,minx,480);
     ch:=#0;
   end;
   if (ch='d') and ((maxx-10)>minx) and ((2*r)<(maxx-minx-10)) and (maxx>2*r) and ((x+r)<maxx-10) then
   begin
     setcolor(0);
     line(maxx,0,maxx,480);
     maxx:=maxx-10;
     setcolor(zvetgr);
     line(maxx,0,maxx,480);
     ch:=#0;
   end;
   if (ch='w') and ((miny+10)<maxy) and ((2*r)<(maxy-miny-10)) and (miny<480-2*r) and ((y-r)>miny+10)

then
   begin
     setcolor(0);
     line(0,miny,640,miny);
     miny:=miny+10;
     setcolor(zvetgr);
     line(0,miny,640,miny);
     ch:=#0;
   end;
   if (ch='x') and ((maxy-10)>miny) and ((2*r)<(maxy-miny-10)) and (maxy>2*r) and ((y+r)<maxy-10) then
   begin
     setcolor(0);
     line(0,maxy,640,maxy);
     maxy:=maxy-10;
     setcolor(zvetgr);
     line(0,maxy,640,maxy);
     ch:=#0;
   end;

   if (ch='8') and (miny>0) then
   begin
     setcolor(0);
     line(0,miny,640,miny);
     miny:=miny-10;
     setcolor(zvetgr);
     line(0,miny,640,miny);
     ch:=#0;
   end;

   if (ch='2') and (maxy<470) then
   begin
     setcolor(0);
     line(0,maxy,640,maxy);
     maxy:=maxy+10;
     setcolor(zvetgr);
     line(0,maxy,640,maxy);
     ch:=#0;
   end;


   if (ch='4') and (minx>0) then
   begin
     setcolor(0);
     line(minx,0,minx,480);
     minx:=minx-10;
     setcolor(zvetgr);
     line(minx,0,minx,480);
     ch:=#0;
   end;


   if (ch='6') and (maxx<630) then
   begin
     setcolor(0);
     line(maxx,0,maxx,480);
     maxx:=maxx+10;
     setcolor(zvetgr);
     line(maxx,0,maxx,480);
     ch:=#0;
   end;

   if (ch=']') and (zvetm<14) then
   begin
     zvetm:=zvetm+1;
     ch:=#0;
   end;
   if (ch='[') and (zvetm>1) then
   begin
     zvetm:=zvetm-1;
     ch:=#0;
   end;

   if (ch=',') and (pause>10) then
   begin
     pause:=pause-10;
     ch:=#0;
   end;

   if (ch='.') and (pause<1000) then
   begin
     pause:=pause+10;
     ch:=#0;
   end;

 end;

 closegraph;
end.

Автор: Some1 16.02.2003 5:22

Может ему нужна более математическая выкладка.. не только частный случай, когда угол падения равен 45o, а и при других углах.
Тогда надо читать мой первый пост.
У тебя есть две прямые - одна - по какой летит шарик.
Другая - об которую он должен удариться.
Т.е. фактически прямых у тебя может и не быть. Нужны не прямые а их формулы.
Формулу прямой можно найти скажем по двум точкам.
(через две точки ведь можно провести прямую).
Следовательно, скажем достаточно взять две точки из пути твоего шарика, и по ним вычислить формулу одной прямой. Но лучше вычислить её исходя из коэфициентов, которые ты прибавляешь к координатам шарика. Потом взять две точки поверхности, об которую будет ударяться шарик, и вычислить формулу второй прямой. После этого найти их точку пересечения A(x,y) и угол между ними Alpha.
И, наконец, вычислить формулу другой прямой, угол между которой и прямой об которую ударяется шарик будет иметь противоположный знак угла Alpha, и которая тоже будет проходить через точку A(x,y). Исходя из найденой формулы прямой можно будет вычислить коофициенты, которые надо будет прибавлять к координатам шарика, чтобы двигать его по найденой прямой.

Если тебе всё это кажется запутанным, я могу разжевать...

Автор: dark0ut 18.02.2003 1:38

ты лучше мне разжуй ;D

Автор: Ricoshet 20.02.2003 21:59

Короче как сделать отскок: ты задаешь движение не
x:=x+1 а x:=x+j и y:=y+j1 . А потом обрабатываешь условия при касании каждой стенки:при касании боковой стенки меняешь j:=-j а верхней на j1:=-j1.
Если че брось сообщение в форум исходник пришлю

Автор: Some1 21.02.2003 13:25

Ну это тоже частный случай - для отскока от горизонтальновертикальных прямых. От косых такое работать не будет.

Автор: ___ALex___ 21.02.2003 17:40

чё вы тут фигню какую-то развели?
парню надо было зеркальное отражение)то бишь угол падения равен углу отражения)луч падает при этом на горизонталь(границы экрана)
зачем ему отражения от других "поверхностей"?!

Автор: ___ALex___ 21.02.2003 17:42

отражение при падении на горизонать/вертикаль конечно просто в нете пишу и поэтому тороплюсь...

Автор: Some1 22.02.2003 14:59

Цитата
...луч падает при этом на горизонталь(границы экрана)
зачем ему отражения от других "поверхностей"?
Это ты с чего такое взял ? он что, написал так ?
Вопрос звучал в общем, я пытаюсь ответить в общем smile.gif для всех случаев.
Ну если от горизонталь/вертикали, то конечно всё просто. Тут я и не спорю smile.gif

З.Ы. Может он пишет нетривиальный арканоид, с отражениями от наклонных поверхностей ?