How to determine if a point is above or below a plane defined by a triangle











up vote
1
down vote

favorite
1












I'm doing some 3D graphics stuff and in order to add some simple lighting, the program needs to determine whether or not a point is below a triangle. (For now just the plane defined by the triangle. I'll tackle the point-in-triangle problem later.) Y is up. Thanks!










share|cite|improve this question






















  • How do you define “up” relative to the triangle? What do you have to work with (just the vertices or do you have a precomputed normal)?
    – amd
    Nov 14 at 23:03

















up vote
1
down vote

favorite
1












I'm doing some 3D graphics stuff and in order to add some simple lighting, the program needs to determine whether or not a point is below a triangle. (For now just the plane defined by the triangle. I'll tackle the point-in-triangle problem later.) Y is up. Thanks!










share|cite|improve this question






















  • How do you define “up” relative to the triangle? What do you have to work with (just the vertices or do you have a precomputed normal)?
    – amd
    Nov 14 at 23:03















up vote
1
down vote

favorite
1









up vote
1
down vote

favorite
1






1





I'm doing some 3D graphics stuff and in order to add some simple lighting, the program needs to determine whether or not a point is below a triangle. (For now just the plane defined by the triangle. I'll tackle the point-in-triangle problem later.) Y is up. Thanks!










share|cite|improve this question













I'm doing some 3D graphics stuff and in order to add some simple lighting, the program needs to determine whether or not a point is below a triangle. (For now just the plane defined by the triangle. I'll tackle the point-in-triangle problem later.) Y is up. Thanks!







triangle 3d






share|cite|improve this question













share|cite|improve this question











share|cite|improve this question




share|cite|improve this question










asked Nov 14 at 21:55









joek204

133




133












  • How do you define “up” relative to the triangle? What do you have to work with (just the vertices or do you have a precomputed normal)?
    – amd
    Nov 14 at 23:03




















  • How do you define “up” relative to the triangle? What do you have to work with (just the vertices or do you have a precomputed normal)?
    – amd
    Nov 14 at 23:03


















How do you define “up” relative to the triangle? What do you have to work with (just the vertices or do you have a precomputed normal)?
– amd
Nov 14 at 23:03






How do you define “up” relative to the triangle? What do you have to work with (just the vertices or do you have a precomputed normal)?
– amd
Nov 14 at 23:03












4 Answers
4






active

oldest

votes

















up vote
0
down vote













HINT



We can proceed as follow




  • find the plane containing the triangle

  • find the intersection point $Q$ between the plane and the vertical line through the point $P$

  • calculate $z_P-z_Q$






