Raytracing Problem: Solving the length of the opposite side of the right triangle where the adjacent side stops

116 Views Asked by At

I'm attempting to perform a raytrace without using the parametric formula for the ray, and using only geometry and trigonometry.

I wonder if it's possible to solve for the point $X$ given only the following:

  • Center of the plane $P$
  • The normal of the plane $\hat{N}$
  • The origin of the ray $R_o$
  • The ray vector $\vec{R}$ (shown as $v$ in the diagram)

I've gotten as far as deriving point A, which I can surmise can be solved using:

$$ A = R_o + (\vec{PR_o} \cdot \hat{N})\hat{N} $$

From here, I've arrived at a right triangle I could use to solve for X, if only I could solve for its opposite side.

Is this approach to raytracing at all possible in the first place?

Solve for X!

2

There are 2 best solutions below

2
On BEST ANSWER

Figured it out! If someone could verify/add to this answer, that would be appreciated!

What I failed to realize is that what I'm actually looking for is the tangent of the triangle, if we consider that the length of the adjacent angle is also the radius of a circle it forms. See diagram below:

enter image description here

By virtue of the handy-dandy mnemonic TOA (tangent is equal to opposite over adjacent):

(1)$$ \tan \theta = \frac{\Vert \overline{AX} \Vert}{\Vert \vec{R_oA} \Vert} $$

Solving for the opposite segment then gives us:

(2)$$ \Vert \vec{R_oA} \Vert \tan \theta = \Vert \overline{AX} \Vert $$

The unknown needed for this equation now is the angle $\theta$. This we can solve from CAH (cosine is equal to adjacent over hypotenuse):

(3)$$ \cos \theta = \frac{\Vert \vec{R_oA} \Vert}{\Vert \vec{R} \Vert} $$

Solving for the angle:

(4)$$ \theta = \arccos \biggl( \frac{\Vert \vec{R_oA} \Vert}{\Vert \vec{R} \Vert} \biggr) $$

The resulting $\theta$ can then be plugged into (2) to solve for $\Vert \overline{AX} \Vert$. The resulting scalar value can then be multiplied to $\hat{AP}$.

(5)$$ X = A + \hat{AP} \Vert \overline{AX} \Vert $$

Quod erat demonstrandum!

0
On

As an alternative to your approach, working in extended Euclidean space (i.e., projective space with a Euclidean geometry imposed on it) and using homogeneous coordinates provides a reasonably efficient way to compute the intersection of a ray (really a line) and plane directly.

To recap briefly, if the inhomogeneous Cartesian coordinate vector of a point $\tilde{\mathbf p}$ is $(x,y,z)^T$, then any vector of the form $\mathbf p = (kx,ky,kz,k)$ for $k\ne0$ is its homogeneous coordinate representation. To put it another way, we can form the homogeneous coordinates of a point by appending a $1$, and the resulting vector can be arbitrarily scaled without changing which point it represents. To convert back into inhomogeneous coordinates, simply divide through by the last element of the vector (unless it’s $0$, in which case you have a point at infinity, which I’ll talk about later). In a similar way, a plane in $\mathbb R^3$ can be represented by an element of $\mathbb R^4$: we can write the plane equation $ax+by+cz+d=0$ in vector form as $(a,b,c,d)\cdot(x,y,z,1)=0$, i.e., in the form $\mathbf\pi^T\mathbf x=0$.

Representing lines in 3D is awkward—witness the many way to represent them depending on what you want to do with the line. One way that you might not have seen is a Plücker matrix: given distinct points $\mathbf p$ and $\mathbf q$, the line through them can be represented by $L=\mathbf p\mathbf q^T-\mathbf q\mathbf p^T$. Note that this is a matrix: $\mathbf p\mathbf q^T$ is the outer product of the two vectors, as opposed to the inner (dot) product $\mathbf p^T\mathbf q$, which is a scalar. This particular representation is handy for the present problem: the intersection of this line with the plane $\mathbf\pi$ is simply given by $$L\mathbf\pi = (\mathbf p\mathbf q^T-\mathbf q\mathbf p^T)\mathbf\pi = (\mathbf\pi^T\mathbf q)\mathbf p-(\mathbf\pi^T\mathbf p)\mathbf q.\tag{*}$$ If this is equal to zero, then the line lies on the plane. I won’t justify this result here, other than to note that it can be viewed as an instance of Plücker’s mu, which gives you a mechanical way to find a linear combination of two equations that’s also satisfied by a point outside of their individual solution sets.

In your case, the point-normal equation of the plane is $\hat N\cdot(x,y,z) = \hat N\cdot P$, with corresponding homogeneous vector $\mathbf\pi = (\hat N;-\hat N\cdot P)^T$. Note that we don’t need a unit normal for this, which can be handy. For one point on the line we take the ray’s origin $\mathbf p=(R_0;1)^T$. For the other, we take the point at infinity $\mathbf q = (\vec R;0)^T$.† Substituting into (*), we get $$\begin{align} (\mathbf\pi^T\mathbf q)\mathbf p-(\mathbf\pi^T\mathbf p)\mathbf q &= (\hat N\cdot\vec R)(R_0;1) - (\hat N\cdot R_0-\hat N\cdot P)(\vec R;0) \\ &= \left((\hat N\cdot\vec R)R_0+\hat N\cdot(P-R_0)\vec R;\hat N\cdot\vec R\right)\end{align},$$ and dehomogenizing yields $$X = R_0+{\hat N\cdot(P-R_0)\over \hat N\cdot\vec R}\vec R.$$ If you fully expand the expression that you ended up with in your own solution, I think that you’ll end up with something quite similar, if not identical to this final expression.


† For each family of parallel lines, we add a “point at infinity” at which they all intersect. There is a distinct such point for each direction in $\mathbb R^3$, and its homogeneous coordinates have a $0$ for its last component. We can identify a direction vector $(x,y,z)^T\in\mathbb R^3$ with the point at infinity with homogeneous coordinates $(x,y,z,0)^T$.