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

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

Форум «Всё о Паскале» _ Задачи _ Найдите ошибку

Автор: Neon6868 12.12.2007 0:25

Задание: Построить три равносторонних треугольника, вращающихся вокруг одной из своих вершин. Эти вершины должны находиться на одинаковом расстоянии от центра экрана.

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

  

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 12.12.2007 1:30

Так кто-нибудь знает в чем ошибка? Сам никак не могу найти!

Автор: volvo 12.12.2007 1:37

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

Автор: Neon6868 12.12.2007 5:05

Цитата(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 12.12.2007 5:47

Ну, вот так, скажем:

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 13.12.2007 23:21

Спасибо за программу. Но напиши лучше формулу, по которой определяются координаты вершин треугольников при повороте? Я в твоей программе не могу понять где это!

Автор: volvo 13.12.2007 23:31

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

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

Автор: Neon6868 13.12.2007 23:38

Я нашел формулу, по которой надо вычислять новые координаты после поворота треугольников! Но с ней почему-то треугольник не вращается как надо! Все вроде правильно сделал. Подскажите плз почему?

 
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 14.12.2007 4:26

Ответьте кто-нибудь...