Canvas.Pen.Style:= psSolid;
Canvas.Pen.Width:= 1;
Canvas.Pen.Color:= clBlue;
Canvas.MoveTo(X–CurveForm.FDX, Y — CurveForm.FDY);
Canvas.LineTo(X + CurveForm.FDX, Y + CurveForm.FDY);
end;
// Плакатное перо
2: begin
Canvas.Pen.Style:= psSolid;
// Предположим, некоторая точка прямой имеет координаты (X, Y),
// а соседняя с ней — координаты (Х+1, Y-1). Тогда при проведении
// через эти точки наклонной линии одинарной ширины между ними
// останутся незаполненные точки, как на шахматной доске.
// Поэтому потребовалось увеличить толщину пера
Canvas.Pen.Width:= 2;
Canvas.Pen.Color:= clBlack;
Canvas.MoveTo(X — 5, Y — 5);
Canvas.LineTo(X + 6, Y + 6);
end;
// Цепочка
3: begin
case CurveForm.FCounter mod 15 of
0: begin
Canvas.Pen.Style:= psSolid;
Canvas.Pen.Width:= 1;
Canvas.Pen.Color:= clBlack;
Canvas.Brush.Style:= bsClear;
Canvas.Ellipse(X — 5, Y — 5, X + 6, Y + 6);
end;
2..13: Canvas.Pixels[X, Y]:= clBlack;
end;
end;
end;
Inc(CurveForm.FCounter);
end;
procedure TCurveForm.DrawCurve(Canvas: TCanvas);
var
LCurve: TCurve;
I, Size: Integer;
PtBuf: array of TPoint;
TpBuf: array of Byte;
L: Extended;
begin
// LCurve хранит координаты начала и конца кривой и ее
// опорных точек. Если включен режим рисования по опорным
// точкам, LCurve совпадает с FCurve, если включен режим
// рисования по точкам кривой, опорные точки LCurve[1]
// и LCurve[2] рассчитываются по приведенным в книге
// формулам на основании точек FCurve
LCurve:= FCurve;
if RGroupDrawMethod.ItemIndex = 1 then
begin
LCurve[1].X:=
Round((-5 * FCurve[0].X + 18 * FCurve[1].X -
9 * FCurve[2].X + 2 * FCurve[3].X) / 6);
LCurve[1].Y:=
Round((-5 * FCurve[0].Y + 18 * FCurve[1].Y -
9 * FCurve[2].Y + 2 * FCurve[3]-Y) / 6);
LCurve[2].X:=
Round((2 * FCurve[0].X — 9 * FCurve[1].X +
18 * FCurve[2].X — 5 * FCurve[3].X) / 6);
LCurve[2].Y:=
Round((2 * FCurve[0].Y — 9 * FCurve[1].Y +
18 * FCurve[2].Y — 5 * FCurve[3].Y) / 6);
end;
// Создаем траекторию на основе кривой
BeginPath(Canvas.Handle);
Canvas.PolyBezier(LCurve);
EndPath(Canvas.Handle);
// Аппроксимируем траекторию отрезками прямых
FlattenPath(Canvas.Handle);
// Получаем число точек траектории. Так как сами точки никуда
// пока не копируются, в качестве фиктивного буфера можно указать
// любую переменную. В данном случае — переменную I
Size:= GetPath(Canvas.Handle, I, I, 0);
// Выделяем память для хранения координат и типов точек траектории
SetLength(PtBuf, Size);
SetLength(TpBuf, Size);
// Получаем координаты и типы точек. Типы точек нас в данном случае
// не интересуют: у первой точки будет тип PT_MOVETO,