Dimentre
@Dimentre
Начинающий

В очередной раз графика в дельфи, как сделать поворот?

Доброго времени суток! В прошлый обращался на тостер с похожими проблемами с анимированием в делфи, теперь сложилась похожая ситуация. Программа категорически не хочет поворачивать рисунок, как бы я ни старался. Есть массив точек, с помощью polygon и polyline создаём рисунок. Затем пытаюсь измерить длину каждого отрезка в цикле и повернуть его на угол. Не могу понять где напутал. Помогите пожалуйста с решением!
Вот нужная часть кода:
var
  Form1: TForm1;
   x,y,dx,dy:integer;
   k:byte;
   p1:array[1..5] of tpoint;
   p2:array[1..5] of tpoint;

implementation
{$R *.dfm}

procedure tform1.ship(color,win:tcolor); // Создаём корабль
begin
with image1.canvas do
begin
pen.color:=color;
pen.width:=2;
brush.Color:=color;
brush.style:=bssolid;
//korpys
moveto(x,y);
//image1.Canvas.Polygon([point(x,y),point(x,y-3*dy),point(x+15*dx,y-3*dy),point(x+10*dx,y)]);
//rubka
//moveto(x+3*dx,y-3*dy);
//image1.Canvas.Polyline([point(x+3*dx,y-3*dy),point(x+3*dx,y-8*dy),point(x+8*dx,y-8*dy),point(x+8*dx,y-3*dy),point(x+3*dx,y-3*dy)]);
    p1[1].X :=x;       p1[1].y :=y;
    p1[2].X :=x;       p1[2].Y :=y-3*dy;
    p1[3].X :=x+15*dx; p1[3].Y :=y-3*dy;
    p1[4].X :=x+10*dx; p1[4].Y :=y;
    p1[5].X :=x;       p1[5].Y :=y;
      Polygon(p1);
    p2[1].X :=x+3*dx;       p2[1].y :=y-3*dy;
    p2[2].X :=x+3*dx;       p2[2].Y :=y-8*dy;
    p2[3].X :=x+8*dx;       p2[3].Y :=y-8*dy;
    p2[4].X :=x+8*dx;       p2[4].Y :=y-3*dy;
    p2[5].X :=x+3*dx;       p2[5].Y :=y-3*dy;
      polyline(p2);
end;
end;

procedure TForm1.Button5Click(Sender: TObject);  // Задаём координаты корабля с клавиатуры
begin
{x:=strtoint(inputbox('Значение Х','Введите значения X',''));
if x>image1.ClientWidth then
begin
showmessage('Превышает ширину рамки');
exit;
end;
y:=strtoint(inputbox('Значение Y','Введите значения Y',''));
if y>image1.Clientheight then
begin
showmessage('Превышает высоту рамки');
exit;
end;}
dx:=10;
dy:=10;
x:=image1.ClientWidth div 2;
y:=image1.Clientheight div 2;
ship(clred,clyellow);
end;

procedure tform1.ship2( color,win:tcolor); // Поворачиваем
const a=pi/2;
var i,x0,y0,x2,y2:integer;
begin
x0:=x+7*dx;
y0:=y-3*dy;
//image1.canvas.moveto(x0,y0);
image1.Canvas.brush.Color:=clwhite;
image1.Canvas.Rectangle(-5,-5,image1.ClientWidth+5,image1.ClientHeight+5);
for i:=1 to 5 do
begin

{x2:=round(sqrt(sqr(p1[i].x-x0)+sqr(p1[i].y-y0))*cos(a));
y2:=round(sqrt(sqr(p1[i].x-x0)+sqr(p1[i].y-y0))*sin(a));
p1[i].x:=x0+x2;
p1[i].y:=y0+y2;}
p1[i].x:=x0+round((p1[i].x-x0)*cos(a)+(p1[i].Y-y0)*sin(a));
p1[i].y:=y0+round((p1[i].y-y0)*cos(a)+(p1[i].x-x0)*sin(a));
end;
image1.Canvas.polygon(p1);
end;

procedure TForm1.Button11Click(Sender: TObject); //Процедура поворота
begin
ship2(clred,clyellow);
end;


До поворота:
d5c58695ee974b68a56108a0cdf5b258.png

После поворота:
e777d599d32d4776a8c11e2e3e909a64.png

Заранее благодарен за помощь!
  • Вопрос задан
  • 834 просмотра
Пригласить эксперта
Ответы на вопрос 1
@Mercury13
Программист на «си с крестами» и не только
Пока без возможности запустить программу вижу у тебя две проблемы.
1. Две ошибки в повороте. а) неверная матрица вращения; б) во второй строке поворота имеет дело с новым X, а не старым.
2. Подобные операции с целыми числами приводят к накоплению погрешностей; через несколько итераций кораблик быстро станет кособоким. С дробными, вообще-то, тоже, только не так быстро и есть шансы, что задачу выполним раньше, чем проблемы будут мало-мальски заметны.

По поводу качества кода — я бы сделал функцию
function RotateAround(const source, pivot : TPoint) : TPoint;
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы