Помощь - Поиск - Пользователи - Календарь
Полная версия: Найдите ошибку
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Neon6868
Задание: Построить три равносторонних треугольника, вращающихся вокруг одной из своих вершин. Эти вершины должны находиться на одинаковом расстоянии от центра экрана.

Треугольник строится не равносторонний!Подскажите почему? И подскажите как сделать вращение?
Программа:

  

Program Grafika;
  uses Graph,CRT;
  var
    x,y,x1,y1,x2,y2,x3,y3,a1,b1,a2,b2,a3,b3,c1,d1,c2,d2,c3,d3,r:integer;
  procedure GraphRezhim;
  var
    Driver,Mode,Error:integer;
  begin
    Driver:=detect;
    Initgraph(Driver,Mode,'D:\BGI');
    Error:=GraphResult;
    if Error<>grOk then writeln('GraphErrorMsg(Error)');
  end;
  procedure Vershini(var x1,y1,a1,b1,c1,d1:integer;x,y,r:integer);
  var
    coo:ArcCoordsType;
  begin
    Arc(x,y,0,90,r);
    GetArcCoords(coo);
    x1:=coo.Xend;
    y1:=coo.Yend;
    Arc(x,y,0,210,r);
    GetArcCoords(coo);
    a1:=coo.Xend;
    b1:=coo.Yend;
    Arc(x,y,0,330,r);
    GetArcCoords(coo);
    c1:=coo.Xend;
    d1:=coo.Yend;
    ClearDevice;
  end;
  procedure Treugolnik(var x1,y1,x2,y2,x3,y3:integer;x,y:integer);
  begin
    x:=round((GetMaxX div 10)*cos(2*pi*1/3));
    y:=round((GetMaxX div 10)*sin(2*pi*1/3));
    x1:=x1+x;
    y1:=y1+y;
    x:=round((GetMaxX div 10)*cos(2*pi*2/3));
    y:=round((GetMaxX div 10)*sin(2*pi*2/3));
    x2:=x1+x;
    y2:=y1+y;
    x:=round((GetMaxX div 10)*cos(2*pi*3/3));
    y:=round((GetMaxX div 10)*sin(2*pi*3/3));
    x3:=x2+x;
    y3:=y2+y;
    line(x1,y1,x2,y2);
    line(x3,y3,x1,y1);
    line(x2,y2,x3,y3);
  end;
  procedure Dvizhenie(x1,y1,x2,y2,x3,y3,
    a1,b1,a2,b2,a3,b3,c1,d1,c2,d2,c3,d3:integer);
  begin
    while not keypressed do
      begin
{Не знаю как сделать}
      end;
  end;
Begin
  GraphRezhim;
  Vershini(x1,y1,a1,b1,c1,d1,GetMaxX div 2,GetMaxY div 2,GetMaxY div 4);
  Treugolnik(x1,y1,x2,y2,x3,y3,x1,y1);
  Treugolnik(a1,b1,a2,b2,a3,b3,a1,b1);
  Treugolnik(c1,d1,c2,d2,c3,d3,c1,d1);
  readln;
End.
 
Neon6868
Так кто-нибудь знает в чем ошибка? Сам никак не могу найти!
volvo
Цитата
Треугольник строится не равносторонний!
Какой именно? Из вообще-то 3 строится, и (почему-то) у меня видно что они все 3 равносторонние...
Neon6868
Цитата(volvo @ 11.12.2007 21:37) *

Какой именно? Из вообще-то 3 строится, и (почему-то) у меня видно что они все 3 равносторонние...


Да, треугольника 3 и они на самом деле равносторонние. Я понял: на экране они показываются как неравносторонние из-за разрешения. А как мне сделать вращение этих треугольников вокруг одной из своих вершин? Я ниже сделал вращение одного треугольника, но не вокруг вершины! А как сделать вокруг вершины?


