delphi svg gdi+ hittest

delphi - Hittest utilizando coordenadas de pantalla en imágenes SVG en coordenadas mundiales



gdi+ (2)

¿Cómo traduzco las coordenadas del mouse en coordenadas mundiales con GDI +? ¿O puede obtener recuadros de delimitación (o incluso mejor) regiones skool antiguas para las formas SVG dibujadas con GDI +?

De todas formas. He estado buscando el código SVG y he encontrado:
http://development.mwcs.de/svgimage.html
Este es el primer componente de Delphi que realmente funciona para SVG, pero estoy divagando.

Este componente usa GDI + para mostrar círculos, curvas, etc.
GDI + usa matrices para convertir coordenadas, rotaciones y distorsiones del mundo en coordenadas de pantalla.
Esta parte lo entiendo Usas la multiplicación de matrices para hacer la traducción.

El problema es esto
Si apunto el cursor de mi mouse sobre una forma cerrada:

  1. ¿De dónde sacaré la matriz de eso traducirá mi punto de pantalla de mi mouse a un punto mundial que pueda golpear en el círculo que veo dibujado en la pantalla?
    Hay tantas matrices para elegir en todos esos objetos GDI.
  2. Por favor , no me des nada sobre dibujar en un mapa de bits y probar colores mágicos bajo el cursor, esto no es lo que estoy buscando.
  3. Si hay una cadena de matrices, ¿cómo las recorro en el orden correcto (¿invertido?) Para que la coordenada de la pantalla se guíe correctamente a la coordenada mundial.

En otras palabras
Las formas que se leen desde una imagen SVG son primitivas que se distorsionan mediante matrices en coordenadas de pantalla. ¿Cómo hago el reverso de una coordenada de pantalla en las coordenadas que puedo utilizar para ver si estoy dentro de una forma o no?

Por favor, tenga en cuenta que necesito saber en qué forma estoy.
Debido a la forma en que se configura la imagen SVG, cada forma tiene una identificación, y quiero usar eso para ver qué región he golpeado con mi mouse.

EDITAR

Alternativamente

  1. ¿Puedo obtener un rectángulo delimitador por forma en las coordenadas de la pantalla para poder verificar las coordenadas de mi mouse con eso?
  2. ¿Puedo obtener una antigua región de Skool GDI donde puedo hacer una PtInRegion con coordenadas de pantalla?

Espero que puedas ayudarme a encontrar mi camino con todos estos caminos distorsionados :-).


Con GDI + tienes que hacer un seguimiento de lo que has hecho / has hecho como GDI +, olvida todo, excepto los propios píxeles después de dibujar los píxeles. La unidad SVG debe mantener la tachuela de todo lo necesario para dibujar todas las formas y establecer la ventana gráfica GDI +. Por lo tanto, sería más fácil obtener la información de la biblioteca SVG.


No profundicé en el código, pero puedo ayudar un poco con las matrices (punto 3).

Supongo que se utilizan las tres matrices de transformación básicas: la rotación, la escala y la matriz de traducción. Llamémoslos R, S y T, respectivamente.

Hay una parte difícil sobre la aplicación de matrices al punto. Diga, quiere traducir el punto y luego gire alrededor del centro de origen. En otras palabras, desea aplicar la rotación al efecto de la traducción del punto. Entonces, las matrices se aplicarán de la siguiente manera:

R (T (P)) = R * T * P = S

Donde * es la multiplicación de la matriz. Tenga en cuenta que el orden de las matrices multiplicadas se invierte en relación con su intención.

Sin embargo, si desea realizar la transformación inversa, además de invertir el orden de las matrices, también debe evaluar sus inversas. Traducimos el punto, luego giramos, así que ahora lo giraremos hacia atrás y luego lo traduciremos de nuevo:

T ^ -1 (R ^ -1 (S)) = T ^ -1 * R ^ -1 * S = P

Tenga en cuenta que no es necesario calcular el inverso de cada matríz, como obviamente T ^ -1 (x) = T (-x), R ^ -1 (ángulo) = R (-angulo) y así sucesivamente. Sin embargo, debería deducir el argumento de la transformación, que puede no ser fácil si solo tiene acceso a la matriz de transformación.

Supongo que las coordenadas mundiales se convierten en coordenadas de pantalla mediante una combinación de trasladar y matriz de escala. El último es responsable de "cambiar la unidad" de coordenadas mundiales a píxeles con respecto al factor de zoom de toda la escena (y, posiblemente, DPI de la pantalla). La matriz de traducción, por otro lado, refleja el panorama de escena y puede aplicarse antes o después de la matriz de escala; en el primer caso, la panorámica se almacena en coordenadas mundiales, en el segundo, la panorámica se almacena en coordenadas de pantalla.

También supongo que todas las transformaciones de objetos se están realizando en las coordenadas mundiales (me parece más conveniente que hacerlo en coordenadas de pantalla). Entonces, pueden esperar que el punto de cada objeto esté sujeto a la siguiente transformación:

W (S (R (T (P)))) = W * S * R * T * P,

donde W es la transformación de Mundo a Pantalla, S es escala, R es rotación y T es traducción.

Espero haber ayudado al menos un poco ...

Actualizado el 17-04-2011

Ok, he buscado dentro del código ahora. El método PaintTo del objeto SVG se ve así:

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;

Antes de cualquier dibujo, el método llama a Graphics.GetTransform (M). Éste, a su vez, llama a GdipGetWorldTransform, que parece ser una función de envoltura en GetWorldTransform de WinAPI .

Supongo que podría ser un buen lugar para comenzar :)