纹理坐标映射如何将一个正方形中的四个三角形的坐标映射到一个三角形中的四个三角形 [英] Texture coordinate mapping how to map coordinates of 4 triangles in a square to 4 triangles in a triangle
问题描述
给出下面的图片
1。我已根据Steven_W的反馈更新了图片,因此右侧图中的4个三角形而不是3个更有意义!
2。再次更新图像以将子三角形标记为灰色的A,B,C,D
什么是伪算法,用于在左侧正方形中映射坐标(x,y),以便在以矩形为边界的矩形内生成坐标(u,v)。右边的三角形,这样点就可以在映射点之间插值,如图所示?
1到4在三角形上从左到右等距,即使我的插图是在边缘处有点粗糙:)
这是为了从360度全景照片的上半部分为天空盒的盖子生成一个粗糙的面板。 / p>
基于反馈更新3
第一步似乎是确定基于(x,y)坐标的左侧图中的三角形
第二个斜率是计算出沿该三角形顶点的距离。然后使用这些距离获取右侧图中相关三角形的坐标
更新4-在左侧图中识别三角形的代码
公共函数TriangleIndex(ByVal x为整数,ByVal y为整数,ByVal w为整数,ByVal h为整数)整数
Dim AboveForwardSlashDiagonal如布尔值=(((((h * x)+(w * y))-(h * w))< 0)
Dim AboveBackSlashDiagonal如布尔值=((((h * x)-(w * y))> 0)
如果AboveForwardSlashDiagonal然后
如果AboveBackSlashDiagonal
return 2'C
else
return 3'D
结束,如果
否则
如果AboveBackSlashDiagonal
返回1'B
否则
返回0'A
如果
结束如果
结束功能
更新5-代码解决方案模板 >
w1和h1是左图的尺寸
w2和h2是右图的尺寸
私有函数TranslateToTriangle(ByVal x1作为整数,ByVal y1作为整数,ByVal w1作为整数,ByVal h1作为整数,ByVal w2作为整数,ByVal h2作为整数)作为System.Drawing.Point
Dim ReturnPoint作为新System.Drawing.Point
选择案例TriangleIndex(x1,y1,w1,h1)
case 0
案例1
案例2
案例3
最终选择
Return ReturnPoint
结束函数
根据三角形的长度更新6公式来计算三角形的面积-
私有函数AreaOfTriangle(ByVal LengthA为Single,ByVal LengthB为Single ,ByVal LengthC as Single)As Single
Dim Perimeter As Single = Leng thA + LengthB + LengthC
返回1/4 * Math.Sqrt(周长*(周长-2 * LengthA)*(周长-2 * LengthB)*(周长-2 * LengthC))
结束函数
让我们首先考虑三角形<$ c的情况$ c> a 。
假设您的原点位于第5点,则第1点和第2点的坐标为(-x0,y0)
和(x0,y0)
,我们应该具有以下内容。
从旧坐标开始的映射(x,y)
到新的(xnew,ynew)
必须是线性的。这意味着,我们得到了以下公式,它们的系数仍未定义:
xnew = A * x + B * y + C
ynew = D * x + E * y + F
如何确定系数?我们有三对值:(-x0,y0)-> (-x0,y0)
,(x0,y0)-> (-x0 / 2,y0)
和(0,0)-> (0,-y0)
。这样可以得到以下内容:
-x0 = -A * x0 + B * y0 + C(1)-x0 / 2 = A * x0 + B * y0 + C(3)
y0 = -D * x0 + E * y0 + F(2)y0 = D * x0 + E * y0 + F(4)
0 = A * 0 + B * 0 + C(5)
-y0 = D * 0 + E * 0 + F(6)
到目前为止很好。 (5)给我们 C = 0
,(6)给我们 F = -y0
。将(2)和(4)相加得到 2 * y0 = 2 * E * y0 + 2 *(-y0)
,因此 E = 2
。减去(2)和(4),我们得到 0 = 2 * D * x0
,因此 D = 0
。加(1)和(2)并考虑 C = 0
,我们得到-(3/4)* x0 = 2 * B * y0
,因此 B = -3 / 4 * x0 / y0
。最后,减去(1)和(2),我们得到 x0 / 2 = 2 * A * x0
,因此 A = 1/4
。
现在,我们可以写下所需的映射:
xnew = 0.25 * x-0.75 *(x0 / y0)* y
ynew = 2 * y-y0
以同样的方式,对于三角形 c
,我们获得:
xnew = -0.25 * x-0.25 *(x0 / y0)* y
ynew = -2 * y-y0
Given the image below
1. I have updated the image based on feedback from Steven_W so there are 4 triangles in the right hand diagram instead of 3 which makes more sense!
2. update image again to label sub triangles as A, B, C, D in grey
What is the pseudo algorithm for mapping a coordinate (x,y) in the left hand square such that a coordinate (u,v) is produced within the rectangle bounding the triangle on the right so that points are interpolated between the mapping points as illustrated on the diagram?
1 to 4 are equidistant on the triangle from left to right even though my illustration is a bit rough around the edges :)
This is to generate a rough and ready panel for the lid of a skybox from the top half a 360 degree panoramic photo.
update 3 based on feedback
The first step appears to be working out which triangle we are in for the left hand diagram based on the (x,y) coordinates.
The second steep is to work out the distance along the vertices of that triangle. Then use those distances to get the coordinates on the related triangle in the diagram on the right
update 4 - code to identify triangle in left hand diagram
Public Function TriangleIndex(ByVal x As Integer, ByVal y As Integer, ByVal w as integer, ByVal h as integer) as integer
Dim AboveForwardSlashDiagonal As Boolean = ((((h * x) + (w * y)) - (h * w)) < 0)
Dim AboveBackSlashDiagonal As Boolean = (((h * x) - (w * y)) > 0)
If AboveForwardSlashDiagonal Then
If AboveBackSlashDiagonal
return 2 ' C
else
return 3 ' D
end if
else
If AboveBackSlashDiagonal
return 1 ' B
else
return 0 ' A
end if
End If
End Function
update 5 - template for code solution
w1 and h1 are dimensions of left diagram w2 and h2 are dimensions of right diagram
Private Function TranslateToTriangle(ByVal x1 As Integer, ByVal y1 As Integer, ByVal w1 As Integer, ByVal h1 As Integer, ByVal w2 As Integer, ByVal h2 As Integer) As System.Drawing.Point
Dim ReturnPoint As New System.Drawing.Point
select case TriangleIndex(x1,y1,w1,h1)
case 0
case 1
case 2
case 3
end select
Return ReturnPoint
End Function
update 6 formula for area of triangle given it's lengths - which might be helpful in calculating barycentric weights?
Private Function AreaOfTriangle(ByVal LengthA As Single, ByVal LengthB As Single, ByVal LengthC As Single) As Single
Dim Perimeter As Single = LengthA + LengthB + LengthC
Return 1 / 4 * Math.Sqrt(Perimeter * (Perimeter - 2 * LengthA) * (Perimeter - 2 * LengthB) * (Perimeter - 2 * LengthC))
End Function
Let's consider first the case of the triangle a
.
Assuming that your origin is at point 5, the coordinates of points 1 and 2 are (-x0, y0)
and (x0, y0)
, we should have the following.
The mapping from the old coordinates (x, y)
into new (xnew, ynew)
must be linear. This means, we've got the following formulae with still undefined coefficients:
xnew = A*x + B*y + C
ynew = D*x + E*y + F
How can we determine the coefficients? We've got three pairs of values: (-x0, y0) -> (-x0, y0)
, (x0, y0) -> (-x0/2, y0)
and (0, 0) -> (0, -y0)
. This gives us the following:
-x0 = -A*x0 + B*y0 + C (1) -x0/2 = A*x0 + B*y0 + C (3)
y0 = -D*x0 + E*y0 + F (2) y0 = D*x0 + E*y0 + F (4)
0 = A*0 + B*0 + C (5)
-y0 = D*0 + E*0 + F (6)
Good so far. (5) gives us C = 0
, (6) gives F = -y0
. Adding (2) and (4) we get 2*y0 = 2*E*y0 + 2*(-y0)
, hence E = 2
. Subtracting (2) and (4) we get 0 = 2*D*x0
, hence D = 0
. Adding (1) and (2) and taking into account that C = 0
, we get -(3/4)*x0 = 2*B*y0
, hence B = -3/4*x0/y0
. Lastly, subtracting (1) and (2) we get x0/2 = 2*A*x0
, hence A = 1/4
.
Now, we can write down the needed mapping:
xnew = 0.25*x - 0.75*(x0/y0)*y
ynew = 2*y - y0
The same way, for triangle c
we obtain:
xnew = -0.25*x - 0.25*(x0/y0)*y
ynew = -2*y - y0
这篇关于纹理坐标映射如何将一个正方形中的四个三角形的坐标映射到一个三角形中的四个三角形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!