我正在使用 Cairo Graphics 和 RichClient6(它是一个包装器),但我相信这个事实并不那么重要。
我需要获取路径的范围。这工作得很好,但当矩阵旋转时就不行了。我不明白在这种情况下会发生什么,而且我自己还无法解决它。
我想问是否有人知道我需要做什么不同的事情,以便即使在旋转矩阵时也能可靠地获得范围。
谢谢你。
以下是一些显示范围如何变化的输出:
Angle: 1, Path Extents: -2,8 -6 343,8 169
Angle: 2, Path Extents: -5,7 -11,9 346,7 174,9
Angle: 3, Path Extents: -8,5 -17,8 349,5 180,8
Angle: 4, Path Extents: -11,3 -23,7 352,3 186,7
Angle: 5, Path Extents: -14,2 -29,6 355,2 192,6
Angle: 6, Path Extents: -16,9 -35,4 357,9 198,4
Angle: 7, Path Extents: -19,7 -41,2 360,7 204,2
Angle: 8, Path Extents: -22,5 -47 363,5 210
Angle: 9, Path Extents: -25,2 -52,7 366,2 215,7
Angle: 10, Path Extents: -27,9 -58,3 368,9 221,3
Angle: 11, Path Extents: -30,5 -63,9 371,5 226,9
Angle: 12, Path Extents: -33,2 -69,4 374,1 232,3
Angle: 13, Path Extents: -35,7 -74,7 376,7 237,7
Angle: 14, Path Extents: -38,3 -80 379,3 243
Angle: 15, Path Extents: -40,7 -85,2 381,7 248,3
Angle: 16, Path Extents: -43,2 -90,4 384,2 253,4
Angle: 17, Path Extents: -45,6 -95,3 386,6 258,3
Angle: 18, Path Extents: -47,9 -100,2 388,9 263,2
Angle: 19, Path Extents: -50,2 -105 391,2 268
Angle: 20, Path Extents: -52,4 -109,6 393,4 272,6
Angle: 21, Path Extents: -54,5 -114,1 395,5 277,1
Angle: 22, Path Extents: -56,6 -118,4 397,6 281,4
Angle: 23, Path Extents: -58,6 -122,6 399,6 285,6
Angle: 24, Path Extents: -60,6 -126,7 401,6 289,7
Angle: 25, Path Extents: -62,4 -130,6 403,4 293,6
Angle: 26, Path Extents: -64,2 -134,4 405,2 297,4
Angle: 27, Path Extents: -65,9 -137,9 406,9 300,9
Angle: 28, Path Extents: -67,6 -141,4 408,6 304,4
Angle: 29, Path Extents: -69,1 -144,6 410,1 307,6
Angle: 30, Path Extents: -70,6 -147,7 411,6 310,7
Angle: 31, Path Extents: -72 -150,5 413 313,5
Angle: 32, Path Extents: -73,3 -153,2 414,3 316,2
Angle: 33, Path Extents: -74,5 -155,8 415,5 318,8
Angle: 34, Path Extents: -75,6 -158,1 416,6 321,1
Angle: 35, Path Extents: -76,6 -160,2 417,6 323,2
Angle: 36, Path Extents: -77,5 -162,2 418,5 325,2
Angle: 37, Path Extents: -78,3 -163,9 419,3 326,9
Angle: 38, Path Extents: -79,1 -165,4 420,1 328,4
Angle: 39, Path Extents: -79,7 -166,8 420,7 329,8
Angle: 40, Path Extents: -80,3 -167,9 421,3 330,9
Angle: 41, Path Extents: -80,7 -168,8 421,7 331,8
Angle: 42, Path Extents: -81,1 -169,6 422,1 332,6
Angle: 43, Path Extents: -81,3 -170,1 422,3 333,1
Angle: 44, Path Extents: -81,5 -170,4 422,5 333,4
Angle: 45, Path Extents: -81,5 -170,5 422,5 333,5
Angle: 46, Path Extents: -81,5 -170,4 422,5 333,4
Angle: 47, Path Extents: -81,3 -170,1 422,3 333,1
Angle: 48, Path Extents: -81,1 -169,6 422,1 332,6
Angle: 49, Path Extents: -80,7 -168,8 421,7 331,8
Angle: 50, Path Extents: -80,3 -167,9 421,3 330,9
Angle: 51, Path Extents: -79,7 -166,8 420,7 329,8
Angle: 52, Path Extents: -79,1 -165,4 420,1 328,4
Angle: 53, Path Extents: -78,3 -163,9 419,3 326,9
Angle: 54, Path Extents: -77,5 -162,2 418,5 325,2
Angle: 55, Path Extents: -76,6 -160,2 417,6 323,2
这是代码:
Public Sub DrawTo(ByRef uDestCC As cCairoContext, ByVal uLeft As Long, ByVal uTop As Long)
Dim dblOffx As Double: Dim dblOffy As Double
' Calculate offsets based on alignment and scaling
dblOffx = Me.AlignmentFactorX * ((m_Img.width * Me.ScaleFactorW) / 2)
dblOffy = Me.AlignmentFactorY * ((m_Img.height * Me.ScaleFactorH) / 2)
Dim dblNewX1 As Double : Dim dblNewY1 As Double
dblNewX1 = (uLeft + dblOffx)
dblNewY1 = (uTop + dblOffy)
Dim dblNewX2 As Double : Dim dblNewY2 As Double
dblNewX2 = -(m_Img.width / 2) - (Me.CenterOffsetX / 2)
dblNewY2 = -(m_Img.height / 2) - (Me.CenterOffsetY / 2)
m_Matrix.TranslateCoords dblNewX1, dblNewY1
m_Matrix.RotateCoordsDeg m_sngAngleDeg
m_Matrix.ScaleCoords Me.ScaleFactorW, Me.ScaleFactorH
m_Matrix.TranslateCoords dblNewX2, dblNewY2
' Set the final transformation
Set uDestCC.Matrix = m_Matrix
' Now draw the image with the same transformations
uDestCC.RenderSurfaceContent m_Img, 0, 0
' Define a rectangle path representing the image area after rotation is set
uDestCC.Rectangle 0, 0, m_Img.width, m_Img.height
' Get the extents now, with rotation already applied
uDestCC.GetPathExtents m_dblTopX, m_dblTopY, m_dblBottomRightX, m_dblBottomRightY
' Clear the path
uDestCC.ClearPath False
m_Matrix.ResetToIdentity
Debug.Print "Angle: " & m_sngAngleDeg & ", Path Extents:", Round(m_dblTopX, 1), Round(m_dblTopY, 1), Round(m_dblBottomRightX, 1), Round(m_dblBottomRightY, 1)
End Sub
我不会说这是什么语言,所以我只是猜测。
我需要获取路径的范围。这工作得很好,但当矩阵旋转时就不行了。我不明白在这种情况下会发生什么,而且我自己还无法解决它。
从这个描述来看,我猜你遇到了开罗的限制。在内部,cairo 始终在表面坐标中工作(即立即应用来自
cairo_rotate()
的任何旋转)。仅通过外部 API 才应用旋转。
因此,如果你在当前路径上添加一个圆心为 0, 0,半径为 10 的圆,cairo 内部会记录当前路径的范围是从 -10, -10 到 10, 10。所以在这一步,一个矩形被放在圆圈周围。如果您现在询问路径的范围,您将得到 -10, -10 到 10, 10。
让我们旋转 45° 重复此操作。 Cairo 在构造路径时立即应用此旋转,但在这种情况下并不重要,因为 0, 0 处的圆在旋转之前和之后看起来是相同的。然而,开罗内部仍然将范围记录为在表面坐标中从-10, -10到10, 10。如果你现在向 cairo 询问范围,它会是这样的:我不知道严格的范围,但我知道一切都在 -10, -10 到 10, 10 的矩形内。但是,你想要 45°对此进行轮换。所以我将旋转这个矩形。在用户空间中,其范围将类似于 -14.14、-14.14 到 14.14。
所以简短的版本:开罗跟踪表面坐标中的范围。仅当您要求时才计算用户坐标平移,并且在此步骤中对“绘制矩形”进行最坏情况分析。因此,您可以获得更大的范围。
我想问是否有人知道我需要做些什么不同的事情,以便即使在旋转矩阵时也能可靠地获得范围。
快速、自发且未经测试的想法:使用类似
cairo_copy_path_flat()
的内容来查询当前路径。我认为你得到的坐标将在用户空间中。因此,您可以在所有坐标上使用 min
和 max
自行计算其范围。