Joh*_*ica 17 delphi svg gdi+ hittest
如何使用GDI +将鼠标坐标转换为世界坐标?或者使用GDI +绘制SVG形状的边界框(甚至更好)旧的skool区域?
无论如何.我一直在寻找SVG代码并找到:
http://development.mwcs.de/svgimage.html
这是第一个真正适用于SVG的Delphi组件,但我离题了.
该组件使用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;
Run Code Online (Sandbox Code Playgroud)
在任何绘图之前,该方法调用Graphics.GetTransform(M).反过来,这个调用GdipGetWorldTransform,它似乎是WinAPI的GetWorldTransform上的包装函数.
我想,这可能是一个好的开始:)
| 归档时间: |
|
| 查看次数: |
1774 次 |
| 最近记录: |