Esta matemática no es específica de la plataforma y tomaré cualquier idioma como respuesta. Es difícil explicar por qué estoy haciendo esto, pero intentaré incluir imágenes.
Tengo una vista (Vista A) que se superpone a un mapa como contenedor. El propósito es contener nuestro contenido mientras permanece fijo en el mapa mientras el usuario arrastra el mapa. Esa vista tiene un sistema de coordenadas donde su origen está en la parte superior izquierda de la pantalla. Será nuestro sistema de coordenadas absolutas, donde estamos tratando de convertir las posiciones hacia y desde.
A continuación, tenemos un Rectángulo que se forma en la intersección entre la Vista A y lo que se ve en la pantalla. Lo logré con la siguiente propiedad en mi UIView:
var visibleRect: CGRect { guard let superview = self.superview?.superview else { return CGRect(x: 0, y: 0, width: 0, height: 0) } // Convert the superview's coordinate system to the current view's coordinate system and find the intersecting rectangle. This is so we don't have to render excessive particles. let val = self.bounds.intersection( self.convert(superview.frame, from: superview) ) return val }
Esto devuelve dicho Rectángulo con un origen relativo al origen de la Vista A. El propósito de este Rectángulo es que Metal View no puede ser demasiado grande, por lo que limité Metal View a dibujar dentro de lo que es visible exclusivamente mientras mantengo las coordenadas exactas de donde Metal View se dibujará en relación con la Vista A.
Pude verificar que el origen relativo del Rectángulo dentro de la Vista A es exacto, y verifiqué que la Vista de Metal encaja dentro del Rectángulo.
Esto es lo que sigo golpeando mi cabeza: las funciones de vértice de metal tienen un sistema de coordenadas central que se extiende de -1
a 1
para todo el ancho y la altura, como se muestra en la siguiente figura (excepto que solo lo estoy usando en el espacio 2D, así que ignore z posición):
Ahora mi pregunta es:
Si tengo un punto en el cuadrante superior izquierdo de la Vista de metal (-0.002, 0.5), ¿cómo tomaría la información dada para encontrar su posición en la Vista A? ¿Cómo devolvería la posición del punto en la Vista A a la Vista de metal teniendo en cuenta el Rectángulo relativamente posicionado?
Aquí hay una imagen para una aclaración esperanzadora:
Pude convertir de View A a Metal View si Metal View ocupa todo el espacio de View A con el siguiente código de texto:
def normalizedToViewA(x, y): x *= 1.0 y *= -1.0 x += 1.0 y += 1.0 return ((x / 2.0) * width, (y / 2.0) * height) def viewAToNormalized(x, y): normalizedX = x / (width / 2.0) normalizedY = y / (height / 2.0) normalizedX -= 1.0 normalizedY -= 1.0 normalizedX *= 1.0 normalizedY *= -1.0 return (normalizedX, normalizedY)
Pero ahora necesito calcular como si Metal View llenara el Rectángulo, que es solo una parte de View A.
Encontré la respuesta y he usado Python para la legibilidad.
La vista A es 1270*680.
# View A (Top Left Origin) width = 1270 height = 680 # Visible Rectangle (Top Left Origin) # with an origin as a position in View A subOriginX = 1000 subOriginY = 400 subWidth = 20 subHeight = 20 # Centered origin converted to top left origin # where origin is (0,0) def normalizedToSubview(x, y): x *= 1.0 y *= -1.0 x += 1.0 y += 1.0 return ((x / 2.0) * subWidth, (y / 2.0) * subHeight) # Top Left origin to centered origin def subviewToNormalized(x, y): normalizedX = x / (subWidth / 2.0) normalizedY = y / (subHeight / 2.0) normalizedX -= 1.0 normalizedY -= 1.0 normalizedX *= 1.0 normalizedY *= -1.0 return (normalizedX, normalizedY) # Relative position of a point within subview # but on View A's plane def subviewToViewA(x, y): return (x + subOriginX, y + subOriginY) # Relative position of a point within View A # but on the subview's plane def viewAToSubView(x, y): return (x - subOriginX, y - subOriginY) # Position within Metal View to a position within View A normalizedCoord = (0.0, 0.0) toSubview = normalizedToSubview(*normalizedCoord) viewACoord = subviewToViewA(*toSubview) print(f"Converted {normalizedCoord} to {toSubview}") print(f"Converted {toSubview} to {viewACoord}") # Converted (0.0, 0.0) to (10.0, 10.0) # Converted (10.0, 10.0) to (1010.0, 410.0) # Position within View A to Metal View backToSubview = viewAToSubView(*viewACoord) backToNormalized = subviewToNormalized(*backToSubview) # Converted (1010.0, 410.0) to (10.0, 10.0) # Converted (10.0, 10.0) to (0.0, -0.0) print(f"Converted {viewACoord} to {backToSubview}") print(f"Converted {backToSubview} to {backToNormalized}")
Este es un problema extremadamente específico, pero comente si enfrenta algo similar e intentaré expandirlo lo mejor que pueda.