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.
-
4\$\begingroup\$ What do you mean by “angle”? Are you asking how to calculate a normal? \$\endgroup\$– AnkoAug 18, 2015 at 19:29
-
\$\begingroup\$ Maybe he's looking for tangent and bi-tangent \$\endgroup\$– Alan WolfeAug 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\$– posfan12Aug 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\$– posfan12Aug 21, 2015 at 0:32
2 Answers
EDIT (added short steps):
get triangle normal vector
v1
(normalized)get reference surface normal vector
v2
(normalized)get angle between normals :
angle = acos(v1•v2)
(where • = 'dot' product )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)
-
\$\begingroup\$ I need the slope, though. A single scalar value not a vector. \$\endgroup\$– posfan12Aug 20, 2015 at 6:27
-
\$\begingroup\$ @posfan12 Angle between the ground plane and a triangle? \$\endgroup\$ 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\$– posfan12Aug 21, 2015 at 0:04
-
\$\begingroup\$ oops , you're absolutely right \$\endgroup\$ Aug 21, 2015 at 6:21
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
}
-
\$\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