Program Grafika;
  uses Graph,CRT;
  var
    x,y,x1,y1,x2,y2,x3,y3,a1,b1,a2,b2,a3,b3,c1,d1,c2,d2,c3,d3,r,u,q,j:integer;
  procedure GraphRezhim;
  var
    Driver,Mode,Error:integer;
  begin
    Driver:=detect;
    Initgraph(Driver,Mode,'D:\BGI');
    Error:=GraphResult;
    if Error<>grOk then writeln('GraphErrorMsg(Error)');
  end;
  procedure Vershina(var x1,y1:integer;x,y,r,u:integer);
  var
    coo:ArcCoordsType;
  begin
    setcolor(0);
    Arc(x,y,0,u,r);
    GetArcCoords(coo);
    x1:=coo.Xend;
    y1:=coo.Yend;
    ClearDevice;
    Setcolor(14);
  end;
  procedure Treugolnik(var x1,y1,x2,y2,x3,y3:integer;x,y:integer);
  begin
    x:=round((GetMaxX div 10)*cos(2*pi*1/3));
    y:=round((GetMaxX div 10)*sin(2*pi*1/3));
    x1:=x1+x;
    y1:=y1+y;
    x:=round((GetMaxX div 10)*cos(2*pi*3/3));
    y:=round((GetMaxX div 10)*sin(2*pi*3/3));
    x3:=x1+x;
    y3:=y1+y;
    x:=round((GetMaxX div 10)*cos(2*pi*2/3));
    y:=round((GetMaxX div 10)*sin(2*pi*2/3));
    x2:=x3+x;
    y2:=y3+y;
    line(x1,y1,x2,y2);
    line(x3,y3,x1,y1);
    line(x2,y2,x3,y3);
  end;
Begin
  GraphRezhim;
  u:=90;
  q:=210;
  j:=330;
  while not keypressed do
    begin
  Vershina(x1,y1,GetMaxX div 2,GetMaxY div 2,GetMaxY div 4,u);
  Vershina(a1,b1,GetMaxX div 2,GetMaxY div 2,GetMaxY div 4,q);
  Vershina(c1,d1,GetMaxX div 2,GetMaxY div 2,GetMaxY div 4,j);
  Treugolnik(x1,y1,x2,y2,x3,y3,x1,y1);
  Treugolnik(a1,b1,a2,b2,a3,b3,a1,b1);
  Treugolnik(c1,d1,c2,d2,c3,d3,c1,d1);
  Delay(1000);
  u:=u+1;
  end;
  readln;
End.


volvo
Ну, вот так, скажем:
uses crt, graph;

type
  polar = record
    phi, r: integer;
  end;
  tri = record
    cx, cy: integer;
    pts: array[1 .. 3] of polar;
  end;

procedure show_triangle(const T: tri);

  procedure line(p1, p2: integer);
  begin
    graph.line(
      T.cx + trunc(T.pts[p1].r * cos(T.pts[p1].phi * pi / 180)),
      T.cy - trunc(T.pts[p1].r * sin(T.pts[p1].phi * pi / 180)),
      T.cx + trunc(T.pts[p2].r * cos(T.pts[p2].phi * pi / 180)),
      T.cy - trunc(T.pts[p2].r * sin(T.pts[p2].phi * pi / 180))
    );
  end;

begin
  line(1, 2);
  line(1, 3);
  line(2, 3);
end;

procedure rotate(var T: tri);
var i: integer;
begin
  for i := 1 to 3 do begin
    inc(T.pts[i].phi, 5);
    if T.pts[i].phi > 360 then dec(T.pts[i].phi, 360);
  end;
  show_triangle(T);
end;

procedure graphix;
var dr, mode, error: integer;
begin
  dr := detect;
  initgraph(dr, mode, '');
  error := graphresult;
  if error <> grOk then writeln(grapherrormsg(error));
end;


var
  i, R, angle: integer;
  figures: array[1 .. 3] of tri;

begin
  graphix;

  R := getmaxy div 4;
  angle := 90;
  for i := 1 to 3 do
    with figures[i] do begin
      cx := (getmaxx div 2) + trunc(R * cos((angle + pred(i) * 120) * pi / 180));
      cy := (getmaxy div 2) - trunc(R * sin((angle + pred(i) * 120) * pi / 180));
      pts[1].phi := 0; pts[1].r := 0;
      pts[2].phi := 240; pts[2].r := 50;
      pts[3].phi := 300; pts[3].r := 50;
    end;

  while not keypressed do begin
    cleardevice;
    for i := 1 to 3 do rotate(figures[i]);
    delay(1000);
  end;

  readln;
  closegraph;
