Created
March 25, 2024 06:29
-
-
Save SabinT/3b8e643e1b4b245a119f03130e507805 to your computer and use it in GitHub Desktop.
Square to Quad homography (credits: hecomi)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
/// <summary> | |
/// Utility to map points inside a unit square (0,0)-(1,1) to a quad defined by 4 points. | |
/// Uses math from: | |
/// https://github.com/hecomi/uHomography/blob/master/Assets/uHomography/Runtime/Scripts/Homography.cs | |
/// Instructions to use for projection mapping: | |
/// * Gather screen coordinates of four corner points, and call UpdateMatrix with them. | |
/// * The Transform method now will map a point inside a unit square to an appropriate point on the screen quad. | |
/// * Create a subdivided quad with both coordinates and uvs from (0,0)-(1,1) | |
/// * Use the Transform method to get new coordinates, but keep the UVs the same. | |
/// Hecomi's github contains a shader based implementation (no need to subdivide) if you want to investigate that further. | |
/// </summary> | |
public class Homography | |
{ | |
private readonly float[] _matrix = new float[9]; | |
public Vector2 Transform(Vector2 pos) | |
{ | |
if (_matrix == null) | |
{ | |
return pos; | |
} | |
float s = _matrix[6] * pos.x + _matrix[7] * pos.y + _matrix[8]; | |
float x = (_matrix[0] * pos.x + _matrix[1] * pos.y + _matrix[2]) / s; | |
float y = (_matrix[3] * pos.x + _matrix[4] * pos.y + _matrix[5]) / s; | |
return new Vector2(x, y); | |
} | |
public void UpdateMatrix(Vector2 topLeft, Vector2 topRight, Vector2 bottomLeft, Vector2 bottomRight) | |
{ | |
Vector2 p00 = bottomLeft; | |
Vector2 p01 = bottomRight; | |
Vector2 p10 = topLeft; | |
Vector2 p11 = topRight; | |
var x00 = p00.x; | |
var y00 = p00.y; | |
var x01 = p01.x; | |
var y01 = p01.y; | |
var x10 = p10.x; | |
var y10 = p10.y; | |
var x11 = p11.x; | |
var y11 = p11.y; | |
var a = x10 - x11; | |
var b = x01 - x11; | |
var c = x00 - x01 - x10 + x11; | |
var d = y10 - y11; | |
var e = y01 - y11; | |
var f = y00 - y01 - y10 + y11; | |
var h13 = x00; | |
var h23 = y00; | |
var h32 = (c * d - a * f) / (b * d - a * e); | |
var h31 = (c * e - b * f) / (a * e - b * d); | |
var h11 = x10 - x00 + h31 * x10; | |
var h12 = x01 - x00 + h32 * x01; | |
var h21 = y10 - y00 + h31 * y10; | |
var h22 = y01 - y00 + h32 * y01; | |
// Update existing array | |
_matrix[0] = h11; | |
_matrix[1] = h12; | |
_matrix[2] = h13; | |
_matrix[3] = h21; | |
_matrix[4] = h22; | |
_matrix[5] = h23; | |
_matrix[6] = h31; | |
_matrix[7] = h32; | |
_matrix[8] = 1f; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment