這個數學不是特定于平臺的,我會用任何語言作為答案。這很難解釋我為什么要這樣做,但我會嘗試包含影像。
我有一個將地圖作為容器覆寫的視圖(視圖 A)。目的是包含我們的內容,同時在用戶拖動地圖時保持固定在地圖上。該視圖有一個坐標系,其原點位于螢屏的左上角。這將是我們的絕對坐標系,我們試圖在其中轉換位置。

接下來,我們在視圖 A 和螢屏上可見的內容之間的交集處形成了一個 Rectangle。我通過 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
}
This returns said Rectangle with an origin relative to the origin of View A. The purpose of this Rectangle is that Metal View cannot be too large, so I limited Metal View to drawing within what is visible exclusively while maintaining the exact coordinates of where Metal View will be drawn in relation to View A.
I've been able to verify that the relative origin of the Rectangle within View A is accurate, and I've verified that Metal View fits within the Rectangle.
Here's what I keep banging my head on: Metal vertex functions have a center coordinate system that spans from -1 to 1 for the entire width and height as shown in the following figure (except I'm only using it in 2D space so ignore z position):

Now my question is:
If I have a point found in the top left quadrant of the Metal View (-0.002, 0.5), how would I take the given information to find it's position in View A? How would I return the point's position in View A to Metal View accounting for the relatively positioned Rectangle?
Visual
Here's a visual for hopeful clarification:

Edit
I was able to convert from View A to Metal View if Metal View takes up the entire span of View A with the following text code:
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)
But now I need to calculate as if Metal View fills the Rectangle which is only a portion of View A.
uj5u.com熱心網友回復:
我找到了答案并使用 Python 來提高可讀性。
視圖 A 為 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}")
這是一個非常小眾的問題,但是如果您遇到類似的問題,請發表評論,我會盡力擴展。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/449659.html
標籤:ios swift user-interface metal
