Skip to content

Instantly share code, notes, and snippets.

@lhog
Last active January 11, 2024 22:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lhog/3d9a1d4f5b592b05c0e922cc92cbb54d to your computer and use it in GitHub Desktop.
Save lhog/3d9a1d4f5b592b05c0e922cc92cbb54d to your computer and use it in GitHub Desktop.
UV coordinates of a quad from its 2D coordinate
float cross2d(vec2 v1, vec2 v2) {
return v1.x * v2.y - v1.y * v2.x;
}
// https://www.uio.no/studier/emner/matnat/ifi/nedlagte-emner/INF4360/h10/undervisningsmateriale/bc_lecture.pdf
bool GetQuadUV(vec2 p00, vec2 p10, vec2 p01, vec2 p11, vec2 p, out vec2 uv) {
vec2 a = p00 - p;
vec2 b = p10 - p00;
vec2 c = p01 - p00;
vec2 d = p00 - p10 - p01 + p11;
float cxd = cross2d(c, d);
float cxb = cross2d(c, b);
float axd = cross2d(a, d);
float axb = cross2d(a, b);
float cxbPaxd = ( cxb + axd);
float bxcPaxd = (-cxb + axd);
float bxd = cross2d(b, d);
float axc = cross2d(a, c);
if (cxd == 0.0) {
uv.x = -axb / cxbPaxd;
} else {
float D = cxbPaxd * cxbPaxd - 4.0 * cxd * axb;
float Dsqrt = sqrt(D);
float x1 = (-cxbPaxd + Dsqrt) / (2.0 * cxd);
float x2 = (-cxbPaxd - Dsqrt) / (2.0 * cxd);
uv.x = mix(x1, x2, float(x1 < 0.0 || x1 > 1.0));
}
if (bxd == 0.0) {
uv.y = -axc / bxcPaxd;
} else {
float D = bxcPaxd * bxcPaxd - 4.0 * bxd * axc;
float Dsqrt = sqrt(D);
float x1 = (-bxcPaxd + Dsqrt) / (2.0 * bxd);
float x2 = (-bxcPaxd - Dsqrt) / (2.0 * bxd);
uv.y = mix(x1, x2, float(x1 < 0.0 || x1 > 1.0));
}
return all(greaterThanEqual(uv, vec2(0))) && all(lessThanEqual(uv, vec2(1)));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment