在平面上的世界空间单元中查找一个 (s, t) 纹理坐标单元的长度

Posted

技术标签:

【中文标题】在平面上的世界空间单元中查找一个 (s, t) 纹理坐标单元的长度【英文标题】:Find length of one (s, t) texture coordinate unit in world space units on a plane 【发布时间】:2017-03-12 05:51:22 【问题描述】:

已编辑:

我有一组纹理坐标和笛卡尔真实世界('世界空间')坐标(以米为单位),我想从这些坐标中找到每个形状的单个单位的世界空间长度st 纹理坐标,当对应于该长度的线在纹理空间中分别水平和垂直定向时。但是当我在纹理空间中没有至少一个水平方向的边缘和一个垂直方向的边缘时,我很难计算这一点。

基本上我希望能够找出 1 s 单位等于米以及 1 t 单位等于米。为了说明这一点,使用示例三角形 - 请参阅下面的坐标值列表 - 我想找到以米为单位的垂直和水平红色箭头线的长度......

(在给定等效坐标集的情况下,我还希望该解决方案适用于任何三角形或多边形)

这里的纹理映射是非参数的,所有 3D 点也是共面的,因此表面是可展开的。平面上世界空间中的映射是等距的(全局缩放),因此二维插值可以是线性的。

(因为我在 MATLAB 中工作 - 我是纹理映射,并且希望能够将可开发的全局缩放曲面上的任何纹理坐标转换为笛卡尔坐标)

例如,我有一组纹理坐标(s, t) 的三角形,如下所示...

编辑值(两次):

(1) 1.7942553649452966 0.8511551466745527
(2) 1.756240725743247 0.8674815156738774
(3) 1.730892921329496 0.8328561344213196
(1) 1.7942553649452966 0.8511551466745527

...具有对应的真实世界(笛卡尔)坐标(x, y, z),单位为米...

编辑值(两次):

(1) 660050.0702952344 5868605.033820355 20.442670747055647
(2) 660050.3347344951 5868606.121563466 20.574639679143946
(3) 660050.4376411334 5868606.55473629 19.53932546324279
(1) 660050.0702952344 5868605.033820355 20.442670747055647

仅供参考,这些来自 CityGML,它使用 COLLADA 方法进行纹理映射。

由于形状总是会形成一个平面,我可以很容易地生成平面方程,以及由每个顶点对表示的线方程。但是如果不知道平面上的线条相对于纹理空间中的水平和垂直方向的旋转,我看不到这些对我有什么帮助。所以从边缘上使用毕达哥拉斯开始是不可能的......?

我在想,这一定是很久以前那些编码对象查看器就已经解决的问题了,它们既可以纹理贴图又可以显示世界空间,但到目前为止我找不到解决方案...

仅供参考,这与我 here 的一个持续问题有关。

谢谢

【问题讨论】:

【参考方案1】:

我可能理解错了,但在这里。

您有一个具有世界空间笛卡尔坐标和纹理坐标的三角形,您想在每个纹理维度中找到一个单位的世界空间距离。

为方便起见,三角形顶点 A、B、C 是结构化的:

p:x,y,z,s,t 

计算单位T的世界空间距离:

对 S 方向的顶点进行排序 - 让我们将它们放在一个数组中 V[]

示例:如果B.s < A.s < C.s 那么:

V[0] = B
V[1] = A 
V[2] = C 

沿着与V[1] 相交的边缘找到分数。 (即在T方向投影)

fraction = (V[1].s-V[0].s)/(V[2].s-V[0].s)

通过V[0] and V[2] 之间的线性插值查找边缘上该点的坐标。 (插入对象中的所有标量)

P = (V[0] * (1 - fraction)) + (V[2] * fraction)

现在你在 T 中有一个垂直对齐跨度的端点,并且可以找到它的长度:

dT = abs(V[1].t - P.t)

你可以用毕达哥拉斯计算那个跨度的世界空间距离:

dW = distanceBetween(V[1].p, P.p)

那么一个单位T的世界空间距离:

uT = dW/dT

你当然可以对 S 做同样的事情。

编辑:更多细节......

在上图中,想法是计算出 P 的坐标。一旦你有了这个,你就可以计算出线 V[1]-Pt 方向和x,y,z 方向上的长度,这就足够了得到你想要的结果。

如果我们知道沿线V[0]V[2](分数)的P的标量(0->1)参数,那么我们可以通过线性插值找到所有分量P(x,y,z,t)。事实证明,该参数与V[1]V[1]S 组件沿V[0]V[2]S 的跨度相同,如红色水平线所示。

Linear interpolation is like a weighted blend。假设分数是 0.33,那么您可以添加:V[2]*0.33 + V[0]*(1 - 0.33) 以找到两者之间的点。它适用于所有组件,因为线 V[0]V[2] 在笛卡尔空间和纹理空间中是一条直线。如果您在这些顶点上存储了其他值,例如 RGBA 中的每个顶点颜色,您可以以相同的方式对它们进行插值并知道 P 处的颜色和 alpha 值。

【讨论】:

看起来不错,谢谢:根据我的值,我得到 uT 为 25.55m 和 uS 为 27.54m;检查每条边的结果,我形成一个 2D 直角三角形,找到对边和相邻的纹理空间长度(在 st 轴上对齐),将它们乘以 uT 或 uS,然后使用毕达哥拉斯得到斜边长度并用边检查结果使用 3D 毕达哥拉斯计算的长度...在将您的答案列为答案之前只需一个查询,& 我在这里可能有点昏暗抱歉:您为什么要这样做线性插值步骤以及为什么线性插值步骤适用于所有标量(s、t、x、y 和 z)? 嗨@JonSlade 我用我脑海中的图表更新了答案:) 谢谢,已更新为已回答。仅供参考,我的意思是 uT(用于 t)和 uT(用于 s)而不是 uT 和 uS

以上是关于在平面上的世界空间单元中查找一个 (s, t) 纹理坐标单元的长度的主要内容,如果未能解决你的问题,请参考以下文章

切割模型固定写死了切平面方程是y=0.1

glm::unProject 问题,世界到屏幕空间对齐错误

查找您可以在坐标平面中采用的路径数的算法

opengl中3d空间平面上的程序网格

平面 题解

三角测量在3D空间的任意平面上的点集