3
\$\begingroup\$

I have lots of triangles in 3D space. How do I determine the slope/angle of these triangles with respect to a fixed ground plane? I need pseudo code examples at the very least.

\$\endgroup\$
  • 4
    \$\begingroup\$ What do you mean by “angle”? Are you asking how to calculate a normal? \$\endgroup\$ – Anko Aug 18 '15 at 19:29
  • \$\begingroup\$ Maybe he's looking for tangent and bi-tangent \$\endgroup\$ – Alan Wolfe Aug 19 '15 at 2:36
  • \$\begingroup\$ I'm not looking for a vector. I need the slope of the plane formed by the triangle with respect to the ground plane. The angle between the floating plane and the ground plane will be okay too. \$\endgroup\$ – posfan12 Aug 20 '15 at 6:35
  • \$\begingroup\$ I guess the angle between the normal and the ground would be okay too. From that I can get the information I need. \$\endgroup\$ – posfan12 Aug 21 '15 at 0:32
4
\$\begingroup\$

EDIT (added short steps):

  1. get triangle normal vector v1 (normalized)

  2. get reference surface normal vector v2 (normalized)

  3. get angle between normals : angle = acos(v1•v2) (where • = 'dot' product )

  4. get slope = Tan(angle)

if you need a surface normal here come the simple algoritm :

A surface normal for a triangle can be calculated by taking the vector cross product of two edges of that triangle. The order of the vertices used in the calculation will affect the direction of the normal (in or out of the face w.r.t. winding).

So for a triangle p1, p2, p3, if the vector U = p2 - p1 and the vector V = p3 - p1 then the normal N = U X V and can be calculated by:

Nx = UyVz - UzVy

Ny = UzVx - UxVz

Nz = UxVy - UyVx

EDIT: to get the angle between reference plane and triangle plane , you can calculate the angle between reference plane normal vector (call it Nref) and triangle normal (N already calculated). Here the angle between 3d vectors math:

"If v1 and v2 are normalised so that |v1|=|v2|=1, then,

angle = acos(v1•v2)"

Finaly from angle to slope : Tan(angle)

\$\endgroup\$
  • \$\begingroup\$ I need the slope, though. A single scalar value not a vector. \$\endgroup\$ – posfan12 Aug 20 '15 at 6:27
  • \$\begingroup\$ @posfan12 Angle between the ground plane and a triangle? \$\endgroup\$ – JamesAMD Aug 20 '15 at 6:30
  • \$\begingroup\$ I think you can't define a single slope. You can get x-slope and y-slope , and can calculate them from normal vector x and y components \$\endgroup\$ – dnk drone.vs.drones Aug 20 '15 at 6:37
  • \$\begingroup\$ Why no slope? Two planes intersect at only one angle. \$\endgroup\$ – posfan12 Aug 21 '15 at 0:04
  • \$\begingroup\$ oops , you're absolutely right \$\endgroup\$ – dnk drone.vs.drones Aug 21 '15 at 6:21
0
\$\begingroup\$

Based on dnk drone.vs.drones' instructions I created the following JavaScript:

function Get_Angle(vertex_1, vertex_2, vertex_3)
{
    // get two vectors in the triangle
    var vector_u =
    [
        vertex_2[0] - vertex_1[0],
        vertex_2[1] - vertex_1[1],
        vertex_2[2] - vertex_1[2]
    ]
    var vector_v =
    [
        vertex_3[0] - vertex_1[0],
        vertex_3[1] - vertex_1[1],
        vertex_3[2] - vertex_1[2]
    ]
    // calculate the cross product to get the normal
    var vector_n =
    [
        vector_u[1] * vector_v[2] - vector_u[2] * vector_v[1],
        vector_u[2] * vector_v[0] - vector_u[0] * vector_v[2],
        vector_u[0] * vector_v[1] - vector_u[1] * vector_v[0]
    ]
    // calculate the magnitude or length of the normal vector
    var magnitude_n = Math.sqrt(vector_n[0] * vector_n[0] + vector_n[1] * vector_n[1] + vector_n[2] * vector_n[2])
    // normalize the normal vector
    vector_n =
    [
        vector_n[0]/magnitude_n,
        vector_n[1]/magnitude_n,
        vector_n[2]/magnitude_n
    ]
    // the normal of the ground plane
    var vector_r = [0,1,0]
    // calculate the dot product of vector_n and vector_r
    var dot_product = vector_n[0] * vector_r[0] + vector_n[1] * vector_r[1] + vector_n[2] * vector_r[2]
    // calculate the angle between vector_n and vector_r
    var angle_between = Math.acos(dot_product)
    // returned value is less than or equal to pi
    return angle_between
}
\$\endgroup\$
  • \$\begingroup\$ Oh wow! Three years later! That's great, thanks for coming back and posting your solution :) \$\endgroup\$ – Alexandre Vaillancourt Aug 9 '18 at 0:10

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.