Маленький вопросик по динамическим массивам и записи

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Маленький вопросик по динамическим массивам и записи

Сообщение xterro » 07.02.2015 19:20:31

Доброго времени суток, пишу значит код, вот его куски:

1. Расписываю список точек Арки, интересует, следующий момент, здесь я использую динамический массив Points(объявлен как Points : array of TPointF; TPointF - запись), у него диапазон от 0 до N-1.
Но у меня получается так, что спокойно прокручивается до N(т.е я выхожу за границы массива), и компилятор даже ни разу не вякнул, почему?
Код: Выделить всё
procedure TArc.CalculateArc();
var
    PX, PY, tmpPX, tmpPY : Real;
    Coef, Delta : Real;
    BAngle, EAngle : Real;
    Iterations, i : Integer;
begin
    { x = R * cos(A) + X
      y = R * sin(A) + Y }

    // Переводим в радианы
    BAngle := (FStartAngle / 180) * Pi;
    EAngle := (FEndAngle / 180) * Pi;

    // Определяем оптимальное количество итераций
    Coef := (Pi*2) / Abs(EAngle - BAngle);
    Iterations := Round((2 * FRadius ) / Coef);
    Delta := (EAngle - BAngle) / Iterations;

    SetLength(Points, Iterations);

    tmpPX := FRadius * Cos(BAngle) + FX;
    tmpPY := FRadius * Sin(BAngle) + FY;

    { Заполняем масив точек, по которым будем отрисовывать арку и получим её границы }
    Points[0].X := tmpPX;
    Points[0].Y := tmpPY;

    for i:=1 to Iterations do begin
        BAngle := BAngle + Delta;
        PX := FRadius * Cos(BAngle) + FX;
        PY := FRadius * Sin(BAngle) + FY;
        Points[i].X := PX;
        Points[i].Y := PY;
        tmpPX := PX;
        tmpPY := PY;
    end;
end;                                                               


2. Есть ещё одна функция, которая вычисляет границы арки, задача в том, что мне нужно вернуть границы, значениями которой будут вещественные числа, т.е простой TRect не подходит.
Сделал для этого запись:
Код: Выделить всё
TRectF = record
        Left    : Real;
        Top     : Real;
        Right   : Real;
        Bottom  : Real;
    end;         


В нужно мне функции думаю динамически выделять память и возвращать указатель на мою TRectF, вопрос в том, когда мне её освобождать? Если сразу после Result := <указатель на мою запись> напишу типа Dispose(<указатель на мою запись>), я же потеряю данные вне функции, где её вызвал, или всё же получу результат(цифирьки), а потом память освободится?

Код: Выделить всё
function TArc.GetBBox() : TRect;
var
   i : Integer;
   MinX, MinY : Real;
   MaxX, MaxY : Real;
begin
    if Length(Points) > 0 then begin
        MaxX := Points[0].X;
        MaxY := Points[0].Y;
        MinX := MaxX;
        MinY := MaxY;

        for i:=1 to Length(Points) do begin
            if Points[i].X > MaxX then
                MaxX := Points[i].X
            else
                if Points[i].X < MinX then
                    MinX := Points[i].X;

            if Points[i].Y > MaxY then
                MaxY := Points[i].Y
            else
                if Points[i].Y < MinY then
                    MinY := Points[i].Y;

        end;
        Result := Rect(Round(MinX), Round(MinY), Round(MaxX+1), Round(MaxY+1));
        // Думаю тут написать Dispose(PRectF);
    end
    else
        Result := Rect(0, 0, 0, 0);
end;                                                 
xterro
постоялец
 
Сообщения: 148
Зарегистрирован: 23.02.2014 13:49:33

Re: Маленький вопросик по динамическим массивам и записи

Сообщение zub » 07.02.2015 20:46:20

>>и компилятор даже ни разу не вякнул, почему?
проверка границ в опциях компилятора включена?

>>Если сразу после Result := <указатель на мою запись> напишу типа Dispose(<указатель на мою запись>), я же потеряю данные вне функции, где её вызвал, или всё же получу результат(цифирьки), а потом память освободится?
Освобождать память нужно когда то что лежит в этой памяти уже ненужно, т.е. в данном случае вне этой функции. Кроме того под такую мелочевку делать отдельные выделения вообще не стоит.
В приведенном примере нет никаких выделений памяти, функция возвращает TRect, а не ^TRec. или я чтото не понял?
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Маленький вопросик по динамическим массивам и записи