share|cite|improve this answer




























    up vote
    0
    down vote













    Suppose the triangle is $ABC$ and the point is $P$.



    Calculate the vectors $B-A$, $C-A$ and $P-A$. Then the sign of the vector triple product
    $$
    (P-A) cdot ((B-A) times (C-A))
    $$

    determines which side of the plane of the triangle contains $P$.



    That triple product is just a determinant, which should make the coding easy.






    share|cite|improve this answer




























      up vote
      0
      down vote













      Write the equation of the plane of the triangle as $$z=ax+by+d$$



      If your point is $p= (x_0, y_0,z_0)$ compare the $z=ax_0+by_0+d$ with $z_0$.



      If $z_0 > ax_0+by_0+d$ then $p$ is above otherwise it is either below or on the plane ( in case of equality).






      share|cite|improve this answer




























        up vote
        0
        down vote













        Although others have already answered the stated question, I'd like to give some advice to those doing similar to what OP is doing.





        1. Precalculate the unit normal vector to the triangle, and store it.



          If the triangle vertices are $vec{v}_0$, $vec{v}_1$, and $vec{v}_2$, then the triangle normal is usually defined as
          $$vec{n} = bigl(vec{v}_1 - vec{v}_0bigr)timesbigl(vec{v}_2 - vec{v}_0bigr)$$
          where $times$ denotes vector cross product. This is scaled to unit length,
          $$hat{n} = frac{vec{n}}{leftlVertvec{n}rightrVert} = frac{vec{n}}{sqrt{vec{n} cdot vec{n}}}$$



          This is best precalculated and stored, because the square root operation tends to be slow, and it is just one vector per triangle.
           




        2. A point is "above" the triangle if it is in the same halfspace as the triange normal vector, with respect to the plane formed by the triangle.



          (If you extend the triangle plane to infinity, it splits space into two halves. If you look at the triangle sideways, the point is "above" the triangle if it is in the same side as the normal is; and "below" if it is on the other side. If the point is on the triangle plane exactly, I recommend you use a clear and unambigous term for it; I use "exactly on the triangle" myself. I'm sure mathematicians have more precise terms, but for those of us who only use math as a tool for solving problems, making sure the terms are unambiguous suffices.)



          This means that point $vec{p}$ has signed distance
          $$d = bigl(vec{p} - vec{v}_0bigr) cdot hat{n}$$
          from the plane of the triangle. (Because all three triangle vertices are on the plane, you can use $vec{v}_1$ or $vec{v}_2$ in above; you'll still get the exact same result, within rounding error.)



          If $hat{n}$ is not an unit vector, i.e. $leftlVerthat{n}rightrVertne 1$, the distance is in units of the normal vector length.
           



        3. When you know the signed distance $d$ of the point $vec{p}$ from the plane, you can trivially project the point to the plane:
          $$vec{p}_text{plane} = vec{p} - d hat{n}$$
          If $hat{n}$ is not an unit vector, i.e. $leftlVerthat{n}rightrVertne1$, the right side is actually $vec{p} - hat{n}(d / lVerthat{n}rVert)$, and you need a "slow" square root operation here. Because you probably test many points per each triangle, it is well worth precalculating and storing the $hat{n}$ beforehand.
           



        4. To determine if $vec{p}_text{plane}$ is within the triangle, find out the barycentric coordinates $(u, v)$ corresponding to $vec{p}_text{plane}$ with respect to that triangle.



          To do this, check which axes have the smallest values in magnitude in $hat{n}$. Their order does not matter. (This essentially picks the axis along which to look at the triangle, with the triangle being as large as possible. We do this to minimize numerical errors.) There are three possibilities: $x$ and $y$; $x$ and $z$; and $y$ and $z$. The solution is obtained using the coordinates on those two axes.



          The solution for $vec{p}_text{plane} = (x, y, z)$ with $hat{n}$ having $x$ and $y$ components closest to zero, is
          $$begin{cases}
          displaystyle u = frac{ (x - x_0)(y_2 - y_0) - (y - y_0)(x_2 - x_0)}{ (x - x_2)(y_1 - y_0) - (y - y_2)(x_1 - x_0) } \
          displaystyle v = frac{ (y - y_0)(x_1 - x_0) - (x - x_0)(y_1 - y_0)}{ x_0 (y_1 - y_2) + x_1 (y_2 - y_0) + x_2 (y_0 - y_1) } \
          end{cases}$$

          The solution for the other axis pairs you'll find just by permuting the coordinates ($y$, $y_0$, $y_1$, $y_2$ to $z$, $z_0$, $z_1$, $z_2$ for $x$ and $z$ axes; and also $x$, $x_0$, $x_1$, $x_2$ to $y$, $y_0$, $y_1$, $y_2$ for $y$ and $z$).



          Also note that you'll want to calculate the divisor for $u$ first. It will be zero at $vec{v}_2$, where $u = 0$, so when the divisor is very close to zero, just use $u = 0$.



          In barycentric coordinates, $vec{v}_0$ is at $(0, 0)$; $vec{v}_1$ is at $(1,0)$, and $vec{v}_2$ is at $(0,1)$. The entire triangle is $0 le u, v, u + v le 1$. The edges are at $u = 0$, $v = 0$, and $u + v = 1$.



          In practice, you define the triangle inclusion test as
          $$Bigl(u ge -epsilonBigr) text{ and }
          Bigl(v ge -epsilonBigr) text{ and }
          Bigl(u le 1+epsilonBigr) text{ and }
          Bigl(v le 1+epsilonBigr) text{ and }
          Bigl(u + v le 1+epsilonBigr)$$

          where $epsilon$ represents the precision of your numerical coordinates. It is the largest positive number you consider equal to zero. (Similarly, if $D$ is the divisor for $u$ earlier, if $-epsilon le D le +epsilon$, use $u = 0$.)



          To linearly interpolate any value $c$ within the triangle, with $c = c_0$ at $vec{v}_0$, $c_1$ at $vec{v}_1$, and $c_2$ at $vec{v}_2$, you can use
          $$c(u,v) = (1 - v)bigl((1-u) c_0 + u c_1bigr) + v c_2$$




        All together, this means that you need only 15 (scalar) multiplications and less than thirty additions or subtractions, to find out if a point is within the triangle, or within a triangular prism extending from the triangle along its normal, including the barycentric coordinates needed for texture or color interpolation. (Color interpolation itself is just four multiplications per component, so typically 12 additional multiplications.) Nifty, eh?






        share|cite|improve this answer





















          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["$", "$"], ["\\(","\\)"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "69"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          noCode: true, onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














           

          draft saved


          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmath.stackexchange.com%2fquestions%2f2998875%2fhow-to-determine-if-a-point-is-above-or-below-a-plane-defined-by-a-triangle%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          4 Answers
          4






          active

          oldest

          votes








          4 Answers
          4






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          0
          down vote













          HINT



          We can proceed as follow




          • find the plane containing the triangle

          • find the intersection point $Q$ between the plane and the vertical line through the point $P$

          • calculate $z_P-z_Q$






          share|cite|improve this answer

























            up vote
            0
            down vote













            HINT



            We can proceed as follow




            • find the plane containing the triangle

            • find the intersection point $Q$ between the plane and the vertical line through the point $P$

            • calculate $z_P-z_Q$






            share|cite|improve this answer























              up vote
              0
              down vote










              up vote
              0
              down vote









              HINT



              We can proceed as follow




              • find the plane containing the triangle

              • find the intersection point $Q$ between the plane and the vertical line through the point $P$

              • calculate $z_P-z_Q$






              share|cite|improve this answer












              HINT



              We can proceed as follow




              • find the plane containing the triangle

              • find the intersection point $Q$ between the plane and the vertical line through the point $P$

              • calculate $z_P-z_Q$







              share|cite|improve this answer












              share|cite|improve this answer



              share|cite|improve this answer










              answered Nov 14 at 22:01









              gimusi

              86.6k74392




              86.6k74392






















                  up vote
                  0
                  down vote













                  Suppose the triangle is $ABC$ and the point is $P$.



                  Calculate the vectors $B-A$, $C-A$ and $P-A$. Then the sign of the vector triple product
                  $$
                  (P-A) cdot ((B-A) times (C-A))
                  $$

                  determines which side of the plane of the triangle contains $P$.



                  That triple product is just a determinant, which should make the coding easy.






                  share|cite|improve this answer

























                    up vote
                    0
                    down vote













                    Suppose the triangle is $ABC$ and the point is $P$.



                    Calculate the vectors $B-A$, $C-A$ and $P-A$. Then the sign of the vector triple product
                    $$
                    (P-A) cdot ((B-A) times (C-A))
                    $$

                    determines which side of the plane of the triangle contains $P$.



                    That triple product is just a determinant, which should make the coding easy.






                    share|cite|improve this answer























                      up vote
                      0
                      down vote










                      up vote
                      0
                      down vote









                      Suppose the triangle is $ABC$ and the point is $P$.



                      Calculate the vectors $B-A$, $C-A$ and $P-A$. Then the sign of the vector triple product
                      $$
                      (P-A) cdot ((B-A) times (C-A))
                      $$

                      determines which side of the plane of the triangle contains $P$.



                      That triple product is just a determinant, which should make the coding easy.






                      share|cite|improve this answer












                      Suppose the triangle is $ABC$ and the point is $P$.



                      Calculate the vectors $B-A$, $C-A$ and $P-A$. Then the sign of the vector triple product
                      $$
                      (P-A) cdot ((B-A) times (C-A))
                      $$

                      determines which side of the plane of the triangle contains $P$.



                      That triple product is just a determinant, which should make the coding easy.







                      share|cite|improve this answer












                      share|cite|improve this answer



                      share|cite|improve this answer










                      answered Nov 14 at 22:02









                      Ethan Bolker

                      39.1k543102




                      39.1k543102






















                          up vote
                          0
                          down vote













                          Write the equation of the plane of the triangle as $$z=ax+by+d$$



                          If your point is $p= (x_0, y_0,z_0)$ compare the $z=ax_0+by_0+d$ with $z_0$.



                          If $z_0 > ax_0+by_0+d$ then $p$ is above otherwise it is either below or on the plane ( in case of equality).






                          share|cite|improve this answer

























                            up vote
                            0
                            down vote













                            Write the equation of the plane of the triangle as $$z=ax+by+d$$



                            If your point is $p= (x_0, y_0,z_0)$ compare the $z=ax_0+by_0+d$ with $z_0$.



                            If $z_0 > ax_0+by_0+d$ then $p$ is above otherwise it is either below or on the plane ( in case of equality).






                            share|cite|improve this answer























                              up vote
                              0
                              down vote










                              up vote
                              0
                              down vote









                              Write the equation of the plane of the triangle as $$z=ax+by+d$$



                              If your point is $p= (x_0, y_0,z_0)$ compare the $z=ax_0+by_0+d$ with $z_0$.



                              If $z_0 > ax_0+by_0+d$ then $p$ is above otherwise it is either below or on the plane ( in case of equality).






                              share|cite|improve this answer












                              Write the equation of the plane of the triangle as $$z=ax+by+d$$



                              If your point is $p= (x_0, y_0,z_0)$ compare the $z=ax_0+by_0+d$ with $z_0$.



                              If $z_0 > ax_0+by_0+d$ then $p$ is above otherwise it is either below or on the plane ( in case of equality).







                              share|cite|improve this answer












                              share|cite|improve this answer



                              share|cite|improve this answer










                              answered Nov 14 at 22:23









                              Mohammad Riazi-Kermani

                              40.2k41958




                              40.2k41958






















                                  up vote
                                  0
                                  down vote













                                  Although others have already answered the stated question, I'd like to give some advice to those doing similar to what OP is doing.





                                  1. Precalculate the unit normal vector to the triangle, and store it.



                                    If the triangle vertices are $vec{v}_0$, $vec{v}_1$, and $vec{v}_2$, then the triangle normal is usually defined as
                                    $$vec{n} = bigl(vec{v}_1 - vec{v}_0bigr)timesbigl(vec{v}_2 - vec{v}_0bigr)$$
                                    where $times$ denotes vector cross product. This is scaled to unit length,
                                    $$hat{n} = frac{vec{n}}{leftlVertvec{n}rightrVert} = frac{vec{n}}{sqrt{vec{n} cdot vec{n}}}$$



                                    This is best precalculated and stored, because the square root operation tends to be slow, and it is just one vector per triangle.
                                     




                                  2. A point is "above" the triangle if it is in the same halfspace as the triange normal vector, with respect to the plane formed by the triangle.



                                    (If you extend the triangle plane to infinity, it splits space into two halves. If you look at the triangle sideways, the point is "above" the triangle if it is in the same side as the normal is; and "below" if it is on the other side. If the point is on the triangle plane exactly, I recommend you use a clear and unambigous term for it; I use "exactly on the triangle" myself. I'm sure mathematicians have more precise terms, but for those of us who only use math as a tool for solving problems, making sure the terms are unambiguous suffices.)



                                    This means that point $vec{p}$ has signed distance
                                    $$d = bigl(vec{p} - vec{v}_0bigr) cdot hat{n}$$
                                    from the plane of the triangle. (Because all three triangle vertices are on the plane, you can use $vec{v}_1$ or $vec{v}_2$ in above; you'll still get the exact same result, within rounding error.)



                                    If $hat{n}$ is not an unit vector, i.e. $leftlVerthat{n}rightrVertne 1$, the distance is in units of the normal vector length.
                                     



                                  3. When you know the signed distance $d$ of the point $vec{p}$ from the plane, you can trivially project the point to the plane:
                                    $$vec{p}_text{plane} = vec{p} - d hat{n}$$
                                    If $hat{n}$ is not an unit vector, i.e. $leftlVerthat{n}rightrVertne1$, the right side is actually $vec{p} - hat{n}(d / lVerthat{n}rVert)$, and you need a "slow" square root operation here. Because you probably test many points per each triangle, it is well worth precalculating and storing the $hat{n}$ beforehand.
                                     



                                  4. To determine if $vec{p}_text{plane}$ is within the triangle, find out the barycentric coordinates $(u, v)$ corresponding to $vec{p}_text{plane}$ with respect to that triangle.



                                    To do this, check which axes have the smallest values in magnitude in $hat{n}$. Their order does not matter. (This essentially picks the axis along which to look at the triangle, with the triangle being as large as possible. We do this to minimize numerical errors.) There are three possibilities: $x$ and $y$; $x$ and $z$; and $y$ and $z$. The solution is obtained using the coordinates on those two axes.



                                    The solution for $vec{p}_text{plane} = (x, y, z)$ with $hat{n}$ having $x$ and $y$ components closest to zero, is
                                    $$begin{cases}
                                    displaystyle u = frac{ (x - x_0)(y_2 - y_0) - (y - y_0)(x_2 - x_0)}{ (x - x_2)(y_1 - y_0) - (y - y_2)(x_1 - x_0) } \
                                    displaystyle v = frac{ (y - y_0)(x_1 - x_0) - (x - x_0)(y_1 - y_0)}{ x_0 (y_1 - y_2) + x_1 (y_2 - y_0) + x_2 (y_0 - y_1) } \
                                    end{cases}$$

                                    The solution for the other axis pairs you'll find just by permuting the coordinates ($y$, $y_0$, $y_1$, $y_2$ to $z$, $z_0$, $z_1$, $z_2$ for $x$ and $z$ axes; and also $x$, $x_0$, $x_1$, $x_2$ to $y$, $y_0$, $y_1$, $y_2$ for $y$ and $z$).



                                    Also note that you'll want to calculate the divisor for $u$ first. It will be zero at $vec{v}_2$, where $u = 0$, so when the divisor is very close to zero, just use $u = 0$.



                                    In barycentric coordinates, $vec{v}_0$ is at $(0, 0)$; $vec{v}_1$ is at $(1,0)$, and $vec{v}_2$ is at $(0,1)$. The entire triangle is $0 le u, v, u + v le 1$. The edges are at $u = 0$, $v = 0$, and $u + v = 1$.



                                    In practice, you define the triangle inclusion test as
                                    $$Bigl(u ge -epsilonBigr) text{ and }
                                    Bigl(v ge -epsilonBigr) text{ and }
                                    Bigl(u le 1+epsilonBigr) text{ and }
                                    Bigl(v le 1+epsilonBigr) text{ and }
                                    Bigl(u + v le 1+epsilonBigr)$$

                                    where $epsilon$ represents the precision of your numerical coordinates. It is the largest positive number you consider equal to zero. (Similarly, if $D$ is the divisor for $u$ earlier, if $-epsilon le D le +epsilon$, use $u = 0$.)



                                    To linearly interpolate any value $c$ within the triangle, with $c = c_0$ at $vec{v}_0$, $c_1$ at $vec{v}_1$, and $c_2$ at $vec{v}_2$, you can use
                                    $$c(u,v) = (1 - v)bigl((1-u) c_0 + u c_1bigr) + v c_2$$




                                  All together, this means that you need only 15 (scalar) multiplications and less than thirty additions or subtractions, to find out if a point is within the triangle, or within a triangular prism extending from the triangle along its normal, including the barycentric coordinates needed for texture or color interpolation. (Color interpolation itself is just four multiplications per component, so typically 12 additional multiplications.) Nifty, eh?






                                  share|cite|improve this answer

























                                    up vote
                                    0
                                    down vote













                                    Although others have already answered the stated question, I'd like to give some advice to those doing similar to what OP is doing.





                                    1. Precalculate the unit normal vector to the triangle, and store it.



                                      If the triangle vertices are $vec{v}_0$, $vec{v}_1$, and $vec{v}_2$, then the triangle normal is usually defined as
                                      $$vec{n} = bigl(vec{v}_1 - vec{v}_0bigr)timesbigl(vec{v}_2 - vec{v}_0bigr)$$
                                      where $times$ denotes vector cross product. This is scaled to unit length,
                                      $$hat{n} = frac{vec{n}}{leftlVertvec{n}rightrVert} = frac{vec{n}}{sqrt{vec{n} cdot vec{n}}}$$



                                      This is best precalculated and stored, because the square root operation tends to be slow, and it is just one vector per triangle.
                                       




                                    2. A point is "above" the triangle if it is in the same halfspace as the triange normal vector, with respect to the plane formed by the triangle.



                                      (If you extend the triangle plane to infinity, it splits space into two halves. If you look at the triangle sideways, the point is "above" the triangle if it is in the same side as the normal is; and "below" if it is on the other side. If the point is on the triangle plane exactly, I recommend you use a clear and unambigous term for it; I use "exactly on the triangle" myself. I'm sure mathematicians have more precise terms, but for those of us who only use math as a tool for solving problems, making sure the terms are unambiguous suffices.)



                                      This means that point $vec{p}$ has signed distance
                                      $$d = bigl(vec{p} - vec{v}_0bigr) cdot hat{n}$$
                                      from the plane of the triangle. (Because all three triangle vertices are on the plane, you can use $vec{v}_1$ or $vec{v}_2$ in above; you'll still get the exact same result, within rounding error.)



                                      If $hat{n}$ is not an unit vector, i.e. $leftlVerthat{n}rightrVertne 1$, the distance is in units of the normal vector length.
                                       



                                    3. When you know the signed distance $d$ of the point $vec{p}$ from the plane, you can trivially project the point to the plane:
                                      $$vec{p}_text{plane} = vec{p} - d hat{n}$$
                                      If $hat{n}$ is not an unit vector, i.e. $leftlVerthat{n}rightrVertne1$, the right side is actually $vec{p} - hat{n}(d / lVerthat{n}rVert)$, and you need a "slow" square root operation here. Because you probably test many points per each triangle, it is well worth precalculating and storing the $hat{n}$ beforehand.
                                       



                                    4. To determine if $vec{p}_text{plane}$ is within the triangle, find out the barycentric coordinates $(u, v)$ corresponding to $vec{p}_text{plane}$ with respect to that triangle.



                                      To do this, check which axes have the smallest values in magnitude in $hat{n}$. Their order does not matter. (This essentially picks the axis along which to look at the triangle, with the triangle being as large as possible. We do this to minimize numerical errors.) There are three possibilities: $x$ and $y$; $x$ and $z$; and $y$ and $z$. The solution is obtained using the coordinates on those two axes.



                                      The solution for $vec{p}_text{plane} = (x, y, z)$ with $hat{n}$ having $x$ and $y$ components closest to zero, is
                                      $$begin{cases}
                                      displaystyle u = frac{ (x - x_0)(y_2 - y_0) - (y - y_0)(x_2 - x_0)}{ (x - x_2)(y_1 - y_0) - (y - y_2)(x_1 - x_0) } \
                                      displaystyle v = frac{ (y - y_0)(x_1 - x_0) - (x - x_0)(y_1 - y_0)}{ x_0 (y_1 - y_2) + x_1 (y_2 - y_0) + x_2 (y_0 - y_1) } \
                                      end{cases}$$

                                      The solution for the other axis pairs you'll find just by permuting the coordinates ($y$, $y_0$, $y_1$, $y_2$ to $z$, $z_0$, $z_1$, $z_2$ for $x$ and $z$ axes; and also $x$, $x_0$, $x_1$, $x_2$ to $y$, $y_0$, $y_1$, $y_2$ for $y$ and $z$).



                                      Also note that you'll want to calculate the divisor for $u$ first. It will be zero at $vec{v}_2$, where $u = 0$, so when the divisor is very close to zero, just use $u = 0$.



                                      In barycentric coordinates, $vec{v}_0$ is at $(0, 0)$; $vec{v}_1$ is at $(1,0)$, and $vec{v}_2$ is at $(0,1)$. The entire triangle is $0 le u, v, u + v le 1$. The edges are at $u = 0$, $v = 0$, and $u + v = 1$.



                                      In practice, you define the triangle inclusion test as
                                      $$Bigl(u ge -epsilonBigr) text{ and }
                                      Bigl(v ge -epsilonBigr) text{ and }
                                      Bigl(u le 1+epsilonBigr) text{ and }
                                      Bigl(v le 1+epsilonBigr) text{ and }
                                      Bigl(u + v le 1+epsilonBigr)$$

                                      where $epsilon$ represents the precision of your numerical coordinates. It is the largest positive number you consider equal to zero. (Similarly, if $D$ is the divisor for $u$ earlier, if $-epsilon le D le +epsilon$, use $u = 0$.)



                                      To linearly interpolate any value $c$ within the triangle, with $c = c_0$ at $vec{v}_0$, $c_1$ at $vec{v}_1$, and $c_2$ at $vec{v}_2$, you can use
                                      $$c(u,v) = (1 - v)bigl((1-u) c_0 + u c_1bigr) + v c_2$$




                                    All together, this means that you need only 15 (scalar) multiplications and less than thirty additions or subtractions, to find out if a point is within the triangle, or within a triangular prism extending from the triangle along its normal, including the barycentric coordinates needed for texture or color interpolation. (Color interpolation itself is just four multiplications per component, so typically 12 additional multiplications.) Nifty, eh?






                                    share|cite|improve this answer























                                      up vote
                                      0
                                      down vote










                                      up vote
                                      0
                                      down vote









                                      Although others have already answered the stated question, I'd like to give some advice to those doing similar to what OP is doing.





                                      1. Precalculate the unit normal vector to the triangle, and store it.



                                        If the triangle vertices are $vec{v}_0$, $vec{v}_1$, and $vec{v}_2$, then the triangle normal is usually defined as
                                        $$vec{n} = bigl(vec{v}_1 - vec{v}_0bigr)timesbigl(vec{v}_2 - vec{v}_0bigr)$$
                                        where $times$ denotes vector cross product. This is scaled to unit length,
                                        $$hat{n} = frac{vec{n}}{leftlVertvec{n}rightrVert} = frac{vec{n}}{sqrt{vec{n} cdot vec{n}}}$$



                                        This is best precalculated and stored, because the square root operation tends to be slow, and it is just one vector per triangle.
                                         




                                      2. A point is "above" the triangle if it is in the same halfspace as the triange normal vector, with respect to the plane formed by the triangle.



                                        (If you extend the triangle plane to infinity, it splits space into two halves. If you look at the triangle sideways, the point is "above" the triangle if it is in the same side as the normal is; and "below" if it is on the other side. If the point is on the triangle plane exactly, I recommend you use a clear and unambigous term for it; I use "exactly on the triangle" myself. I'm sure mathematicians have more precise terms, but for those of us who only use math as a tool for solving problems, making sure the terms are unambiguous suffices.)



                                        This means that point $vec{p}$ has signed distance
                                        $$d = bigl(vec{p} - vec{v}_0bigr) cdot hat{n}$$
                                        from the plane of the triangle. (Because all three triangle vertices are on the plane, you can use $vec{v}_1$ or $vec{v}_2$ in above; you'll still get the exact same result, within rounding error.)



                                        If $hat{n}$ is not an unit vector, i.e. $leftlVerthat{n}rightrVertne 1$, the distance is in units of the normal vector length.
                                         



                                      3. When you know the signed distance $d$ of the point $vec{p}$ from the plane, you can trivially project the point to the plane:
                                        $$vec{p}_text{plane} = vec{p} - d hat{n}$$
                                        If $hat{n}$ is not an unit vector, i.e. $leftlVerthat{n}rightrVertne1$, the right side is actually $vec{p} - hat{n}(d / lVerthat{n}rVert)$, and you need a "slow" square root operation here. Because you probably test many points per each triangle, it is well worth precalculating and storing the $hat{n}$ beforehand.
                                         



                                      4. To determine if $vec{p}_text{plane}$ is within the triangle, find out the barycentric coordinates $(u, v)$ corresponding to $vec{p}_text{plane}$ with respect to that triangle.



                                        To do this, check which axes have the smallest values in magnitude in $hat{n}$. Their order does not matter. (This essentially picks the axis along which to look at the triangle, with the triangle being as large as possible. We do this to minimize numerical errors.) There are three possibilities: $x$ and $y$; $x$ and $z$; and $y$ and $z$. The solution is obtained using the coordinates on those two axes.



                                        The solution for $vec{p}_text{plane} = (x, y, z)$ with $hat{n}$ having $x$ and $y$ components closest to zero, is
                                        $$begin{cases}
                                        displaystyle u = frac{ (x - x_0)(y_2 - y_0) - (y - y_0)(x_2 - x_0)}{ (x - x_2)(y_1 - y_0) - (y - y_2)(x_1 - x_0) } \
                                        displaystyle v = frac{ (y - y_0)(x_1 - x_0) - (x - x_0)(y_1 - y_0)}{ x_0 (y_1 - y_2) + x_1 (y_2 - y_0) + x_2 (y_0 - y_1) } \
                                        end{cases}$$

                                        The solution for the other axis pairs you'll find just by permuting the coordinates ($y$, $y_0$, $y_1$, $y_2$ to $z$, $z_0$, $z_1$, $z_2$ for $x$ and $z$ axes; and also $x$, $x_0$, $x_1$, $x_2$ to $y$, $y_0$, $y_1$, $y_2$ for $y$ and $z$).



                                        Also note that you'll want to calculate the divisor for $u$ first. It will be zero at $vec{v}_2$, where $u = 0$, so when the divisor is very close to zero, just use $u = 0$.



                                        In barycentric coordinates, $vec{v}_0$ is at $(0, 0)$; $vec{v}_1$ is at $(1,0)$, and $vec{v}_2$ is at $(0,1)$. The entire triangle is $0 le u, v, u + v le 1$. The edges are at $u = 0$, $v = 0$, and $u + v = 1$.



                                        In practice, you define the triangle inclusion test as
                                        $$Bigl(u ge -epsilonBigr) text{ and }
                                        Bigl(v ge -epsilonBigr) text{ and }
                                        Bigl(u le 1+epsilonBigr) text{ and }
                                        Bigl(v le 1+epsilonBigr) text{ and }
                                        Bigl(u + v le 1+epsilonBigr)$$

                                        where $epsilon$ represents the precision of your numerical coordinates. It is the largest positive number you consider equal to zero. (Similarly, if $D$ is the divisor for $u$ earlier, if $-epsilon le D le +epsilon$, use $u = 0$.)



                                        To linearly interpolate any value $c$ within the triangle, with $c = c_0$ at $vec{v}_0$, $c_1$ at $vec{v}_1$, and $c_2$ at $vec{v}_2$, you can use
                                        $$c(u,v) = (1 - v)bigl((1-u) c_0 + u c_1bigr) + v c_2$$




                                      All together, this means that you need only 15 (scalar) multiplications and less than thirty additions or subtractions, to find out if a point is within the triangle, or within a triangular prism extending from the triangle along its normal, including the barycentric coordinates needed for texture or color interpolation. (Color interpolation itself is just four multiplications per component, so typically 12 additional multiplications.) Nifty, eh?






                                      share|cite|improve this answer












                                      Although others have already answered the stated question, I'd like to give some advice to those doing similar to what OP is doing.





                                      1. Precalculate the unit normal vector to the triangle, and store it.



                                        If the triangle vertices are $vec{v}_0$, $vec{v}_1$, and $vec{v}_2$, then the triangle normal is usually defined as
                                        $$vec{n} = bigl(vec{v}_1 - vec{v}_0bigr)timesbigl(vec{v}_2 - vec{v}_0bigr)$$
                                        where $times$ denotes vector cross product. This is scaled to unit length,
                                        $$hat{n} = frac{vec{n}}{leftlVertvec{n}rightrVert} = frac{vec{n}}{sqrt{vec{n} cdot vec{n}}}$$



                                        This is best precalculated and stored, because the square root operation tends to be slow, and it is just one vector per triangle.
                                         




                                      2. A point is "above" the triangle if it is in the same halfspace as the triange normal vector, with respect to the plane formed by the triangle.



                                        (If you extend the triangle plane to infinity, it splits space into two halves. If you look at the triangle sideways, the point is "above" the triangle if it is in the same side as the normal is; and "below" if it is on the other side. If the point is on the triangle plane exactly, I recommend you use a clear and unambigous term for it; I use "exactly on the triangle" myself. I'm sure mathematicians have more precise terms, but for those of us who only use math as a tool for solving problems, making sure the terms are unambiguous suffices.)



                                        This means that point $vec{p}$ has signed distance
                                        $$d = bigl(vec{p} - vec{v}_0bigr) cdot hat{n}$$
                                        from the plane of the triangle. (Because all three triangle vertices are on the plane, you can use $vec{v}_1$ or $vec{v}_2$ in above; you'll still get the exact same result, within rounding error.)



                                        If $hat{n}$ is not an unit vector, i.e. $leftlVerthat{n}rightrVertne 1$, the distance is in units of the normal vector length.
                                         



                                      3. When you know the signed distance $d$ of the point $vec{p}$ from the plane, you can trivially project the point to the plane:
                                        $$vec{p}_text{plane} = vec{p} - d hat{n}$$
                                        If $hat{n}$ is not an unit vector, i.e. $leftlVerthat{n}rightrVertne1$, the right side is actually $vec{p} - hat{n}(d / lVerthat{n}rVert)$, and you need a "slow" square root operation here. Because you probably test many points per each triangle, it is well worth precalculating and storing the $hat{n}$ beforehand.
                                         



                                      4. To determine if $vec{p}_text{plane}$ is within the triangle, find out the barycentric coordinates $(u, v)$ corresponding to $vec{p}_text{plane}$ with respect to that triangle.



                                        To do this, check which axes have the smallest values in magnitude in $hat{n}$. Their order does not matter. (This essentially picks the axis along which to look at the triangle, with the triangle being as large as possible. We do this to minimize numerical errors.) There are three possibilities: $x$ and $y$; $x$ and $z$; and $y$ and $z$. The solution is obtained using the coordinates on those two axes.



                                        The solution for $vec{p}_text{plane} = (x, y, z)$ with $hat{n}$ having $x$ and $y$ components closest to zero, is
                                        $$begin{cases}
                                        displaystyle u = frac{ (x - x_0)(y_2 - y_0) - (y - y_0)(x_2 - x_0)}{ (x - x_2)(y_1 - y_0) - (y - y_2)(x_1 - x_0) } \
                                        displaystyle v = frac{ (y - y_0)(x_1 - x_0) - (x - x_0)(y_1 - y_0)}{ x_0 (y_1 - y_2) + x_1 (y_2 - y_0) + x_2 (y_0 - y_1) } \
                                        end{cases}$$

                                        The solution for the other axis pairs you'll find just by permuting the coordinates ($y$, $y_0$, $y_1$, $y_2$ to $z$, $z_0$, $z_1$, $z_2$ for $x$ and $z$ axes; and also $x$, $x_0$, $x_1$, $x_2$ to $y$, $y_0$, $y_1$, $y_2$ for $y$ and $z$).



                                        Also note that you'll want to calculate the divisor for $u$ first. It will be zero at $vec{v}_2$, where $u = 0$, so when the divisor is very close to zero, just use $u = 0$.



                                        In barycentric coordinates, $vec{v}_0$ is at $(0, 0)$; $vec{v}_1$ is at $(1,0)$, and $vec{v}_2$ is at $(0,1)$. The entire triangle is $0 le u, v, u + v le 1$. The edges are at $u = 0$, $v = 0$, and $u + v = 1$.



                                        In practice, you define the triangle inclusion test as
                                        $$Bigl(u ge -epsilonBigr) text{ and }
                                        Bigl(v ge -epsilonBigr) text{ and }
                                        Bigl(u le 1+epsilonBigr) text{ and }
                                        Bigl(v le 1+epsilonBigr) text{ and }
                                        Bigl(u + v le 1+epsilonBigr)$$

                                        where $epsilon$ represents the precision of your numerical coordinates. It is the largest positive number you consider equal to zero. (Similarly, if $D$ is the divisor for $u$ earlier, if $-epsilon le D le +epsilon$, use $u = 0$.)



                                        To linearly interpolate any value $c$ within the triangle, with $c = c_0$ at $vec{v}_0$, $c_1$ at $vec{v}_1$, and $c_2$ at $vec{v}_2$, you can use
                                        $$c(u,v) = (1 - v)bigl((1-u) c_0 + u c_1bigr) + v c_2$$




                                      All together, this means that you need only 15 (scalar) multiplications and less than thirty additions or subtractions, to find out if a point is within the triangle, or within a triangular prism extending from the triangle along its normal, including the barycentric coordinates needed for texture or color interpolation. (Color interpolation itself is just four multiplications per component, so typically 12 additional multiplications.) Nifty, eh?







                                      share|cite|improve this answer












                                      share|cite|improve this answer



                                      share|cite|improve this answer










                                      answered Nov 16 at 7:48









                                      Nominal Animal

                                      6,5402517




                                      6,5402517






























                                           

                                          draft saved


                                          draft discarded



















































                                           


                                          draft saved


                                          draft discarded














                                          StackExchange.ready(
                                          function () {
                                          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmath.stackexchange.com%2fquestions%2f2998875%2fhow-to-determine-if-a-point-is-above-or-below-a-plane-defined-by-a-triangle%23new-answer', 'question_page');
                                          }
                                          );

                                          Post as a guest















                                          Required, but never shown





















































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown

































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown







                                          Popular posts from this blog

                                          Plaza Victoria

                                          Puebla de Zaragoza

                                          Musa