I could do a line intersection between, say, PV1 and AB and then project that onto AB to find the factor, but I'm wondering if there's an easier way.
Thanks!
I could do a line intersection between, say, PV1 and AB and then project that onto AB to find the factor, but I'm wondering if there's an easier way.
Thanks!
Build vectors $CD, DA, AB, BC$.
Now $OC +k_1CD+k_2DA+k_3AB+k_4BC, k_i \in [0,1]$ can represent any position inside.
Since they are linearly dependent the representation $\{k_1,k_2,k_3,k_4\}$ can't be unique. But if we impose $k_i \in [0,k_{i-1}]$ maybe they will be? Otherwise some slight regularization will probably work well enough.
Let’s expand on your idea first. It’s easy to find the lines $\overline{V_1P}$ and $\overline{V_2P}$ and their intersections with the sides of the quadrilateral. (I’m assuming that’s what you meant since if you’re just going to project onto the sides, there’s no particular reason to involve $V_1$ and $V_2$). You can then find the portion of the distance along the side that this intersection represents with a division.
Working in homogeneous coordinates, we have $V_1=(A\times B)\times(C\times D)$ and $V_2=(A\times D)\times(B\times C)$. Choose two adjacent sides for your references, let’s say $AB$ and $AD$. $\overline{PV_1}$ and $\overline{AD}$ intersect at $P_1=(P\times V_1)\times(A\times D)$. (This method of using cross products to find the intersection of lines is Cramer’s rule in disguise.) Convert to Cartesian coordinates and then divide the difference between $x$- or $y$-coordinates of $P_1$ and $A$ by the difference between the corresponding coordinates of $D$ and $A$ (whichever difference is non-zero). This will give you a “$y$-offset” of $P$ relative to the quadrilateral. A similar computation will give you the “$x$-offset.”
For example, let the four corners be $A(1,0)$, $B(8,-1)$, $C(6,4)$, $D(2,3)$. We thus have $V_1=((1, 0, 1)\times(8, -1, 1))\times((6, 4, 1)\times(2, 3, 1))=(66,-11,-11)$, which is $(-6,1)$ in Cartesian coordinates. $V_2=(44,88,11)$, which is $(4,9)$ in Cartesian coordinates. Taking $P(4,2)$, we can compute $$\begin{align}P_1 &= ((4,2,1)\times V_1)\times(A\times D) \\ &= (506,561,319)\end{align}$$ which is $\left(\frac{46}{29},\frac{51}{29}\right)$ in Cartesian coordinates. $D-A=(1,3)$, so I’ll choose to work with $x$-coordinates of these points to get the “$y$-offset”: $\left(\frac{46}{29}-1\right)/1=\frac{17}{29}\approx0.586$. I’ll leave working out the “$x$-offset” to you.
The above is a fairly straightforward computation, but the method has a possible flaw depending on what you want this number for: the offsets depend on the sides that you chose. If we redo the above computation with $BC$ instead of $AD$, we end up with $0.654$ instead. There’s a fairly simple way to ensure that the offsets at both sides are consistent, and that’s to treat the quadrilateral as a perspective projection of the unit square. This answer gives a straightforward way to construct the necessary projection matrix; this answer has an explicit, albeit more complicated direct formula.
Following the construction in the first link, first compute the matrix $D$ that maps the standard basis to the unit square (this will be the same for all quadrilaterals that you are trying to rectify): $$\begin{bmatrix}0&1&0\\0&0&1\\1&1&1\end{bmatrix}^{-1}\begin{bmatrix}1\\1\\1\\\end{bmatrix}=\left[\begin{array}{r}-1\\1\\1\end{array}\right]$$ so $$D=\begin{bmatrix}0&1&0\\0&0&1\\1&1&1\end{bmatrix}\left[\begin{array}{rcc}-1&0&0\\0&1&0\\0&0&1\end{array}\right]=\left[\begin{array}{rcc}0&1&0\\0&0&1\\-1&1&1\end{array}\right].$$ For the mapping $S$ from the standard basis to the above quadrilateral we have: $$\left[\begin{array}{crc}1&8&2\\0&-1&3\\1&1&1\end{array}\right]^{-1}\begin{bmatrix}6\\4\\1\end{bmatrix}=\left[\begin{array}{r}-1\\\frac12\\\frac32\end{array}\right]$$ and so $$S=\left[\begin{array}{crc}1&8&2\\0&-1&3\\1&1&1\end{array}\right]\left[\begin{array}{rcc}-1&0&0\\0&\frac12&0\\0&0&\frac32\end{array}\right]=\left[\begin{array}{rrc}-1&4&3\\0&-\frac12&\frac92\\-1&\frac12&\frac32\end{array}\right].$$ The projective map that takes the quadrilateral to the unit square is then given by the matrix (using the adjugate instead of the inverse as recommended)$$M=DS^{adj}=\left[\begin{array}{crr}-\frac92&\frac32&\frac92\\-\frac12&-\frac72&\frac12\\-2&\frac52&-\frac{29}2\end{array}\right].$$ (You can multiply this matrix by $2$ or any other non-zero constant to simplify further calculations without affecting the results.) We can check a couple of the corners: $M[1,0,1]^T=[0,0,-33/2]^T$, which is equivalent to Cartesian $(0,0)$ and $M[8,-1,1]^T=[-33,0,-33]^T$, which is Cartesian $(1,0)$ as required. Applying this matrix to $P$ results in $\left[-\frac{21}2,-\frac{17}2,-\frac{35}2\right]^T$, which in Cartesian coordinates is $\left(\frac35,\frac{17}{35}\right)\approx(0.6,0.486)$.
The order of the four corner points doesn’t matter when building these matrices as long as you use a consistent order for both.
Effectively, using a perspective projection builds a non-uniformly spaced grid on the quadrilateral. You give up a uniform spacing along an edge, but you gain consistency along lines through $V_1$ and $V_2$, which are the vanishing points of the perspective. If your quadrilateral is the result of a perspective projection in the first place, this, of course, is the correct way to invert the mapping.