Помощь - Поиск - Пользователи - Календарь
Полная версия: Движение точки по линии
Форум «Всё о Паскале» > Pascal, Object Pascal > Написание игр
pashist
Привет=) Есть линия, начало которой привязано к центру координат(х1, у1=320, 240), направленная под произвольным углом α. Нужно, чтобы черная точка прошла по всей белой линии, не выходя за её пределы толщины. Толщина точки равна толщине линии. Как это реализовать?
klem4
Из заданных 2-х точек прямой (центр и (x1, y1)) получаешь уравнения прямой - F(x).

Ну а далее все просто, в цикле по Х от Х(центра) до X1 выводи точку с координатами (x, F(x));
pashist
unsure.gif А можно код?
volvo
Цитата
Из заданных 2-х точек прямой (центр и (x1, y1)) получаешь уравнения прямой - F(x).
А я бы перешел в полярную систему координат... И не надо заморочек с функциями, просто увеличивать расстояние от центра до точки при заданном угле blum.gif
klem4
Можно и так smile.gif

В общем вот набросок. Для наглядности отрисовывается маленькая окружность вместо точки. И через некоторый промежуток.

uses Crt, Graph;

function F(x: Integer) : Integer;
begin
F := round(3/4 * x);
end;

var

gd, gm: Integer;

x: Integer;

begin

gd := Detect;

InitGraph(gd, gm, '');


line(0, 0, 320, 240);

SetColor(Red);

x := 0;

while (x <= 320) do begin
circle(x, F(x), 2);
delay(300);
inc(x, 20);
end;

readkey;

end.


pashist
Написал, но работает только в частном случае..( По-моему, неправильно высчитывается F(x):
Uses Graph,Crt;
Function F(x: Integer): Integer;
Begin
F:=Round(3/4*x);
End;
Var GD,GM: Integer;
x: Integer;
Begin
GD:=Detect;
InitGraph(GD,GD,'');
Line(320,240,640,480);
ReadLn;
SetColor(Red);
x:=320;
While (x<400) Do
Begin
PutPixel(x,F(x),Red);
Delay(30000);
inc(x,20);
End;
Readln
End.

Нужно, чтобы система координат начиналась в центре экрана (320, 240).
klem4
Уравнени у меня рассчитано для прямой проходящей через точки с координатами [(0, 0) ; (320, 240)] так я понял надо по заданию. Если тебе нужа универсальная программа, поищи по форуму или сам выведи как получить уравнение прямой заданной по двум точка [(x1, y1); (x2, y2)]

Вот формула :

(x - x1) / (x2 - x1) = (y - y1) / (y2 - y1)
Бродяжник
Может я чего не понимаю, но
Цитата
Нужно, чтобы черная точка прошла по всей белой линии, не выходя за её пределы толщины.

Так? Если рассматривать эту задачу не геометрически, а в приложении к растру монитора, то ведь у нас может быть не одна точка с координатой Х = Xi, а несколько (если прямая наклонена под углом более 45 градусов). Поэтому простой цикл по Х с вычислением Y=f(X) не проходит. Лучше использовать алгоритм Брезенхама и для вычерчивания самой линии и для последующего скольжения точки.
Гость
Если так, то можно допустить некоторое отклонение от линии
pashist
Цитата
Вот формула :
(x - x1) / (x2 - x1) = (y - y1) / (y2 - y1)


uses graph,crt;
const x1=320;
y1=240;
x2=500;
y2=400;
function F(x: Integer): Integer;
begin
f:=round( ((x-x1)/((x2-x1)*(y2-y1)))+y1 );
end;
Var gd,gm,x,i: Integer;
begin
gd:=detect;
initgraph(gd,gm,'');
line(x1,y1,x2,y2);
x:=340;
for i:=1 to 20 do
begin
putpixel(x,f(x),red);
inc(x,20);
delay(30000)
end;
readln
end.

Почему F(x) все время выдает одно и то же значение? nea.gif
volvo
Ну, наверное, потому, что функция написана неправильно?
function F(x: Integer): integer;
begin
f:=round((x-x1)*(y2-y1)/(x2-x1)) + y1;
end;

Почему ты делил на (y2 - y1), когда нужно умножать?
pashist
Уряяяя!!!!! Спасибо! good.gif
pashist
Кадр 11 дубль 2.. Почему функция работает некорректно? Если задать в констнтах x2=639, y2=479, то точка во время движения на полпути резко смещается по y примерно на 100 пикселей вверх! В чем дело?
volvo
Смотря, что ты еще изменял. У меня, например, выдает вот такие значения:
       340       255
360 270
380 285
400 300
420 315
440 330
460 345
480 360
500 375
520 390
540 405
560 420
580 435
600 450
620 465
640 480
660 495
680 510
700 525
720 540

(первый столбец - X, второй - Y)... Как видишь, никакого скачка.


P.S.
Отставить мой предыдущий пост. Он просто еще раз показывает преимущество 32-битных компиляторов. У тебя по ходу вычисления происходит переполнение. Промежуточный результат не помещается в Integer, и как результат - усечение...

Вот патч:
function F(x: Integer): integer;
begin
f:=round(LongInt(x-x1)*(y2-y1)/(x2-x1)) + y1;
end;
pashist
Еще вопрос, в тему. Есть прямая, которая крутится, начало которой закреплено в центре экрана: x1=320, y1=240. Длина прямой-20. Как найти координаты x2, y2, которые являются продолжением этой прямой до границы экрана? Нужно получить уравнение этой прямой.
klem4
Цитата
прямая, которая крутится


Ты имеешь в виду, второй конец прямой движется по окружности ?
pashist
Цитата
Ты имеешь в виду, второй конец прямой движется по окружности ?

Да. Управление с клавиатуры.
klem4
Ну тогда соклько раз можно повторять одно и тоже.

Поиск -> "Движение окружности", "Маятник" , "Система маятников"
pashist
Нет, смысл не в этом. Дописываю курсовик, там в центре экрана стоит охотник и стреляет в мышек. Когда охотник правильно прицелился на мышку, тогда понятно, в какую конечную точку летит пуля-в точку координаты мышки. А если он прицелен неправильно? Куда тогда должна лететь пуля? Ружьё охотника-это прямая, которая движется по окружности, и координаты для функции рисования прямой есть: x1,y1,x2,y2, где x1,y1=320,240. То бишь нужно найти продолжение этой прямой до границы экрана, найти ту точку на границе экрана, в которую должна лететь пуля (по траектории прямой) при промахе охотника.
volvo
Я тебе предлагал перейти в полярную систему координат, в которой этой проблемы вообще не возникло бы? Предлагал. Ты не захотел? Не захотел...

Вот и сиди, мучайся...
pashist
Как перейти к полярной системе координат? У меня весь курсовик ориентирован на начало координат в центре экрана! Много нужно переписывать?
Бродяжник
Если это та прога про охоту на мышек, с которой я когда-то даже чуток помогал, то ведь там уже и есть полярная система! Там нажатиями на клавиши меняется угол направления ружья, а само ружье рисуется, как линия между двумя точками - началом координат (центром экрана) и точкой, координаты которой вычисляются, исходя из угла поворота ружья и длины ствола. Аналогичным образом координаты пули в каждый момент можно вычислить, исходя из все того же самого угла поворота ружья и расстояния, которое пролетела пуля от центра экрана. В цикле увеличиваем это расстояние и вычисляем новые положения пули, пока она не улетит за экран. Могу накидать примерчик, но не сегодня.
Удачи!
pashist
Бродяжник, СПАСИБО!! Всё сделал, всё работает smile.gif
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.