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
  • 4
    \$\begingroup\$ What do you mean by “angle”? Are you asking how to calculate a normal? \$\endgroup\$ Aug 18, 2015 at 19:29
  • \$\begingroup\$ Maybe he's looking for tangent and bi-tangent \$\endgroup\$
    – Alan Wolfe
    Aug 19, 2015 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, 2015 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, 2015 at 0:32

2 Answers 2

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\$
8
  • \$\begingroup\$ I need the slope, though. A single scalar value not a vector. \$\endgroup\$
    – posfan12
    Aug 20, 2015 at 6:27
  • \$\begingroup\$ @posfan12 Angle between the ground plane and a triangle? \$\endgroup\$
    – James0124
    Aug 20, 2015 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\$ Aug 20, 2015 at 6:37
  • \$\begingroup\$ Why no slope? Two planes intersect at only one angle. \$\endgroup\$
    – posfan12
    Aug 21, 2015 at 0:04
  • \$\begingroup\$ oops , you're absolutely right \$\endgroup\$ Aug 21, 2015 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\$
2
  • \$\begingroup\$ Oh wow! Three years later! That's great, thanks for coming back and posting your solution :) \$\endgroup\$
    – Vaillancourt
    Aug 9, 2018 at 0:10
  • \$\begingroup\$ Can someone confirm this produces accurate results? I'm trying to review slope for rain drainage but I'm getting interesting results using the function above. i.imgur.com/RTIK3Fc.png white labels are for confirmed edge grade (deg/90*100 basically) and green labels is for the face grade. Shouldn't the face share the grade of the 2.85% edge since the top edge is at 0%? \$\endgroup\$ Jan 17 at 22:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .