如何计算等角矩形/正方形的高度和宽度

发布于 2024-10-10 11:52:26 字数 227 浏览 5 评论 0原文

我正在编写一个等距瓷砖游戏。每块瓷砖的宽度是高度的两倍 (w:h = 2:1)。地图中的所有图块都具有相同的尺寸,并且它们的宽度和高度是已知的(图块宽度和图块高度)。

可以有任意数量的列(>0)和行(>0)。

我正在努力想出一个公式来计算完全绘制的地图的宽度和高度。这需要是从最顶部到最底部以及最左边到最右边的距离。由于列数和行数可能会有所不同(因此地图并不总是完美的菱形),事实证明这非常困难!

I'm writing an isometric tile game. Each tile is twice as wide as it is tall (w:h = 2:1). All tiles in a map are the same size and their width and heights are known (TileWidth and TileHeight).

There can be any number of columns (>0) and rows (>0).

I'm struggling to come up with a formula to calculate the width and height of the fully drawn map. This needs to be the distance from the very top to the very bottom and the extreme left to the extreme right. As the number of columns and rows can vary (and thus the map is not always a perfect diamond) it's proving very hard!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

西瓜 2024-10-17 11:52:26

好问题!有一个不太明显的答案,但很容易计算:

让我们将行轴称为“r”,将列轴称为“c”,并考虑第一张图片,其中沿 r 轴的范围为 5,沿c 轴为 3。

沿 r 轴的单位增量,相对于绘图平面,角度 +30 = (cos 30°, sin 30°) = (sqrt(3)/2, 0.5),单位增量沿 c 轴的位置为 -30 = (cos 30°, -sin 30°) = (sqrt(3)/2, -0.5)。

您需要考虑等距矩形的两条对角线。在第一张图片中,这些对角线是 D1 = [+5*U 沿 r 轴和 +3*U 沿 c 轴] 和 D2 = [+5*U 沿 r 轴和 -3*U 沿 c 轴],其中 U 是等轴测平面中的瓷砖长度。当变换到绘图平面时,变为 D1 = ((5+3)*sqrt(3)/2*U, (5-3)/2*U) = (4*sqrt(3)*U, 1* U) 和 D2 = ((5-3)*sqrt(3)/2*U, (5+3)/2*U) = (sqrt(3)*U, 4*U)。因此,屏幕宽度和高度是两个范围中的最大值 = 4*sqrt(3)*U, 4*U。

这可以概括为:如果有 Nr 行和 Nc 列,并且图块长度为 U,则绘图平面中矩形对角线的长度为 D1 = ((Nr+Nc)*sqrt(3)/2* U, (Nr-Nc)/2*U) 和 D2 = ((Nr-Nc)*sqrt(3)/2*U, (Nr+Nc)/2*U),因此屏幕宽度和高度, 是:

W = U*(Nr+Nc)*sqrt(3)/2
H = U*(Nr+Nc)/2

Good question! There's a not-too-obvious answer but it's easy to calculate:

Let's call the row axis "r" and the column axis "c", and consider the first picture, where the extent along the r axis is 5 and the extent along the c axis is 3.

The unit increment along the r axis, relative to the drawing plane, is at angle +30 = (cos 30°, sin 30°) = (sqrt(3)/2, 0.5), and the unit increment along the c axis is at -30 = (cos 30°, -sin 30°) = (sqrt(3)/2, -0.5).

You need to consider the two diagonals of your isometric rectangle. In the first picture, those diagonals are D1 = [+5*U along the r axis and +3*U along the c axis] and D2 = [+5*U along the r axis and -3*U along the c axis], where U is the tile length in the isometric plane. When transformed into the drawing plane, this becomes D1 = ((5+3)*sqrt(3)/2*U, (5-3)/2*U) = (4*sqrt(3)*U, 1*U) and D2 = ((5-3)*sqrt(3)/2*U, (5+3)/2*U) = (sqrt(3)*U, 4*U). The screen width and height, therefore, are the maximum of the two extents = 4*sqrt(3)*U, 4*U.

This can be generalized: if there are Nr rows and Nc columns, and the tile length is U, the extent of the diagonals of the rectangle in the drawing plane are D1 = ((Nr+Nc)*sqrt(3)/2*U, (Nr-Nc)/2*U) and D2 = ((Nr-Nc)*sqrt(3)/2*U, (Nr+Nc)/2*U), and the screen width and height, therefore, are:

W = U*(Nr+Nc)*sqrt(3)/2
H = U*(Nr+Nc)/2
ま昔日黯然 2024-10-17 11:52:26

等角投影的角度为60°和30°。图块的实际宽度和高度将为:

