<p>I realize that the solution I'm giving further below is basically the one you mentioned in your question. So let's begin by addressing this:</p>

<blockquote>
  <p>The solution in question assumes that M° is linear.. if that was the case you can have:</p>
  
  <p>M°(P) = alpha*M°(A) + beta * M°(B) + gamma*M°(C)</p>
  
  <p>But that is not the case (correct me if I'm wrong). </p>
</blockquote>

<p>The solution in question works directly in UV space. I don't see where it would make any assumptions concerning the nature or even existence of a "mapping from 3D to UV space"!? All it does assume is that UV coordinates vary linearly across each triangle (note: each triangle, not the entire mesh)&hellip;</p>

<p><span class="math-container">$$
\def\mvec#1{\begin{pmatrix}#1\end{pmatrix}}
\def\ivec#1{\left(\begin{smallmatrix}#1\end{smallmatrix}\right)}
\def\mmat#1{\begin{bmatrix}#1\end{bmatrix}}
\def\vec#1{\mathrm{\mathbf{#1}}}
\def\mat#1{\mathrm{\mathbf{#1}}}
$$</span></p>

<p>In general, the <span class="math-container">$u$</span> and <span class="math-container">$v$</span> coordinates at a point on a triangle's plane given by the affine coordinates <span class="math-container">$\lambda_1$</span> and <span class="math-container">$\lambda_2$</span> are
<span class="math-container">\begin{align}
  u &amp;= u_1 + \lambda_1 (u_2 - u_1) + \lambda_2 (u_3 - u_1) \\
  v &amp;= v_1 + \lambda_1 (v_2 - v_1) + \lambda_2 (v_3 - v_1)
\end{align}</span>
where <span class="math-container">$u_i$</span>, <span class="math-container">$v_i$</span> are the <span class="math-container">$u$</span>, <span class="math-container">$v$</span> coordinates at vertex <span class="math-container">$i$</span>. We can rewrite this as
<span class="math-container">\begin{equation}
  \mmat{
    u_2 - u_1 &amp; u_3 - u_1 \\
    v_2 - v_1 &amp; v_3 - v_1
  } \cdot \mvec{
    \lambda_1 \\
    \lambda_2
  } = \mvec{
    u - u_1 \\
    v - v_1
  }.
\end{equation}</span>
Knowing <span class="math-container">$u_i$</span> and <span class="math-container">$v_i$</span> at each vertex of a given triangle, we can compute
<span class="math-container">\begin{equation}
  \mat M = \mmat{
    u_2 - u_1 &amp; u_3 - u_1 \\
    v_2 - v_1 &amp; v_3 - v_1
  }.
\end{equation}</span>
We can then find the affine coordinates corresponding to the point with whatever <span class="math-container">$u$</span>, <span class="math-container">$v$</span> coordinates we want:
<span class="math-container">\begin{equation}
  \mvec{
    \lambda_1 \\
    \lambda_2
  } = 
  \mat M^{-1} \cdot \mvec{
    u - u_1 \\
    v - v_1
  }.
\end{equation}</span>
Note that these affine coordinates always exist as long as <span class="math-container">$\mat M^{-1}$</span> exists (which makes sense; there will always be exactly one point somewhere in the plane of the triangle where <span class="math-container">$u$</span> and <span class="math-container">$v$</span> reach whatever value you may be looking for as long as <span class="math-container">$u$</span> and <span class="math-container">$v$</span> vary independently). However, they will not necessarily fall inside the triangle.</p>

<p>So one way to find the point you're looking for would be to iterate over all triangles of the mesh and, for each triangle, compute <span class="math-container">$\mat M^{-1}$</span>, and <span class="math-container">$\lambda_1$</span> and <span class="math-container">$\lambda_2$</span> for <span class="math-container">$u = 0$</span> and <span class="math-container">$v = 0$</span>, and check whether
<span class="math-container">\begin{align}
  \lambda_1 &amp;\geq 0 &amp; &amp;\land &amp; \lambda_2 &amp;\geq 0 &amp; &amp;\land &amp; \lambda_1 + \lambda_2 &amp;\leq 1.
\end{align}</span>
If this is the case, you have found a triangle that contains a point at which <span class="math-container">$u = 0$</span> and <span class="math-container">$v = 0$</span>. You can then compute the coordinates of that point as
<span class="math-container">\begin{equation}
  \vec p = (1 - \lambda_1 - \lambda_2) \vec v_1 + \lambda_1 \vec v_2 + \lambda_2 \vec v_3
\end{equation}</span>
where <span class="math-container">$\vec v_1$</span>, <span class="math-container">$\vec v_2$</span>, and <span class="math-container">$\vec v_3$</span> are the coordinates of the respective triangle vertices.</p>

<p>It may make sense to, for example, use an initial check against a given triangle's bounding rectangle in UV space and/or other methods to quickly rule out triangles that cannot contain the coordinates of interest to speed up the search&hellip;</p>

CC BY-SA 4.0
2019-01-13T20:42:42.043Z
Yeah, that's basically the solution that I was talking about. The specific thing that I don't understand is how can you write p=v1 + lambda_1*v2 + lambda_2*v3
stackmann0
CC BY-SA 4.0
2019-01-13T21:12:12.423Z
@stackmann0 that's how u/v coordinates (or any attribute really) are interpolated over a triangle. General barycentric coordinates are not unique. So we turn to affine coordinates instead, which are just a normalized form of barycentric coordinates. Every linear combination of a triangle's vertices where all the coefficients sum to one uniquely identifies a point on the triangle's plane. If we know two of the coefficients, the third one is given by 1 - the rest. If you think about it: a triangle/plane is a 2D entity, so there's inherently only two degrees of freedom to fix on any point on it.
Michael Kenzel
CC BY-SA 4.0
2019-01-13T21:12:14.933Z
Furthermore, any point *inside* a triangle is uniquely identified by a [convex combination](https://en.wikipedia.org/wiki/Convex_combination) of the vertices, which is just a further constrained version of the affine coordinates from before where, in addition to summing to 1, all coordinates are nonnegative.
Michael Kenzel
CC BY-SA 4.0
2019-01-13T21:37:18.973Z
Also, this all makes a lot of sense if you just think about it geometrically: Basically, you start at any of the three vertices, walk some distance along the direction of one edge, and then some distance along the direction of another edge. Any unique combination of distances along two of the edges will take you to a unique point in the triangle's plane. And you'll never be able to leave this plane by just walking along triangle edges.
Michael Kenzel
CC BY-SA 4.0
2019-01-13T21:38:22.213Z
And if you walk both distances in the direction that each edge is pointing, and you never walk all the way to the next vertex along the first edge and you always stop short of the distance remaining to the third edge along the second edge from there, then you can never leave the triangle…
Michael Kenzel
CC BY-SA 4.0
2019-01-13T21:51:12.947Z
@stackmann0 sorry, I somehow overlooked that I actually had a mistake in that formula you mentioned in your comment above. Of course $\vec v_1$ should be weighed by $1 - \lambda_1 - \lambda_2$ to compute $\vec p$. fixed…
Michael Kenzel
CC BY-SA 4.0
2019-01-14T10:56:35.773Z
Thank you for the detailed explanation, but the way I see it is that you got two triangles: the one in UV space (with which we're getting lamba_1 and lambda_2) and the one we have in 3D space (part of the mesh). lambda_1 and lambda_2 are barycentric coordinates for a point inside a triangle in UV space, I don't see how they can be used for the 3D triangle without talking about the relationship between the two triangles.
I'm probably not seeing things clearly or I'm confusing things..
stackmann0
CC BY-SA 4.0
2019-01-14T11:59:47.010Z
@stackmann0 Each 3D triangle has a corresponding triangle in UV space. What you're looking for is any triangle that contains the point $(0,0)$ in UV space. To find this triangle, you only have to consider the UV space triangles. It's completely irrelevant where the corresponding triangles are located in 3D space. Only once you found a triangle that contains $(0,0)$ in UV space, you are interested in what point on the corresponding 3D triangle the UV point $(0,0)$ maps to. The mapping of the UV space triangle to the 3D triangle works as described above and can be inverted as described above…
Michael Kenzel
CC BY-SA 4.0
2019-01-14T12:13:55.543Z
Barycentric coordinates are independent of whatever coordinate system the triangle is embedded in. Think about barycentric coordinates as a way of describing a point on the plane of a triangle relative to the triangle itself. For example, the barycentric coordinates $(1, 1, 1)$ always identify the centroid of a triangle and $(1, 0, 1)$ will always be the point half way along the third edge, no matter what the coordinates the triangle's vertices may be…
Michael Kenzel
CC BY-SA 4.0
2019-01-15T15:21:52.030Z
I understand now.. Thank you for you explanation :)
stackmann0
CC BY-SA 4.0
2019-01-11T20:25:47.640Z
2019-01-13T21:49:36.183Z
2019-01-13T21:49:36.183Z
Michael Kenzel
<p>Michael Kenzel's answer gives a good general algorithm, but here's a "20% of the effort, 80% of the value" answer. Because <span class="math-container">$(u,v) \in [0,1]$</span> space is a square being filled with convex polygons, <span class="math-container">$(0,0)$</span> can only be mapped in one of two conditions:</p>

<ol>
<li><span class="math-container">$(0,0)$</span> is at a vertex; or</li>
<li>Some vertices have negative co-ordinates.</li>
</ol>

<p>Generally 2 is avoided when unwrapping your mesh unless you're using a texture in wrapped mode, which is quite unusual because it makes the seams on your mesh look bad. It's also ruled out by the condition in your question that "the UV mapping is one-to-one". So most of the time, if <span class="math-container">$(0,0)$</span> is present at all, it's at a vertex. That makes your algorithm very simple: just look through your vertices until you find one with those exact texture co-ordinates, and then read out the object-space position of that vertex.</p>

<p>It's actually more common for <span class="math-container">$(0,0)$</span> to not be present at all, (a) because you need to take special care with texture filtering when going up to the edge of the texture, and (b) unwrapping a shape into a mesh doesn't usually give you a convenient corner to place there. <a href="https://www.google.com/search?q=uv+unwrap&amp;tbm=isch" rel="nofollow noreferrer">The examples on this Google Image search</a> are a good illustration: of a few dozen examples on the first few pages, I only found a couple of UV maps where the net touched any of the corners.</p>

CC BY-SA 4.0
2019-01-13T14:22:06.560Z
2019-01-13T14:22:06.560Z
Dan Hulme
<p>I have a 3D triangular mesh(vertices, indices, uv coords) that I'm rendering to the screen. Let's assume that the UV mapping is one-to-one. I'm trying to find a way to find the 3D position of the point with UV coordinates equal to (0,0). I searched the internet but I only find answers that I don't find convincing. 
The solution that I found: </p>

<ul>
<li>Find, in UV space, the triangle that contains (0,0).. let's call it T </li>
<li>Calculate barycentric coordinates for (0,0) with respect to T </li>
<li>interpolate the 3D positions of T's vertices using barycentric coords to get the result. </li>
</ul>

<p>this seems wrong to me. Here's why: 
Let M be the mapping between 3D space and UV space that associates UV coords for every vertex. 
Let A,B and C be the vertices of T. 
Let P be the origin of UV space ( P = (0,0) ). </p>

<p>We have P = alpha*A + beta * B + gamma*C (alpha,beta and gamma are the barycentric coords of P with respect to T). 
We assumed the UV mapping to be one-to-one, so let M° be the inverse of M. 
We have : </p>

<p>M°(P) = M°(alpha*A + beta * B + gamma*C)</p>

<p>The solution in question assumes that M° is linear.. if that was the case you can have: </p>

<p>M°(P) = alpha*M°(A) + beta * M°(B) + gamma*M°(C)</p>

<p>But that is not the case (correct me if I'm wrong). </p>

<p>So is there a way to find the 3D position of a point with specific UV coords? </p>

<p>Thanks in advance.</p>

<3d><uv-mapping>
How to get the 3D position for the point with (0,0) UV coordinates?
stackmann0
# How to get the 3D position for the point with (0,0) UV coordinates?

(Asked by: username_0 on 2019-01-11)

I have a 3D triangular mesh(vertices, indices, uv coords) that I'm rendering to the screen. Let's assume that the UV mapping is one-to-one. I'm trying to find a way to find the 3D position of the point with UV coordinates equal to (0,0). I searched the internet but I only find answers that I don't find convincing.
The solution that I found:

* Find, in UV space, the triangle that contains (0,0).. let's call it T
* Calculate barycentric coordinates for (0,0) with respect to T
* interpolate the 3D positions of T's vertices using barycentric coords to get the result.

this seems wrong to me. Here's why:
Let M be the mapping between 3D space and UV space that associates UV coords for every vertex.
Let A,B and C be the vertices of T.
Let P be the origin of UV space ( P = (0,0) ).

We have P = alpha\*A + beta \* B + gamma\*C (alpha,beta and gamma are the barycentric coords of P with respect to T).
We assumed the UV mapping to be one-to-one, so let M° be the inverse of M.
We have :

M°(P) = M°(alpha\*A + beta \* B + gamma\*C)

The solution in question assumes that M° is linear.. if that was the case you can have:

M°(P) = alpha\*M°(A) + beta \* M°(B) + gamma\*M°(C)

But that is not the case (correct me if I'm wrong).

So is there a way to find the 3D position of a point with specific UV coords?

Thanks in advance.

**Tags:** 3d, uv-mapping


---

## 2 answers

### Answer by username_1 on 2019-01-11. Score: 1 | Accepted answer

I realize that the solution I'm giving further below is basically the one you mentioned in your question. So let's begin by addressing this:

> The solution in question assumes that M° is linear.. if that was the case you can have:
>
> M°(P) = alpha\*M°(A) + beta \* M°(B) + gamma\*M°(C)
>
> But that is not the case (correct me if I'm wrong).

The solution in question works directly in UV space. I don't see where it would make any assumptions concerning the nature or even existence of a "mapping from 3D to UV space"!? All it does assume is that UV coordinates vary linearly across each triangle (note: each triangle, not the entire mesh)…

$$
\def\mvec#1{\begin{pmatrix}#1\end{pmatrix}}
\def\ivec#1{\left(\begin{smallmatrix}#1\end{smallmatrix}\right)}
\def\mmat#1{\begin{bmatrix}#1\end{bmatrix}}
\def\vec#1{\mathrm{\mathbf{#1}}}
\def\mat#1{\mathrm{\mathbf{#1}}}
$$

In general, the $u$ and $v$ coordinates at a point on a triangle's plane given by the affine coordinates $\lambda\_1$ and $\lambda\_2$ are
\begin{align}
u &= u\_1 + \lambda\_1 (u\_2 - u\_1) + \lambda\_2 (u\_3 - u\_1) \\
v &= v\_1 + \lambda\_1 (v\_2 - v\_1) + \lambda\_2 (v\_3 - v\_1)
\end{align}
where $u\_i$, $v\_i$ are the $u$, $v$ coordinates at vertex $i$. We can rewrite this as
\begin{equation}
\mmat{
u\_2 - u\_1 & u\_3 - u\_1 \\
v\_2 - v\_1 & v\_3 - v\_1
} \cdot \mvec{
\lambda\_1 \\
\lambda\_2
} = \mvec{
u - u\_1 \\
v - v\_1
}.
\end{equation}
Knowing $u\_i$ and $v\_i$ at each vertex of a given triangle, we can compute
\begin{equation}
\mat M = \mmat{
u\_2 - u\_1 & u\_3 - u\_1 \\
v\_2 - v\_1 & v\_3 - v\_1
}.
\end{equation}
We can then find the affine coordinates corresponding to the point with whatever $u$, $v$ coordinates we want:
\begin{equation}
\mvec{
\lambda\_1 \\
\lambda\_2
} =
\mat M^{-1} \cdot \mvec{
u - u\_1 \\
v - v\_1
}.
\end{equation}
Note that these affine coordinates always exist as long as $\mat M^{-1}$ exists (which makes sense; there will always be exactly one point somewhere in the plane of the triangle where $u$ and $v$ reach whatever value you may be looking for as long as $u$ and $v$ vary independently). However, they will not necessarily fall inside the triangle.

So one way to find the point you're looking for would be to iterate over all triangles of the mesh and, for each triangle, compute $\mat M^{-1}$, and $\lambda\_1$ and $\lambda\_2$ for $u = 0$ and $v = 0$, and check whether
\begin{align}
\lambda\_1 &\geq 0 & &\land & \lambda\_2 &\geq 0 & &\land & \lambda\_1 + \lambda\_2 &\leq 1.
\end{align}
If this is the case, you have found a triangle that contains a point at which $u = 0$ and $v = 0$. You can then compute the coordinates of that point as
\begin{equation}
\vec p = (1 - \lambda\_1 - \lambda\_2) \vec v\_1 + \lambda\_1 \vec v\_2 + \lambda\_2 \vec v\_3
\end{equation}
where $\vec v\_1$, $\vec v\_2$, and $\vec v\_3$ are the coordinates of the respective triangle vertices.

It may make sense to, for example, use an initial check against a given triangle's bounding rectangle in UV space and/or other methods to quickly rule out triangles that cannot contain the coordinates of interest to speed up the search…

> **Comments:**
> **username_0**: Yeah, that's basically the solution that I was talking about. The specific thing that I don't understand is how can you write p=v1 + lambda_1*v2 + lambda_2*v3  
> **username_1**: @username_0 that's how u/v coordinates (or any attribute really) are interpolated over a triangle. General barycentric coordinates are not unique. So we turn to affine coordinates instead, which are just a normalized form of barycentric coordinates. Every linear combination of a triangle's vertices where all the coefficients sum to one uniquely identifies a point on the triangle's plane. If we know two of the coefficients, the third one is given by 1 - the rest. If you think about it: a triangle/plane is a 2D entity, so there's inherently only two degrees of freedom to fix on any point on it.  
> **username_1**: Furthermore, any point *inside* a triangle is uniquely identified by a [convex combination](https://en.wikipedia.org/wiki/Convex_combination) of the vertices, which is just a further constrained version of the affine coordinates from before where, in addition to summing to 1, all coordinates are nonnegative.  
> **username_1**: Also, this all makes a lot of sense if you just think about it geometrically: Basically, you start at any of the three vertices, walk some distance along the direction of one edge, and then some distance along the direction of another edge. Any unique combination of distances along two of the edges will take you to a unique point in the triangle's plane. And you'll never be able to leave this plane by just walking along triangle edges.  
> **username_1**: And if you walk both distances in the direction that each edge is pointing, and you never walk all the way to the next vertex along the first edge and you always stop short of the distance remaining to the third edge along the second edge from there, then you can never leave the triangle…  
> **username_1**: @username_0 sorry, I somehow overlooked that I actually had a mistake in that formula you mentioned in your comment above. Of course $\vec v_1$ should be weighed by $1 - \lambda_1 - \lambda_2$ to compute $\vec p$. fixed…  
> **username_0**: Thank you for the detailed explanation, but the way I see it is that you got two triangles: the one in UV space (with which we're getting lamba_1 and lambda_2) and the one we have in 3D space (part of the mesh). lambda_1 and lambda_2 are barycentric coordinates for a point inside a triangle in UV space, I don't see how they can be used for the 3D triangle without talking about the relationship between the two triangles. I'm probably not seeing things clearly or I'm confusing things..  
> **username_1**: @username_0 Each 3D triangle has a corresponding triangle in UV space. What you're looking for is any triangle that contains the point $(0,0)$ in UV space. To find this triangle, you only have to consider the UV space triangles. It's completely irrelevant where the corresponding triangles are located in 3D space. Only once you found a triangle that contains $(0,0)$ in UV space, you are interested in what point on the corresponding 3D triangle the UV point $(0,0)$ maps to. The mapping of the UV space triangle to the 3D triangle works as described above and can be inverted as described above…  
> **username_1**: Barycentric coordinates are independent of whatever coordinate system the triangle is embedded in. Think about barycentric coordinates as a way of describing a point on the plane of a triangle relative to the triangle itself. For example, the barycentric coordinates $(1, 1, 1)$ always identify the centroid of a triangle and $(1, 0, 1)$ will always be the point half way along the third edge, no matter what the coordinates the triangle's vertices may be…  
> **username_0**: I understand now.. Thank you for you explanation :)  

---

### Answer by username_2 on 2019-01-13. Score: 0

username_1's answer gives a good general algorithm, but here's a "20% of the effort, 80% of the value" answer. Because $(u,v) \in [0,1]$ space is a square being filled with convex polygons, $(0,0)$ can only be mapped in one of two conditions:

1. $(0,0)$ is at a vertex; or
2. Some vertices have negative co-ordinates.

Generally 2 is avoided when unwrapping your mesh unless you're using a texture in wrapped mode, which is quite unusual because it makes the seams on your mesh look bad. It's also ruled out by the condition in your question that "the UV mapping is one-to-one". So most of the time, if $(0,0)$ is present at all, it's at a vertex. That makes your algorithm very simple: just look through your vertices until you find one with those exact texture co-ordinates, and then read out the object-space position of that vertex.

It's actually more common for $(0,0)$ to not be present at all, (a) because you need to take special care with texture filtering when going up to the edge of the texture, and (b) unwrapping a shape into a mesh doesn't usually give you a convenient corner to place there. [The examples on this Google Image search](https://www.google.com/search?q=uv+unwrap&tbm=isch) are a good illustration: of a few dozen examples on the first few pages, I only found a couple of UV maps where the net touched any of the corners.


---

