Как построить график функции, заданной параметрически?
{$n+}
type
tcurve = procedure(t: double;
var x, y: double);
const
scale = ... ; { масштаб изображения }
{
Процедура для отрисовки точки кривой,
параметрическое представление которой задано функцией F
при значении параметра = T
}
procedure set_point(t: double; f: tcurve);
var
x, y: double;
begin
f(t, x, y);
putpixel( (getmaxx div 2) + trunc(scale * x),
(getmaxy div 2) - trunc(scale * y), white );
end;
{
Отрисовка кривой со значениями параметра,
лежащими в интервале [start, finish] и шагом изменения параметра step
}
procedure draw_curve(start, finish, step: double;
f: tcurve);
var t: double;
begin
{ отрисовываем оси координат }
setcolor(green);
line(0, getmaxy div 2, getmaxx, getmaxy div 2);
line(getmaxx div 2, 0, getmaxx div 2, getmaxy);
t := start; { начало интервала }
{ пока не вышли за границу интервала }
while t <= finish do begin
set_point(t, f);
t := t + step; { наращиваем параметр }
end;
end;
{ Пример использования: }
begin
{ Инициализируем графику... }
draw_curve({начало интервала}, {конец интервала}, {шаг}, my_curve);
readln;
{ Закрываем графику }
end.
В качестве параметра в процедуру отрисовки может быть передана процедура вида:
{ Процедура должна компилироваться с директивой FAR }
procedure my_curve(t: double; var x, y: double); far;
begin
x := ... ; { задание кривой }
y := ... ;
end;
Примеры кривых, полученных с использованием приведенной функции draw_curve приведены ниже. Для всех примеров
(если не указано отдельно) принимались следующие значения A, B, L и scale:
const a = 3; b = 9; L: double = 4; scale = 12; step = 0.005;
Исходник: curves.pas
procedure semi_cubic(t: double; var x, y: double); far;
begin
x := sqr(t);
y := a * sqr(t) * t;
end;
...
{ Вызов: }
draw_curve(-10, 10, step, semi_cubic);
procedure decart(t: double; var x, y: double); far;
begin
x := 3 * a * t / (1 + t * sqr(t));
y := 3 * a * sqr(t) / (1 + t * sqr(t));
end;
...
{ Вызов (двойной, т.к. в точке (-1) значение не определено): }
draw_curve(-10, -1-step, step, decart);
draw_curve(-1+step, 10, step, decart);
procedure cissoide(t: double; var x, y: double); far;
begin
x := a * sqr(t) / (1 + sqr(t));
y := a * t * sqr(t) / (1 + sqr(t));
end;
...
{ Вызов: }
draw_curve(-10, 10, step, cissoide);
procedure strophoide(t: double; var x, y: double); far;
begin
x := a * (sqr(t) - 1) / (sqr(t) + 1);
y := a * t * (sqr(t) - 1) / (sqr(t) + 1);
end;
...
{ Вызов: }
draw_curve(-10, 10, step, strophoide);
procedure conhoide(t: double; var x, y: double); far;
begin
x := a + L * cos(t);
y := a * sin(t) / cos(t) + L * sin(t)
end;
...
{ Вызов: }
draw_curve(-pi/2+step, pi/2-step, step, conhoide); { правая ветвь }
draw_curve(pi/2+step, 3*pi/2-step, step, conhoide); { левая ветвь }
procedure ulitka(t: double; var x, y: double); far;
begin
x := a * sqr(cos(t)) + l * cos(t);
y := a * cos(t) * sin(t) + l * sin(t);
end;
...
{ Вызов: }
draw_curve(0, 2*pi-step, step, ulitka);
procedure cardioide(t: double; var x, y: double); far;
begin
x := a * cos(t) * (1 + cos(t));
y := a * sin(t) * (1 + cos(t));
end;
...
{ Вызов: }
draw_curve(0, 2*pi-step, step, cardioide);
Циклоиды, спирали, эвольвенты:
procedure cycloide(t: double; var x, y: double); far;
begin
x := a * (t - L * sin(t));
y := a * (1 - L * cos(t));
end;
...
{ Вызов: }
cleardevice; L := 1; { Обычная }
draw_curve(-10, 10, step, cycloide);
readln;
cleardevice; L := 0.3; { Укороченная }
draw_curve(-10, 10, step, cycloide);
readln;
cleardevice; L := 3; { Удлиненная }
draw_curve(-10, 10, step, cycloide);
readln;
procedure epi_cycloide(t: double; var x, y: double); far;
begin
x := (a + B) * cos(t) - L * a * cos((a + B)*t / a);
y := (a + B) * sin(t) - L * a * sin((a + B)*t / a);
end;
...
{ Вызов: }
cleardevice; L := 1; { Обычная }
draw_curve(-10, 10, step, epi_cycloide);
readln;
cleardevice; L := 0.3; { Укороченная }
draw_curve(-10, 10, step, epi_cycloide);
readln;
cleardevice; L := 3; { Удлиненная }
draw_curve(-10, 10, step, epi_cycloide);
readln;
procedure hypo_cycloide(t: double; var x, y: double); far;
begin
x := (b - a) * cos(t) + L * a * cos((b - a)*t / a);
y := (b - a) * sin(t) - L * a * sin((b - a)*t / a);
end;
...
{ Вызов: }
cleardevice; L := 1; { Обычная }
draw_curve(-10, 10, step, hypo_cycloide);
readln;
cleardevice; L := 0.3; { Укороченная }
draw_curve(-10, 10, step, hypo_cycloide);
readln;
cleardevice; L := 3; { Удлиненная }
draw_curve(-10, 10, step, hypo_cycloide);
readln;
procedure hyp_spiral(t: double; var x, y: double); far;
begin
x := a * cos(t)/t;
y := a * sin(t)/t;
end;
...
{ Вызов: }
draw_curve(-10, -step, step, hyp_spiral); { ветка влево }
draw_curve(step, 10, step, hyp_spiral); { ветка вправо }
procedure evolventa(t: double; var x, y: double); far;
begin
x := a * cos(t) + a * t * sin(t);
y := a * sin(t) - a * t * cos(t);
end;
...
{ Вызов: }
draw_curve(-10, 10, step, evolventa);