![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
|
Пишу нечто похожее на 3D карту, структуру ячеек с шириной, высотой, и длинной по типу одномерного массива:
Код:
type TGrid3D = class(TObject)
public
SizeX, SizeY, SizeZ: Integer;
Grid3D: array of Byte;
end;
var
Grid3D: array of TGrid3D;
Grid3DNumber: Word = 0;
function DsGrid3dCreate(SX,SY,SZ: Double): Double; cdecl;
begin
Result:=-1;
if SX*SY*SZ>1024*1024*1024 then Exit;
SetLength(Grid3D,Length(Grid3D)+1);
Grid3D[Grid3DNumber]:=TGrid3D.Create;
Grid3D[Grid3DNumber].SizeX:=Trunc(SX);
Grid3D[Grid3DNumber].SizeY:=Trunc(SY);
Grid3D[Grid3DNumber].SizeZ:=Trunc(SZ);
SetLength(Grid3D[Grid3DNumber].Grid3D,Grid3D[Grid3DNumber].SizeX*Grid3D[Grid3DNumber].SizeY*Grid3D[Grid3DNumber].SizeZ);
Result:=Grid3DNumber;
Grid3DNumber:=Grid3DNumber+1;
end;
function DsGrid3dDestroy(ID: Double): Double; cdecl;
begin
Result:=0;
Grid3D[Trunc(ID)].Destroy;
Result:=1;
end;
function DsGrid3dSet(ID, X, Y, Z, V: Double): Double; cdecl;
var r: Integer;
begin
Result:=0;
r:=Grid3D[Trunc(ID)].SizeX*Grid3D[Trunc(ID)].SizeY*Trunc(Z)+Grid3D[Trunc(ID)].SizeX*Trunc(Y)+Trunc(X);
Grid3D[Trunc(ID)].Grid3D[r]:=Trunc(V);
Result:=1;
end;
function DsGrid3dGet(ID, X, Y, Z: Double): Double; cdecl;
var r: Integer;
begin
r:=Grid3D[Trunc(ID)].SizeX*Grid3D[Trunc(ID)].SizeY*Trunc(Z)+Grid3D[Trunc(ID)].SizeX*Trunc(Y)+Trunc(X);
if (X<0) or (Y<0) or (Z<0) or
(X>=Grid3D[Trunc(ID)].SizeX) or (Y>=Grid3D[Trunc(ID)].SizeY) or (Z>=Grid3D[Trunc(ID)].SizeZ)
then Result:=-1 else Result:=Grid3D[Trunc(ID)].Grid3D[r];
end;
function DsGrid3dGetSize(ID, WHD: Double): Double; cdecl;
begin
try
Result:=-1;
if WHD = 0 then Result:= Grid3D[Trunc(ID)].SizeX;
if WHD = 1 then Result:= Grid3D[Trunc(ID)].SizeY;
if WHD = 2 then Result:= Grid3D[Trunc(ID)].SizeZ;
except
Result:=-1;
end;
end;вопрос в оптимизации DsGrid3dGet т.к. для защиты от некорректного ввода пользователя используется условие т.е. код защищён от запроса на отсутствующую ячейку. Можно ли заменить условие чем-то более быстым, поскольку этот запрос наиболее востребыванный? Последний раз редактировалось gadmaker, 27.01.2013 в 15:33. |
|
#2
|
|||
|
|||
|
некоретный ввод проверяется во время ввода, а не каждое чтение ячейки
и второе, нахрена тут вообще class(TObject) ![]() |
| Этот пользователь сказал Спасибо my33oh за это полезное сообщение: | ||
OTVET (28.01.2013)
| ||
|
#3
|
|||
|
|||
|
это DLL расширение для скриптового языка те таких сеток может быть более одной. А проверка внутри функции нужна для исключения проверок в скрипте т.к. Delphi это сделает намного быстрее.
|
|
#4
|
|||
|
|||
|
Ну для начала в каждую функцию добавить переменную
Код:
var Cell:TGrid3D; Код:
Cell := Grid3D[Trunc(ID)]; Код:
function DsGrid3dCreate(SX,SY,SZ: Double): Double; cdecl; var Cell:TGrid3D; begin Result:=-1; if SX*SY*SZ>1024*1024*1024 then Exit; SetLength(Grid3D,Length(Grid3D)+1); Cell:=TGrid3D.Create; Grid3D[Grid3DNumber]:=Cell; Cell.SizeX:=Trunc(SX); Cell.SizeY:=Trunc(SY); Cell.SizeZ:=Trunc(SZ); SetLength(Cell.Grid3D,Cell.SizeX*Cell.SizeY*Cell.SizeZ); Result:=Grid3DNumber; Grid3DNumber:=Grid3DNumber+1; end; Код:
function DsGrid3dGet(ID, X, Y, Z: Double): Double; cdecl; var r,IX,IY,IZ: Integer; Cell:TGrid3D; begin Result:=-1; IX := Trunc (X); if (IX<0) then Exit; IY := Trunc (Y); if (IY<0)then Exit; IZ := Trunc (Z); if (IZ<0) then Exit; Cell := Grid3D[Trunc(ID)]; if (IX>=Cell.SizeX) Then Exit; if (IY>=Cell.SizeY) Then Exit; if (IZ>=Cell.SizeZ) Then Exit; r:=Cell.SizeX*Cell.SizeY*IZ+Cell.SizeX*IY+IX; Result:=Cell.Grid3D[r]; end; |
| Этот пользователь сказал Спасибо icWasya за это полезное сообщение: | ||
OTVET (28.01.2013)
| ||
|
#5
|
||||
|
||||
|
На тему данного кода, действительно лишнее использование объектов, и странные проверки. Автор, почему не record? Последний раз редактировалось M.A.D.M.A.N., 28.01.2013 в 18:59. |
|
#6
|
|||
|
|||
|
Цитата:
|
|
#7
|
|||
|
|||
|
>масло масляное
Я экономил не булевские операции, а преобразования double-int А вот здесь можно Код:
r:=Cell.SizeX*Cell.SizeY*IZ+Cell.SizeX*IY+IX; сэкономить одно умножение Код:
r:=Cell.SizeX*(Cell.SizeY*IZ+IY)+IX; |
|
#8
|
|||
|
|||
|
Спасибо за ответы! Уже пробую оптимизировать, позвольте ещё один вопрос по алглритмам:
r:=Cell.SizeX*(Cell.SizeY*IZ+IY)+IX; - алгоритм получения значения из массива по координатам (Огромное спасибо за него!!!). Как будет выглядеть обратный алгоритм получения координат т.е. исли известен индекс массива? |
|
#9
|
|||
|
|||
|
как то так
Код:
procedure GetIndexes(ID:double; r:double; var X,Y,Z:Double); var IR:Integer; Cell:TGrid3D; begin IR:=Trunc(r); Cell := Grid3D[Trunc(ID)]; X := IR mod Cell.SizeX; IR:= IR div Cell.SizeX; Y := IR mod Cell.SizeY; Z := IR div Cell.SizeY; end; |