【问题标题】:How to calculate the height and width of an isometric rectangle/square如何计算等距矩形/正方形的高度和宽度
【发布时间】:2011-01-06 12:57:42
【问题描述】:

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

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

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

【问题讨论】:

    标签: math drawing trigonometry tiles isometric


    【解决方案1】:

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

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

    沿 r 轴的单位增量,相对于绘图平面,角度为 +30 = (cos 30°, sin 30°) = (sqrt(3)/2, 0.5),沿 r 轴的单位增量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) and D2 = ((Nr-Nc)*sqrt(3)/2*U, (Nr+Nc)/2*U),屏幕宽度和因此,高度是:

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

    【讨论】:

      【解决方案2】:

      等轴测投影的角度为 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

      【讨论】:

      • 谢谢。它们不是严格等距的——它们是二等分的(宽度是高的两倍)。
      【解决方案3】:

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

      所以地图的轴对齐边界框的宽度是(rows+columns)*TileWidth/2,高度是(rows+columns)*TileHeight/2

      【讨论】:

        【解决方案4】:

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

        假设瓦片没有旋转,那么四个角的坐标如下:

        (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 得到高度。

        这有帮助吗?

        【讨论】:

        • 等轴测投影不是旋转。
        • 操作,抱歉,但这并没有真正改变解决方案。他可以不用旋转矩阵,而是用投影矩阵,然后做同样的计算。
        • 天哪。这很棘手。我认为我的角度 theta 是 45 度,但我并不真正理解维基百科文章中写的矩阵公式。我觉得自己很笨(我的背景不是数学或计算机科学!)。
        • 好的,那你能解释一下你的游戏吗?你用它做什么?游戏引擎? DirectX等?你是如何定义瓷砖的?这样我可以给你一个具体的答案。
        • 这是一个用 REAL Studio 编写的游戏引擎。瓷砖是png图像。这是我用来在屏幕上放置图块的代码: x = column * (Data.TileWidth/2) + (row * (TileWidth/2)) + Origin.X y = column * (TileHeight/2) - (行 * (TileHeight/2)) + Origin.Y。其中 Origin 是地图的起点(处理滚动),x 和 y 是实际坐标。
        【解决方案5】:

        我认为你可以使用Pythagoras' theorem

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

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

        【讨论】:

        • 这适用于计算矩形的宽度和高度(以及将地图一分为二的三角形的斜边),但不适用于地图的宽度。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-17
        • 2012-09-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多