21
$\begingroup$

If I have a triangle with $3$ points $P_1, P_2,$ and $P_3$, each with $x, y,$ and $z$ coordinates, how do I find the surface normal $N$ in $x, y,$ and $z$ such that

$$(N_x)^2+(N_y)^2+(N_z)^2 = 1$$

I'm looking for a simple formula that uses values like $x_1$, $x_2$, or $y_3$, and doesn't involve complicated equations or cross products.

$\endgroup$
  • 1
    $\begingroup$ What are Nx,Ny,Nz? $\endgroup$ – Salech Alhasov Feb 16 '13 at 17:42
  • 2
    $\begingroup$ @SalechAlhasov x, y, and z coordinates of the surface normal vector. $\endgroup$ – acer Feb 16 '13 at 17:45
  • 1
    $\begingroup$ In general the $N$ for each of $x, y$ and $z$ will be different. One thing you could do is write $v = P_1 - P_2$ and $w = P_2 - P_3$ to get two vectors ,then take the cross product $u = v \times w$; then $u\cdot (x, y, z) = d$, where $d = u\cdot P_1 = u\cdot P_2 = u\cdot P_3$ ($P_1, P_2, P_3$ are on the plane.) $\endgroup$ – snar Feb 16 '13 at 17:46
  • $\begingroup$ @snarski Could you simplify that? $\endgroup$ – acer Feb 16 '13 at 17:48
  • 6
    $\begingroup$ Cross products aren't that complicated... $\endgroup$ – Rahul Feb 16 '13 at 18:27
17
$\begingroup$

The cross product of two sides of the triangle equals the surface normal. So, if $V$ = $P_2$ - $P_1$ and $W$ = $P_3$ - $P_1$, and $N$ is the surface normal, then:

$N_x = (V_y * W_z) - (V_z * W_y)$

$N_y = (V_z * W_x) - (V_x * W_z)$

$N_z = (V_x * W_y) - (V_y * W_x)$

If $A$ is the new vector whose components add up to 1, then:

$A_x = \frac {N_x}{(N_x)^2 + (N_y)^2 + (N_z)^2}$

$A_y = \frac {N_y}{((N_x)^2 + (N_y)^2 + (N_z)^2}$

$A_z = \frac {N_z}{(N_x)^2 + (N_y)^2 + (N_z)^2}$

My sources: http://en.wikipedia.org/wiki/Normal_(geometry)

$\endgroup$
  • 1
    $\begingroup$ If $N_x+N_y+N_z=0$ then the condition that their sum equal 1, as the OP asked for, can't be met anyway. $\endgroup$ – Dan Rust Feb 18 '13 at 15:11
  • 1
    $\begingroup$ $N_x + N_y + N_z$ can't equal $0$ unless the triangle's points are all the same. $\endgroup$ – acer Feb 18 '13 at 17:08
  • 7
    $\begingroup$ Oh really? What about the triangle whose vertices are $(0,0,0)$, $(1,1,0)$, and $(0,0,1)$? $\endgroup$ – Rahul Feb 19 '13 at 5:35
  • 1
    $\begingroup$ Normalization of a vector is done by dividing by the sum of the square of the components. This answer is flat out wrong. $\endgroup$ – user64742 Dec 7 '19 at 18:09
  • 1
    $\begingroup$ @acer I'm more annoyed by the 78k people who viewed this and not one of them made a single attempt to edit or correct this. Even worse that nobody on this comment thread was able to state the actual flaw instead of randomly shooting out counter examples. $\endgroup$ – user64742 Dec 9 '19 at 0:14
6
$\begingroup$

Let $P_1=(x_1,y_1,z_1)$, $P_2=(x_2,y_2,z_2)$ and $P_3=(x_3,y_3,z_3)$. The normal vector to the triangle with these three points as its vertices is then given by the cross product $n=(P_2-P_1)\times (P_3-P_1)$. In matrix form, we then see that $$n=\det\left(\left[\begin{matrix}i&j&k\\ x_2-x_1&y_2-y_1&z_2-z_1\\ x_3-x_1&y_3-y_1&z_3-z_1 \end{matrix}\right]\right)$$

$$=\left(\begin{matrix}(y_2-y_1)(z_3-z_1)-(y_3-y_1)(z_2-z_1)\\ (z_2-z_1)(x_3-x_1)-(x_2-x_1)(z_3-z_1)\\ (x_2-x_1)(y_3-y_1)-(x_3-x_1)(y_2-y_1) \end{matrix}\right)$$

If you need that the sum of the coefficients of $\hat{n}$ equals 1, then set $\alpha$ equal to the sum of the coefficients of $n$ and then let $\hat{n}=\frac{1}{\alpha}n$. Obviously, if $\alpha=0$ then you will never be able to satisfy your condition as any scalar multiple of $n$ will have the same zero-sum of coefficients.

$\endgroup$
2
$\begingroup$

The general question can be written in python like this:

import numpy as np
p1 = np.array([0,0,5])
p2 = np.array([1,0,5])
p3 = np.array([0,1,5])

N = np.cross(p2-p1, p3-p1)

The 'normalized' sum of 1 can be attempted like this:

N = N / n.sum()

For the (0,0,0), (1,1,0), (0,0,1) example mentioned above, where the components add up to 0, the result silently degrades to array([ inf, -inf, nan]).

$\endgroup$
  • $\begingroup$ Please, this is Math SE, not Stack Overflow. $\endgroup$ – scaaahu Jan 20 '19 at 12:50
  • 1
    $\begingroup$ This is really cool, numpy is useful for more than I thought. Plus when I first asked this question it was exactly for this purpose—to be able to calculate the surface normal in a programming environment. $\endgroup$ – acer Jan 21 '19 at 17:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.