График рисуется неверно

При работе следующего кода почему-то получается неверный график:

procedure TForm1.Button1Click(Sender: TObject);
const
x1 = -10;
x2 = 10;
m = 50;
var
x0,y0, x_pos, line_pos: integer;
x,y: real;
begin
  with Image1 do
    begin
      x0 := Width div 2;
      y0 := Height div 2;

      with Canvas do begin
          Pen.Color := clBlack;
          Pen.Width := 1;
          MoveTo(0, y0);
          LineTo(ClientWidth, y0);
          MoveTo(x0, 0);
          LineTo(x0,ClientHeight);

          Pen.Color := clRed;
          Pen.Width := 2;

          x := x1;
          S := Edit1.Text;
          x_pos := 1;

          while x_pos <= length(S) do begin // заменяет все "х" в строке
            if S[x_pos] = 'x' then begin
              delete(S, x_pos, 1);
              insert('(' + floattostr(x) + ')', S, x_pos);
            end;
            x_pos := x_pos + 1;
          end;

          Calc(S, ans, ErrPos, Mess); //вычисляет значение строки. S - сама строка, ans - значение выражения, ErrPos - индекс ошибки, Mess - сообщение ошибки
          if ErrPos > 0 then
            Label2.Caption := Mess;

          y := ans;
          MoveTo(x0 + Trunc(x * m), y0 - Trunc(y * m));
          LineTo(x0 + Trunc(x * m), y0 - Trunc(y * m));
          while x < x2 do begin
            x_pos := 1;
            x := x + 0.01;
            S := Edit1.Text;
            while x_pos <= length(S) do begin
              if S[x_pos] = 'x' then begin
                delete(S, x_pos, 1);
                insert('(' + floattostr(x) + ')', S, x_pos);
              end;
              x_pos := x_pos + 1;
            end;
            Calc(S, ans, ErrPos, Mess);
            y := ans;
            LineTo(x0 + Trunc(x * m), y0 - Trunc(y * m));

Вот, что получается в результате работы кода:delphi7 график

Это, конечно, похоже на sin(x), однако хотелось бы большего сходства. В чём ошибка?

*Дополнено. Код процедуры Calc:

var
    ans     : real;
    S       : string;
    ErrPos  : integer;
    Mess    : string;

procedure Calc(S: string;
    var V: real;
    var ErrPos: integer;
    var ErrMess: string
    );
const
    EOT = #0;

type 
    Functions = (ABSOLUTE, SQUARE, TRUNCATE,
                 ROUNDING, SINUS, COSINUS, ARC,
                 LOG, EXPONENT, SQUAREROOT,
                 DUMMY
                 );
const
    FirstFunc = ABSOLUTE;
    LastFunc = SQUAREROOT; 
    FuncNames: array[Functions] of string[6] =
                    ('ABS', 'SQR', 'TRUNC', 'ROUND',
                     'SIN', 'COS', 'ARCTAN', 'LN',
                     'EXP', 'SQRT', ''
                    );
var 
    i   : integer;
    Ch  : char;

procedure Error(Message: string);
begin
    if ErrPos = 0 then begin
        ErrMess := Message;
        ErrPos := i;
        Ch := EOT;
    end;
end;

procedure NextChar;
begin
    if ErrPos <> 0 then
        Ch := EOT
    else
        repeat
            i := i + 1;
            if i <= length(S) then
                Ch := UpCase(S[i])
            else 
                Ch := EOT;
        until Ch <> ' ';
end;

procedure Number(var V: real);
var 
    NumStr  : string; {Текст числа}
    Err     : integer; {Номер неверного символа}

procedure IntNumber;
begin  
    if not(Ch in ['0'..'9']) then
        Error('Число начинается не с цифры');
    while Ch in ['0'..'9'] do begin
        NumStr := NumStr + Ch;
        NextChar;
    end;
