Making sure a vector is parallel to a plane

668 Views Asked by At

I have no background in Math nor any plans on becoming any good in it.

I've been slowly but surely making my way through writing some bits of code that involve NPC pathing in a video game. I'm stuck at one particular spot that I'm sure is easy peasy for anyone with even a basic understanding of geometry. Incredibly challenging for someone who hasn't done any geometry since junior high.

I have a plane P which is defined by its normal vector {x, y, z}

I need to find a vector V that will move in the X, Y direction I need, but stay parallel to the plane P. X and Y can change but must remain proportional to each other, so the general direction of the vector is the same when ignoring the Z axis (looking from above...), but parallel to the plane P.

Not sure I'm being clear.

Rephrasing:

I have an object that I need to make slide in a particular X, Y direction in a 3D world, but it must slide parallel to the plane P that happens to be the ground, of which I know the normal vector. I need to find the X, Y, Z vector for the object that will make sure it never intersects with the plane P.

I've tried googling around, playing around with different things such as the dot product and whatnot. Thought I'd just ask you guys.

Thanks in advance!

3

There are 3 best solutions below

0
On

Let $(x,y,z)$ be the normal vector of the plane. Then a vector $(X,Y,Z)$ is parallel to the plane if and only if $$xX+yY+zZ=0.$$

0
On

A plane is actually defined by its normal vector $\vec{n}$ and its signed distance from origin $d$: point $\vec{p}$ is on the plane if and only if $$\vec{n} \cdot \vec{p} = d \tag{1}\label{AC1}$$ When you know the normal of the plane, and at least one point $\vec{p}$ on the plane, you can determine the signed distance from origin $d$ using that same equation. You can can multiply both $\vec{n}$ and $d$ by any nonzero real number, without affecting the plane or its location at all. (It is common to divide both by $\sqrt{n_x^2 + n_y^2 + n_z^2}$, so that $\vec{n}$ is an unit vector, i.e. length $1$, $\left\lVert\vec{n}\right\rVert = 1$, and the signed distance from origin $d$ is the Euclidean distance, as the value of $d$ is actually the signed distance from origin expressed in units of the normal vector length; positive if the plane is in the direction of the normal vector from origin, negative if in the opposite direction; and $d = 0$ if and only if the plane passes through origin $(0, 0, 0)$.)

If we use $$\vec{p} = \left [ \begin{matrix} x \\ y \\ z \end{matrix} \right ], \quad \vec{n} = \left [ \begin{matrix} n_x \\ n_y \\ n_z \end{matrix} \right ]$$ then we can write $\eqref{AC1}$ as $$x n_x + y n_y + z n_z = d \tag{2}\label{AC2}$$

If we have a vector $\vec{b}$ that has the desired direction when projected to the plane (i.e., if we look along the plane normal, we see the part of $\vec{b}$ we are interested in), we can use one step of the Gram-Schmidt process to calculate $\vec{q}$, corresponding to the part of $\vec{b}$ that is perpendicular to $\vec{n}$.

(Because $\vec{n}$ is perpendicular to the plane, and we are working in three-dimensional Euclidean space, if $\vec{q}$ is perpendicular to the normal $\vec{n}$, then it is parallel to the plane. This is what each step in the Gram-Schmidt process does. You can do more than one step of it to make a vector perpendicular to a whole set of given vectors, as long as those given vectors are perpendicular to each other.)

Fortunately, this is simple: $$\vec{q} = \vec{b} - \vec{n}\frac{\vec{b}\cdot\vec{n}}{\vec{n}\cdot\vec{n}} \tag{3}\label{AC3}$$ Or, in Cartesian coordinate form: $$\begin{aligned} c &= \frac{\vec{b} \cdot \vec{n}}{\vec{n} \cdot \vec{n}} = \frac{ b_x n_x + b_y n_y + b_z n_z}{ n_x^2 + n_y^2 + n_z^2 } \\ q_x &= b_x - c n_x \\ q_y &= b_y - c n_y \\ q_z &= b_z - c n_z \\ \end{aligned}$$ Note that if the normal vector is a zero vector, $\vec{n} = \vec{0}$, the divisor is zero, and the value of $c$ is infinite. If this does occur, then there is no plane, because the zero vector $\vec{0}$ has no direction.

If $\vec{p}$ is on the plane defined by $\vec{n}$ and $d$, and $\lambda \in \mathbb{R}$ (i.e., $\lambda$ is any real number), then $\vec{p} + \lambda \vec{q}$ is also on the plane.

If $\vec{b} = \vec{0}$, or $\vec{b}$ is perpendicular to the plane, then the above just yields $\vec{q} = \vec{0}$. This just means that the vector $\vec{d}$ did not specify any direction on the plane.


What if you don't know the exact normal for the plane?

If you know three points (say, $\vec{p}_1$, $\vec{p}_2$, and $\vec{p}_3$) on the plane that are not collinear (along the same line), then you can easily calculate the normal: $$\begin{aligned} \vec{n} &= (\vec{p}_2 - \vec{p}_1)\times(\vec{p}_3 - \vec{p}_1) \\ d &= \vec{n} \cdot \vec{p}_1 \\ \end{aligned} \tag{4}\label{AC4}$$ Using Cartesian coordinates, $\eqref{AC4}$ is $$\begin{aligned} n_x &= ( y_2 - y_1 ) ( z_3 - z_1 ) - ( z_2 - z_1 ) ( y_3 - y_1 ) \\ n_y &= ( z_2 - z_1 ) ( x_3 - x_1 ) - ( x_2 - x_1 ) ( z_3 - z_1 ) \\ n_z &= ( x_2 - x_1 ) ( y_3 - y_1 ) - ( y_2 - y_1 ) ( x_3 - x_1 ) \\ d &= n_x x_1 + n_y y_1 + n_z z_1 \\ \end{aligned}$$

0
On

Basically, you just need to find where a vertical line intersects a plane $P'$ through the origin that’s parallel to yours. Let’s call your normal $\mathbf n=(n_x,n_y,n_z)$. The equation of $P'$ can be expressed by the dot product $\mathbf n\cdot\mathbf x=0$. If the horizontal direction of movement is given by the vector $(x,y,0)$, then you just need to solve $\mathbf n\cdot(x,y,z)=0$ for $z$: $$z=-{n_xx+n_yy\over n_z}.$$ You can then scale the entire vector as needed. You could instead compute the orthogonal projection of $(x,y,0)$ onto $P'$, for which you can easily find formulas on this site and elsewhere on the Web, but the above calculation is even simpler.

Note that this is undefined when $n_z=0$. That makes sense: in that case, $P$ and $P'$ are vertical (i.e., parallel to the $z$-axis), so our line is either parallel to $P'$ or is completely contained withing the plane.