Сообщение xterro » 07.02.2015 21:03:24

проверка границ в опциях компилятора включена?

Не могу найти где это делается в настройках Lazarus :(

или я чтото не понял?

Задача состоит в том, чтобы вернуть из функции "свой" прямоугольник - границы фигуры, в данном случае арки(элементами которого являются переменные типа Real, а не Integer как в обычном TRect).
Не могу же я написать что-то типа: Result := TRectF(1, 2, 3, 4) как в случае с простым TRect - компилятор начнёт ругаться. Т.е в приведённом коде я сделал так:

Код: Выделить всё
Result := Rect(Round(MinX), Round(MinY), Round(MaxX+1), Round(MaxY+1));
но здесь есть округления которые мне не нужны, как-то можно обойтись, чтобы "прямоугольник" был не целочисленным? Потому как это на экране, координаты могут быть целочисленными, а во внутреннем представлении оно всё вещественное, например начало линии X1/Y1: 5,75/24,89, конец X2/Y2: 103,15/50,84 :)
xterro
постоялец
 
Сообщения: 148
Зарегистрирован: 23.02.2014 13:49:33

Re: Маленький вопросик по динамическим массивам и записи

Сообщение zub » 07.02.2015 22:16:49

>>Не могу найти где это делается в настройках Lazarus
в опциях проекта на вкладке Debugging/Checks and assertions

>>Задача состоит в том...
Код: Выделить всё
function TArc.GetBBox() : TRectF;
begin
  ...
  result.Left:=...;
  result.Top:=...;
  result.Right:=...;
  result.Bottom:=...;
end;

Либо определи свою функцию например RectF соторая будет собирать 4 флоата в TRectF, наподобии как
>>Rect(0, 0, 0, 0);
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Маленький вопросик по динамическим массивам и записи

Сообщение xterro » 08.02.2015 01:42:15

Код: Выделить всё
result.Left:=...;
  result.Top:=...;
  result.Right:=...;
  result.Bottom:=...;

О, так можно делать оказывается )) А по поводу функции, могу ли я её определить не методом класса, а независимо, скажем в начале модуля и потом использовать в своих классах? :?

P.S. Сейчас поставил опцию в параметрах проекта, действительно, выкинул исключение, при присваивании значения элементу массива: RunError(201) - видимо это и есть выход за пределы :)
xterro
постоялец
 
Сообщения: 148
Зарегистрирован: 23.02.2014 13:49:33

Re: Маленький вопросик по динамическим массивам и записи

Сообщение zub » 08.02.2015 02:13:36

>>могу ли я её определить не методом класса, а независимо,
Конечно подобное не нужно в методах дуги. Собирай подобные функции в отдельном "общеупотребимом" модуле
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Маленький вопросик по динамическим массивам и записи

Сообщение xterro » 08.02.2015 09:15:02

Спасибо :)
xterro
постоялец
 
Сообщения: 148
Зарегистрирован: 23.02.2014 13:49:33

Re: Маленький вопросик по динамическим массивам и записи

Сообщение zub » 08.02.2015 10:23:33

Еще совет - чтобы определить aabb дуги ненадо перебирать все точки представления - их может быть достаточно много при определенных детализациях. Достаточно взять крайние точки и точки "квадрантов" (лежащие на осях х и у) попадающие в угол дуги
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Маленький вопросик по динамическим массивам и записи

Сообщение xterro » 08.02.2015 16:47:41

Достаточно взять крайние точки и точки "квадрантов" (лежащие на осях х и у) попадающие в угол дуги

Знать бы ещё как это делать :? Всё равно надо по массиву точек пробегать?
xterro
постоялец
 
Сообщения: 148
Зарегистрирован: 23.02.2014 13:49:33

Re: Маленький вопросик по динамическим массивам и записи

Сообщение zub » 08.02.2015 17:25:21

нет, ненадо, учавсрвуют только точки Points[0],Points[length(points)] и выборочно в зависимости от охвата дуги точки (x0+r,y0),(x0,y0+r),(x0-r,y0),(x0,y0-r). где (x0,y0) - центр дуги, r - радиус.

Но пока тормозов не почувствуется, можно и просто перебирать все точки
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Маленький вопросик по динамическим массивам и записи

Сообщение xterro » 08.02.2015 17:59:36

точно, чёта я не подумал, спасибо ещё раз ))
xterro
постоялец
 
Сообщения: 148
Зарегистрирован: 23.02.2014 13:49:33


Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6

Рейтинг@Mail.ru