end;
begin
    NumStr := '';
    IntNumber;
    if Ch = '.' then begin
        NumStr := NumStr + Ch;
        NextChar;
        IntNumber;
    end;
    if Ch = 'E' then begin
        NumStr := NumStr + Ch;
        NextChar;
        if Ch in ['+','-'] then begin
            NumStr := NumStr + Ch;
            NextChar;
        end;
        IntNumber;
    end;
    Val(NumStr, V, Err);
    if Err <> 0 then
        Error('Ошибка в числе');
end;

procedure Name(var F: Functions);
var 
    NameStr : string;
begin
    if Ch in ['A'..'Z'] then begin
        NameStr := Ch;
        NextChar;
        end
    else
        Error('Ожидается буква');
    while Ch in ['A'..'Z', '0'..'9'] do begin
        NameStr := NameStr + Ch;
        NextChar;
    end;

    F := FirstFunc;
    while (F <= LastFunc) and (NameStr <> FuncNames[F]) do
        F := succ(F);
    if F = DUMMY then
        Error('Неправильное имя функции');
end;

function Func(F: Functions; ans: real) : real;
begin
    Func := ans;
    case F of
    ABSOLUTE    : Func := abs(ans);
    SQUARE      : Func := sqr(ans);
    TRUNCATE    : Func := trunc(ans);
    ROUNDING    : Func := round(ans);
    SINUS       : Func := sin(ans);
    COSINUS     : Func := cos(ans);
    ARC         : Func := arctan(ans);
    LOG         : 
        if ans > 0 then
            Func := ln(ans)
        else
            Error('Логарифм неположительного числа');
    EXPONENT    : Func := exp(ans);
    SQUAREROOT  :
        if ans >= 0 then 
            Func := sqrt(ans)
        else 
            Error('Корень из отрицательного числа');
    end;
end;

procedure Expression(var V: real); forward;

procedure Multiplier(var V: real);
var
    F : Functions;
begin
    if Ch in ['0'..'9'] then
        Number(V)
    else if Ch in ['A'..'Z'] then begin
        Name(F);
        if Ch <> '(' then
            Error('Ожидается ''(''')
        else begin
            NextChar;
            Expression(V);
            V := Func(F, V);
            if Ch = ')' then
                NextChar
            else
                Error('Ожидается '')''')
            end
         end
    else if Ch = '(' then begin
        NextChar;
        Expression(V);
        if Ch <> ')' then
            Error('Ожидается '')''')
        else 
            NextChar
        end
    else
        Error('Ожидается число, функция или ''(''');
end;

procedure Addend(var V: real);
var 
    Op  : char;     {Знак операции}
    X   : real;     {Значение операнда}
begin
    Multiplier(V);
    while Ch in ['*','/'] do begin
        Op := Ch;
        NextChar;
        Multiplier(X);
        if Op = '*' then
            V := V * X
        else if X <> 0 then
            V := V / X
        else
            Error('Деление на ноль');
        end;
end;

procedure Expression(var V: real);
var 
    Op  : char;
    X   : real;
begin
    Op := '+';
    if Ch in ['+','-'] then begin
        Op := Ch;
        NextChar;
    end;
    Addend(V);
    if Op = '-' then
        V := -V;
    while Ch in ['+','-'] do begin
        Op := Ch;
        NextChar;
        Addend(X);
        if Op = '+' then
            V := V + X
        else
            V := V - X
    end;
end;

begin
    ErrPos := 0;
    i := 0;
    NextChar;
    Expression(V);
    if Ch <> EOT then
        Error('Ожидается конец выражения');
end;

Ответы (1 шт):

Автор решения: Vlad Chapl

В режиме отладки ставим break point на любую из трех строк

Calc(S, ans, ErrPos, Mess);
y := ans;
LineTo(x0 + Trunc(x * m), y0 - Trunc(y * m));

и смотрим как меняется x0 + Trunc(x * m) и y0 - Trunc(y * m). По вашей задумке они должны плавно меняться (для этого можно пошагово выполнить несколько иттераций, отслеживая изменения значений переменных).

Коротко об отладке + Лекция: Отладка программ в среде Delphi

→ Ссылка