Добрый день! Необходимо написать графический редактор следующего вида: Окно разбито на 2 части, в левой вводятся параметры фигуры, в правой она отрисовывается. Например: для начала задан прямоугольник высотой 50 и шириной 100. Указываем высоту - 25, на ней ширина 50 и фигура должна преобразоваться, приняв форму песочных часов и далее в этом духе. Надеюсь нормально объяснил...
Программу еще не начал, код писать не прошу, необходима консультация в том, какие элементы выбрать для разработки, TPaintBox или TImage и т.д. и как лучше всё это отрисовывать, может кто может дать совет?
RussoTuristo, ты не думал никогда над тем, что чем меньше строк в программе - тем лучше? Вот тебе 2 хинта, как можно безо всяких проблем убрать по десятку строк в каждом случае, без изменения функционала программы.
Первый - касается вот этого ужаса (из процедуры TzoneMath.ShowOnTable):
Цитата
for i:=1 to steps do begin grid.Cells[0,i]:=FloatToStr(RoundTo(rooms[room].iParams[i-1].tau,-5)); grid.Cells[1,i]:=FloatToStr(RoundTo(rooms[room].iParams[i-1].Fp,-5)); grid.Cells[2,i]:=FloatToStr(RoundTo(rooms[room].iParams[i-1].Gk,-5)); grid.Cells[3,i]:=FloatToStr(RoundTo(rooms[room].iParams[i-1].y,-5)); grid.Cells[4,i]:=FloatToStr(RoundTo(rooms[room].iParams[i-1].Qpozh,-5)); grid.Cells[5,i]:=FloatToStr(RoundTo(rooms[room].iParams[i-1].Ro2,-5)); grid.Cells[6,i]:=FloatToStr(RoundTo(rooms[room].iParams[i-1].T2,-5)); grid.Cells[7,i]:=FloatToStr(RoundTo(rooms[room].iParams[i-1].Gm,-5)); end;
Зачем это делать, расскажи? Что, выводить значения можно только вот таким, допотопным, "строка за строкой" способом? А понадобится тебе уменьшить точность, будешь везде "-5" изменять на "-4" что-ли?
Исправление:(Показать/Скрыть)
1) изменяем описание структуры TiParams на вот такое: TiParams = packed record yP, T2P, Ro2P, T21 : Extended; //пересчет
case Boolean of False: (tau : Extended; //текущее время (с) Fp, Gk, y, Qpozh, Ro2, T2, Gm : Extended); True : (Values : Array[0 .. 7] Of Extended); end; , то есть, вариантная запись, все те элементы, которые будут выводиться в Grid, располагаем в конце структуры в нужном порядке, и совмещаем с ними массив Extended-значений (не забудь добавить слово Packed в описание структуры, иначе вылетишь с ошибкой). А там, где было построчное добавление - один простой цикл (работаем с элементами, как с массивом, он ведь физически располагается на тех же местах, что и переменные, и обращение rooms[room].iParams[i-1].Values[0] эквивалентно rooms[room].iParams[i-1].tau, и т.д.):
for i:=1 to steps do begin for j := 0 to 7 do grid.Cells[j, i] := FloatToStr(RoundTo(rooms[room].iParams[i-1].Values[j], -5)); end;
Функционал не изменился, все работает абсолютно так же, как и раньше.
Второй. Зачем дублировать здесь:
Цитата
function TzoneMath.fGm(iter,CurrentRoom:integer; woll:TWoll; forroom:integer):extended;
function TrapezeSt1(a, b: extended; eps: extended): extended; function func(h: extended): extended; begin curroom:=CurrentRoom; Result:=Woll.Proem[0].Width * Rooms[CurrentRoom].iParams[iter].Ro2P * sqrt((2 * TrapezeInt(Rooms[CurrentRoom].Height-Rooms[CurrentRoom].iParams[iter].yP, woll.Proem[0].Height, 0.01, fdP_1))/Rooms[CurrentRoom].iParams[iter].Ro2P); end; var xx1,xx2,xx3:extended; c:integer; begin result:=0; for c:=1 to round(abs(b-a)/eps) do begin xx1:=func(a+c*eps); xx2:=func(a+c*eps+eps); if xx2>xx1 then begin xx3:=xx1 end else begin xx3:=xx2; end; result:=result+abs(xx2-xx1)*eps+abs(xx3)*eps; end; end;
begin if (Rooms[CurrentRoom].Height-Rooms[CurrentRoom].iParams[iter_buf].YP)<woll.Proem[0].Height then begin result:= TrapezeSt1(Rooms[CurrentRoom].Height-Rooms[CurrentRoom].iParams[iter].yP, Woll.Proem[0].Height, 0.01); end else begin result:=0; end; end;
то, что уже сделано в модуле intfunc? У тебя же уже есть там функция, вычисляющая интеграл. Зачем же ты ее тут опять переписываешь заново? Всё проще:
Исправление:(Показать/Скрыть)
function fdP_1(h: extended): extended; // Эта функция у тебя была... begin result:=9.81*(zoneMath.Rooms[curroom].iParams[0].Ro2P-zoneMath.Rooms[curroom].iParams[iter_buf].Ro2P) end;
// После нее добавляешь еще одну, небольшую, функцию: var currWoll : TWoll; iteration : Integer;
function SecondFunc(h: extended): extended; begin with zoneMath.Rooms[curroom] do Result:=CurrWoll.Proem[0].Width * iParams[iteration].Ro2P * sqrt( (2 * TrapezeInt(Height-iParams[iteration].yP, currwoll.Proem[0].Height, 0.01,fdP_1)) / iParams[iteration].Ro2P ); end;
function TzoneMath.fGm(iter,CurrentRoom:integer; woll:TWoll; forroom:integer):extended; begin curroom:=CurrentRoom; currWoll := woll; iteration := iter;
if (Rooms[CurrentRoom].Height-Rooms[CurrentRoom].iParams[iter_buf].YP)<woll.Proem[0].Height then begin result:= TrapezeInt(Rooms[CurrentRoom].Height-Rooms[CurrentRoom].iParams[iter].yP, Woll.Proem[0].Height, 0.01, SecondFunc); end else begin result:=0; end; end;
, и она прекрасно сделает то, что положено...
Функционал опять же, остался прежним, а если так - то зачем писАть больше? Кстати, еще один повод перейти на новую версию Дельфи. в 2009 и выше это делается через анонимные функции, избавляя тебя от необходимости добавлять вон те две глобальные переменные.
Да, и еще... Я бы подумал над переносом хотя бы части глобальных переменных в соответствующие классы (в секцию private). Скажем, curroom. Внести ее в TzoneMath, например. Так же, как и iter_buf. Подумай над этим... И "разгрузи" код, путем использования With. Его ж читать невозможно...
Сообщение отредактировано: IUnknown - 3.05.2011 11:06