Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 在世界坐标中使用SVG图像中的屏幕坐标进行Hittest_Delphi_Svg_Gdi+_Hittest - Fatal编程技术网

Delphi 在世界坐标中使用SVG图像中的屏幕坐标进行Hittest

Delphi 在世界坐标中使用SVG图像中的屏幕坐标进行Hittest,delphi,svg,gdi+,hittest,Delphi,Svg,Gdi+,Hittest,如何使用GDI+将鼠标坐标转换为世界坐标? 或者为使用GDI+绘制的SVG形状获取边界框(甚至更好)旧skool区域 无论如何。我一直在寻找SVG代码,发现: 这是第一个真正适用于SVG的Delphi组件,但我离题了 此组件使用GDI+显示圆、曲线等。 GDI+使用矩阵将世界坐标、旋转和扭曲转换为屏幕坐标。 这部分我理解。您可以使用矩阵乘法进行转换 问题在于 如果将鼠标光标指向闭合形状上: 我从何处获得矩阵,该矩阵将我的鼠标屏幕点转换为一个世界点,我可以将其点击到屏幕上绘制的圆圈中? 在所有这

如何使用GDI+将鼠标坐标转换为世界坐标? 或者为使用GDI+绘制的SVG形状获取边界框(甚至更好)旧skool区域

无论如何。我一直在寻找SVG代码,发现:

这是第一个真正适用于SVG的Delphi组件,但我离题了

此组件使用GDI+显示圆、曲线等。
GDI+使用矩阵将世界坐标、旋转和扭曲转换为屏幕坐标。
这部分我理解。您可以使用矩阵乘法进行转换

问题在于
如果将鼠标光标指向闭合形状上:

  • 我从何处获得矩阵,该矩阵将我的鼠标屏幕点转换为一个世界点,我可以将其点击到屏幕上绘制的圆圈中?
    在所有这些GDI对象中有很多矩阵可供选择
  • 请不要告诉我有关绘制位图和测试光标下的神奇颜色的内容,这不是我要找的
  • 如果有一个矩阵链,我如何以正确的(颠倒的?)顺序遍历它们,以便屏幕坐标被正确引导到世界坐标
  • 换句话说
    从SVG图像读入的形状是原语,会被矩阵扭曲为屏幕坐标。 如何将屏幕坐标转换为可以用来查看是否在形状内部的坐标

    请注意 我需要知道我处于哪种状态。
    由于SVG图像的设置方式,每个形状都有一个id,我想用它来查看我用鼠标点击的区域

    编辑

    或者

  • 我可以得到屏幕坐标中每个形状的边界矩形,这样我就可以对照它检查鼠标坐标
  • 我可以得到一个旧的skool GDI区域,在那里我可以用屏幕坐标做一个PTIN区域

  • 希望您能帮助我找到解决所有这些扭曲路径的方法:-)。

    我没有深入研究代码,但我可以在矩阵方面提供一些帮助(第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+使用矩阵进行转换。矩阵做旋转和剪切(新)以及平移和缩放(旧)。我有做矩阵变换的函数,这不是问题所在。我只是不知道从哪里得到世界->屏幕转换使用的矩阵(倍数)。我不知道原始转换在哪里完成的顺序。因此,我无法创建