Wiso = TileWidth * Cos(30) + TileHeight * Cos(60)
Hiso = TileWidth * Sin(30) + TileHeight * Sin(60)

现在,您可以将这些数字乘以每行和每列的图块数量来获得网格的大小。

编辑:看看你的图像,看起来投影不是等距的(至少不是我在学校学到的),并且角度两侧都是 60 度,因此将 Cos(60) 替换为Cos(30)Sin(60)Sin(30)

另一种看待它的方式:

Wgrid = TileWidth * Cos(30) * Ncols + TileHeight * Cos(30) * Nrows
Hgrid = TileWidth * Sin(30) * Ncols + TileHeight * Sin(30) * Nrows

The angles of the isometric projection are 60deg and 30deg. The actual width and height of a tile will be:

Wiso = TileWidth * Cos(30) + TileHeight * Cos(60)
Hiso = TileWidth * Sin(30) + TileHeight * Sin(60)

Now you can add multiply these numbers by the number of tiles per row and column to get the grid's size.

EDIT: looking at your images, it seems like the projection is not isometric (at least not what I learned in school), and the angles are 60deg to both sides, so replace the Cos(60) with Cos(30) and the Sin(60) with Sin(30)

Another way to look at it:

Wgrid = TileWidth * Cos(30) * Ncols + TileHeight * Cos(30) * Nrows
Hgrid = TileWidth * Sin(30) * Ncols + TileHeight * Sin(30) * Nrows

北城半夏 2024-10-17 11:52:26

如果从底部开始并向左侧走去,则每列的图块高度将上移一半,然后每行的高度将上移一半。同样,如果您从左侧开始并沿着底部边缘行走,则每列向上移动图块宽度的一半,然后每行向上移动一半宽度。

因此,地图的轴对齐边界框的宽度为 (rows+columns)*TileWidth/2,高度为 (rows+columns)*TileHeight/2

If you start at the bottom and walk up the left side, you move up half the tile height for each column, then half the height for each row. Similarly if you start at the left and walk along the bottom edge, you move up half the tile width for each column, then half the width for each row.

So the width of the axis-aligned bounding box for the map is (rows+columns)*TileWidth/2 and the height is (rows+columns)*TileHeight/2

燕归巢 2024-10-17 11:52:26

为什么不使用旋转方程如下:

假设瓷砖没有旋转,所以四个角有以下坐标:

(0, 0, 0)
(w, 0, 0)
(0, h, 0)
(w, h, 0)

现在

w = Number of Columns * Tile Width
h = Number of Rows * Tile Height

我假设你有投影矩阵,所以在应用它之后,你会得到 4 个 3D 点的 2D 屏幕坐标,你需要做的是:

  1. 获取所有点的最小x坐标(投影后)。
  2. 获取所有点的最大 x 坐标(投影后)。
  3. 获取所有点的最小 y 坐标(投影后)。
  4. 获取所有点的最大 y 坐标(投影后)。

2 减 1 得到宽度,4 减 3 得到高度。

这有帮助吗?

Why not use rotation equations as follows:

Suppose the tiles are not rotated, so the four corners have the following coordinates:

(0, 0, 0)
(w, 0, 0)
(0, h, 0)
(w, h, 0)

where

w = Number of Columns * Tile Width
h = Number of Rows * Tile Height

Now I suppose you have the projection matrix, so after applying it, you get 2D screen coordinates of the 4 3D points, and what you need to do is this:

  1. Get the minimum x-coordinate of all the points (after projection).
  2. Get the maximum x-coordinate of all the points (after projection).
  3. Get the minimum y-coordinate of all the points (after projection).
  4. Get the maximum y-coordinate of all the points (after projection).

Subtract 1 from 2, and you to get the width, and 3 from 4 to get the height.

Does that help?

写给空气的情书 2024-10-17 11:52:26

我认为你可以用毕达哥拉斯定理来做到这一点:

halfWidth = tileWidth / 2;
halfHeight = tileHeight / 2;
h = Math.sqrt((halfWidth * halfWidth ) * (halfHeight * halfHeight));
rowLength = rowSize * h;
colLength = colSize * h;

我的数学不太好,但是h 应该是图块一侧的长度,因此您可以将其乘以图块数量。

I think you could do this with Pythagoras' theorem:

halfWidth = tileWidth / 2;
halfHeight = tileHeight / 2;
h = Math.sqrt((halfWidth * halfWidth ) * (halfHeight * halfHeight));
rowLength = rowSize * h;
colLength = colSize * h;

My maths is not great but h should be the length of one side of a tile so you can then multiply that by the number of tiles.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文