Delphi 在世界坐标中使用SVG图像中的屏幕坐标进行Hittest
如何使用GDI+将鼠标坐标转换为世界坐标? 或者为使用GDI+绘制的SVG形状获取边界框(甚至更好)旧skool区域 无论如何。我一直在寻找SVG代码,发现:Delphi 在世界坐标中使用SVG图像中的屏幕坐标进行Hittest,delphi,svg,gdi+,hittest,Delphi,Svg,Gdi+,Hittest,如何使用GDI+将鼠标坐标转换为世界坐标? 或者为使用GDI+绘制的SVG形状获取边界框(甚至更好)旧skool区域 无论如何。我一直在寻找SVG代码,发现: 这是第一个真正适用于SVG的Delphi组件,但我离题了 此组件使用GDI+显示圆、曲线等。 GDI+使用矩阵将世界坐标、旋转和扭曲转换为屏幕坐标。 这部分我理解。您可以使用矩阵乘法进行转换 问题在于 如果将鼠标光标指向闭合形状上: 我从何处获得矩阵,该矩阵将我的鼠标屏幕点转换为一个世界点,我可以将其点击到屏幕上绘制的圆圈中? 在所有这
这是第一个真正适用于SVG的Delphi组件,但我离题了 此组件使用GDI+显示圆、曲线等。
GDI+使用矩阵将世界坐标、旋转和扭曲转换为屏幕坐标。
这部分我理解。您可以使用矩阵乘法进行转换 问题在于
如果将鼠标光标指向闭合形状上:
在所有这些GDI对象中有很多矩阵可供选择
从SVG图像读入的形状是原语,会被矩阵扭曲为屏幕坐标。 如何将屏幕坐标转换为可以用来查看是否在形状内部的坐标 请注意 我需要知道我处于哪种状态。
由于SVG图像的设置方式,每个形状都有一个id,我想用它来查看我用鼠标点击的区域 编辑 或者
希望您能帮助我找到解决所有这些扭曲路径的方法:-)。我没有深入研究代码,但我可以在矩阵方面提供一些帮助(第3点) 我猜,使用了三种基本变换矩阵:旋转矩阵、缩放矩阵和平移矩阵。让我们分别称它们为R、s和T 将矩阵应用于点有一个棘手的部分。例如,要平移该点,然后围绕原点中心旋转。换句话说,您希望将旋转应用于点平移的效果。因此,矩阵将按以下方式应用: R(T(p))=R*T*p=S 其中*是矩阵乘法。请注意,相乘矩阵的顺序与您的意图相反 然而,如果你想进行逆变换,除了颠倒矩阵的顺序,你还必须计算它们的逆矩阵。我们平移了点,然后旋转-现在我们将旋转它,然后再向后平移: T^-1(R^-1(S))=T^-1*R^-1*S=p 请注意,您不必计算每个矩阵的逆矩阵,因为显然t^-1(x)=t(-x),R^-1(角度)=R(-角度)等等。但是,您必须推导转换的参数,如果您只能访问转换矩阵,这可能不容易 我猜,世界坐标通过平移和缩放矩阵的组合转换为屏幕坐标。最后一个负责根据整个场景的缩放因子(以及,可能的,显示器的DPI)将单位从世界坐标“更改为像素”。另一方面,平移矩阵反映场景平移,可以在比例矩阵之前或之后应用;在第一种情况下,平移存储在世界坐标中,在第二种情况下,平移存储在屏幕坐标中 我还想,所有的对象变换都是在世界坐标系中进行的(这听起来比在屏幕坐标系中进行更方便)。因此,您可以预期,每个对象的点都会经历以下变换: W(S(R(T(p)))=W*S*R*T*p 其中W是世界到屏幕的变换,S是比例,R是旋转,T是平移 希望我至少帮了一点忙
更新日期17-04-2011 好的,我现在已经查看了代码内部。SVG对象的PaintTo方法如下所示:
procedure TSVG.PaintTo(Graphics: TGPGraphics; Bounds: TGPRectF;
Rects: PRectArray; RectCount: Integer);
var
M: TGPMatrix;
MA: TMatrixArray;
begin
M := TGPMatrix.Create;
try
Graphics.GetTransform(M);
try
M.GetElements(MA);
FInitialMatrix.Cells[0, 0] := MA[0];
FInitialMatrix.Cells[0, 1] := MA[1];
FInitialMatrix.Cells[1, 0] := MA[2];
FInitialMatrix.Cells[1, 1] := MA[3];
FInitialMatrix.Cells[2, 0] := MA[4];
FInitialMatrix.Cells[2, 1] := MA[5];
FInitialMatrix.Cells[2, 2] := 1;
SetBounds(Bounds);
Paint(Graphics, Rects, RectCount);
finally
Graphics.SetTransform(M);
end;
finally
M.Free;
end;
end;
在绘制任何图形之前,该方法调用Graphics.GetTransform(M)。这个函数反过来调用GdipGetWorldTransform,它似乎是WinAPI上的一个包装函数
我想,这可能是一个很好的开始:)使用GDI+你必须跟踪你所做的事情,因为GDI+本身在绘制像素后会忘记所有事情,但像素本身除外。SVG单元必须掌握绘制所有形状和设置GDI+视口所需的一切。因此,从SVG库中获取信息会更容易 您基本上是在问如何将光标的文字屏幕位置(X,Y)转换为SVG显示对象中光标的相对位置(也是X,Y)?1996年,我使用Delphi 1编写的第一个程序是一个软件,用于计算公顷面积并绘制多边形(方位角+距离)。我创建了一些代码,使用SetMapMode()、SetWindow(Org | Ext)、SetViewPort(Org | Ext)等调用将单词坐标转换到屏幕上。GDI+使用相同的调用?不,GDI+使用矩阵进行转换。矩阵做旋转和剪切(新)以及平移和缩放(旧)。我有做矩阵变换的函数,这不是问题所在。我只是不知道从哪里得到世界->屏幕转换使用的矩阵(倍数)。我不知道原始转换在哪里完成的顺序。因此,我无法创建