如何在Delphi中表示坐标网格?

时间:2022-04-11 18:36:14

I'm trying to represent a two-dimensional coordinate grid with a two-dimensional array. Problem is, declaring the array flips the X and Y coordinates because of the way Delphi allocates the array. This makes it difficult to read elements of the array. For example, the following program gives a range check error while trying to print:

我试图用二维数组表示二维坐标网格。问题是,由于Delphi分配数组的方式,声明数组会翻转X和Y坐标。这使得难以读取阵列的元素。例如,以下程序在尝试打印时给出范围检查错误:

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

{$R+}
procedure play;
var
   grid: array of array of boolean;
   x, y: integer;
begin
  try
   setLength(grid, 3, 8);
   grid[1, 5] := true;
   for y := low(grid) to high(grid) do
   begin
      for x := low(grid[y]) to high(grid[y]) do
      begin
         if grid[x, y] then
            write('X')
         else write('.');
      end;
      writeln;
   end;
   readln;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end;

begin
   play;
end.

I have to write the index backwards (if grid[y, x] then) to keep that from happening, but then the grid prints out sideways, with the X shown at (5, 1) instead of at (1, 5). If I try to change the shape of the grid by saying setLength(grid, 3, 8); then the assignment on the next line gives a range check error. I end up having to write all of my coordinates backwards, and any time I forget they're backwards, bad things end up happening in the program.

我必须向后写索引(如果是grid [y,x]那么)以防止这种情况发生,但随后网格横向打印出来,X显示在(5,1)而不是(1,5)。如果我尝试通过说setLength(grid,3,8)来改变网格的形状;然后下一行的赋值给出范围检查错误。我最终不得不向后写下我的所有坐标,每当我忘记它们倒退时,程序中就会发生不好的事情。

Does anyone know any tricks to make the coordinate order work intuitively?

有没有人知道使坐标顺序直观地工作的任何技巧?

3 个解决方案

#1


You just need to give the proper bounds in the for statements. It's important to pay careful attention when applying the low and high functions to multi-dimensional arrays. For the current example (a 2-dimensional array), low(grid) and high(grid) will return the limits on the first dimension (row), whereas low(grid[0]) and high(grid[0]) will return the limits on the first column (assuming it exists). Note the changed for limits below:

你只需要在for语句中给出适当的界限。将低功能和高功能应用于多维阵列时,务必要特别注意。对于当前示例(二维数组),低(网格)和高(网格)将返回第一维(行)的限制,而低(网格[0])和高(网格[0])将返回第一列的限制(假设它存在)。请注意以下限制的更改:

program Play_console;

{$APPTYPE CONSOLE}

uses
  SysUtils;

{$R+}
procedure play;
var
   grid: array of array of boolean;
   x, y: integer;
begin
  try
   setLength(grid, 3, 8);
   grid[1, 5] := true;
   for y := low(grid[0]) to high(grid[0]) do
   begin
      for x := low(grid) to high(grid) do
      begin
         if grid[x, y] then
            write('X')
         else write('.');
      end;
      writeln;
   end;

   readln;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end;

begin
   play;
end.

I tested this and it seems to do exactly what you want.

我测试了它,它似乎完全符合你的要求。

#2


[y, x] is common and standard array access across most (all?) programming languages. It will be confusing for anyone looking at your code if you do it otherwise.

[y,x]是大多数(所有?)编程语言中常见的标准数组访问。如果您这样做,那么对于任何查看您的代码的人来说都会感到困惑。

#3


I'd say that the standard representation isn't only consistent with general programming convention, it's consistent with graphing in general. Plot [1,4] on graph paper and you'll get the same thing as in your second (actual result) example, with the exception that the y axis is flipped in screen coordinates, but you're not complaining about that.

我要说标准表示不仅与通用编程约定一致,而且与一般的图形一致。在方格纸上绘制[1,4]并且你会得到与第二个(实际结果)示例中相同的东西,除了y轴在屏幕坐标中翻转,但你并没有抱怨这一点。

More specifically, the x axis is consistently horizontal, and the y axis is consistently vertical. That's what your example shows. It's not reversed.

更具体地,x轴始终是水平的,并且y轴始终是垂直的。这就是你的例子所显示的。它没有逆转。

I'd say just get used to it.

我会说只是习惯了。

#1


You just need to give the proper bounds in the for statements. It's important to pay careful attention when applying the low and high functions to multi-dimensional arrays. For the current example (a 2-dimensional array), low(grid) and high(grid) will return the limits on the first dimension (row), whereas low(grid[0]) and high(grid[0]) will return the limits on the first column (assuming it exists). Note the changed for limits below:

你只需要在for语句中给出适当的界限。将低功能和高功能应用于多维阵列时,务必要特别注意。对于当前示例(二维数组),低(网格)和高(网格)将返回第一维(行)的限制,而低(网格[0])和高(网格[0])将返回第一列的限制(假设它存在)。请注意以下限制的更改:

program Play_console;

{$APPTYPE CONSOLE}

uses
  SysUtils;

{$R+}
procedure play;
var
   grid: array of array of boolean;
   x, y: integer;
begin
  try
   setLength(grid, 3, 8);
   grid[1, 5] := true;
   for y := low(grid[0]) to high(grid[0]) do
   begin
      for x := low(grid) to high(grid) do
      begin
         if grid[x, y] then
            write('X')
         else write('.');
      end;
      writeln;
   end;

   readln;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end;

begin
   play;
end.

I tested this and it seems to do exactly what you want.

我测试了它,它似乎完全符合你的要求。

#2


[y, x] is common and standard array access across most (all?) programming languages. It will be confusing for anyone looking at your code if you do it otherwise.

[y,x]是大多数(所有?)编程语言中常见的标准数组访问。如果您这样做,那么对于任何查看您的代码的人来说都会感到困惑。

#3


I'd say that the standard representation isn't only consistent with general programming convention, it's consistent with graphing in general. Plot [1,4] on graph paper and you'll get the same thing as in your second (actual result) example, with the exception that the y axis is flipped in screen coordinates, but you're not complaining about that.

我要说标准表示不仅与通用编程约定一致,而且与一般的图形一致。在方格纸上绘制[1,4]并且你会得到与第二个(实际结果)示例中相同的东西,除了y轴在屏幕坐标中翻转,但你并没有抱怨这一点。

More specifically, the x axis is consistently horizontal, and the y axis is consistently vertical. That's what your example shows. It's not reversed.

更具体地,x轴始终是水平的,并且y轴始终是垂直的。这就是你的例子所显示的。它没有逆转。

I'd say just get used to it.

我会说只是习惯了。