end.

rolleyes.gif
Neon6868
Спасибо за программу. Но напиши лучше формулу, по которой определяются координаты вершин треугольников при повороте? Я в твоей программе не могу понять где это!
volvo
В моей программе вершины хранятся в полярной системе координат. При этом одна из них (P1, вокруг которой будет происходить вращение) является центром этой самой системы: P1 = (0, 0), а две другие, соответственно, инициализируются значениями P2 = (240, r) и P3 = (300, r), что означает "угол P2P1P3 = 60 градусов, и 2 одинаковых ребра => треугольник P1P2P3 - равносторонний"

Ну, а для вращения точки, заданной в полярной системе координат (относительно центра, которым является точка P1), достаточно элементарно увеличить угол phi у всех трех вершин... Вот и все, пожалуй smile.gif
Neon6868
Я нашел формулу, по которой надо вычислять новые координаты после поворота треугольников! Но с ней почему-то треугольник не вращается как надо! Все вроде правильно сделал. Подскажите плз почему?

 
Program Grafika;
  uses Graph,CRT;
  var
    x,y,x1,y1,x2,y2,x3,y3,a1,b1,a2,b2,a3,b3,c1,d1,c2,d2,c3,d3,r,u,q,j,i:integer;
  procedure GraphRezhim;
  var
    Driver,Mode,Error:integer;
  begin
    Driver:=detect;
    Initgraph(Driver,Mode,'D:\BGI');
    Error:=GraphResult;
    if Error<>grOk then writeln('GraphErrorMsg(Error)');
  end;
  procedure Vershina(var x1,y1:integer;x,y,r,u:integer);
  var
    coo:ArcCoordsType;
  begin
    setcolor(0);
    Arc(x,y,0,u,r);
    GetArcCoords(coo);
    x1:=coo.Xend;
    y1:=coo.Yend;
    ClearDevice;
    Setcolor(14);
  end;
  procedure Treugolnik(var x1,y1,x2,y2,x3,y3:integer;x,y:integer);
  begin
    x:=round((GetMaxX div 10)*cos(2*pi*1/3));
    y:=round((GetMaxX div 10)*sin(2*pi*1/3));
    x1:=x1+x;
    y1:=y1+y;
    x:=round((GetMaxX div 10)*cos(2*pi*3/3));
    y:=round((GetMaxX div 10)*sin(2*pi*3/3));
    x3:=x1+x;
    y3:=y1+y;
    x:=round((GetMaxX div 10)*cos(2*pi*2/3));
    y:=round((GetMaxX div 10)*sin(2*pi*2/3));
    x2:=x3+x;
    y2:=y3+y;
    line(x1,y1,x2,y2);
    line(x3,y3,x1,y1);
    line(x2,y2,x3,y3);
  end;
  procedure Dvizhenie(var x1,y1,x2,y2,x3,y3,i:integer);
    begin
      x1:=round(x1*cos(i)+y1*sin(i));
      y1:=round(-x1*sin(i)+y1*cos(i));
      x3:=round(x3*cos(i)+y3*sin(i));
      y3:=round(-x3*sin(i)+y3*cos(i));
      line(x1,y1,x2,y2);
      line(x3,y3,x1,y1);
      line(x2,y2,x3,y3);
    end;
Begin
  GraphRezhim;
  Vershina(x1,y1,GetMaxX div 2,GetMaxY div 2,GetMaxY div 4,90);
  Vershina(a1,b1,GetMaxX div 2,GetMaxY div 2,GetMaxY div 4,210);
  Vershina(c1,d1,GetMaxX div 2,GetMaxY div 2,GetMaxY div 4,330);
  Treugolnik(x1,y1,x2,y2,x3,y3,x1,y1);
  Treugolnik(a1,b1,a2,b2,a3,b3,a1,b1);
  Treugolnik(c1,d1,c2,d2,c3,d3,c1,d1);
  while not keypressed do
    begin
      ClearDevice;
      Dvizhenie(x1,y1,x2,y2,x3,y3,i);
  Delay(60000);
  i:=i+1;
  u:=u+1;
  end;
  readln;
End.

Neon6868
Ответьте кто-нибудь...
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.