Positioning objects parallel with a mesh

Viewed 85

I'm trying to align multiple line objects along a human body circumference depending on the orientation of the triangles from the mesh. I would like to put the lines parallel to the mesh. I correctly assign the position for the lines along the circumference, but I also need to add the rotation of the lines such that to be parallel with the body. The body is a mesh formed by multiple triangles and every line is "linked" with a triangle.

All I have is:

  • 3 points for the closest triangle from the mesh for every line

  • The normal of the triangle

  • The positions for the instantiated lines (2 points, start and end)

I need to calculate the angle for every X, Y, Z axes for the line such that the normal of the triangle is perpendicular with the line mesh. I don't know how to get the desired angle. I really appreciate if someone would like to help me.

input:

FVector TrianglePoints[3];

FVector Triangle_Normal; //Calculated as (B-A)^(C-A), where A,B,C are the points of the triangle

FVector linePosition; //I also have the start line and the endLine position if that helps

ouput:

//FRotator rotation(x,y,z), such that the triangle normal and the line object to be perpendicular.

An overview of the circumference line construction. Now the rotation is calculated using the Start position and End position for each line. When we cross some irregular parts of the mesh we want to rotate the lines correctly. Now the rotation is fixed, depending just on the line start and end position.

2 Answers

If I have understood correctly your goal, here is some related vector geometry:

A,B,C are the vertices of the triangle:
A = [xA, yA, zA],
B = [xB, yB, zB]
C = [xC, yC, zC]

K,L are the endpoints of the line-segment:
K = [xK, yK, zK]
L = [xL, yL, zL]

vectors are interpreted as row-vectors
by . I denote matrix multiplication
by x I denote cross product of 3D vectors
by t() I denote the transpose of a matrix
by | | I denote the norm (magnitude) of a vector

Goal: find the rotation matrix and rotation transformation of segment KL 
      around its midpoint, so that after rotation KL is parallel to the plane ABC
      also, the rotation is the "minimal" angle rotation by witch we need to 
      rotate KL in order to make it parallel to ABC

AB = B - A
AC = C - A
KL = L - K

n = AB x AC
n = n / |n|

u = KL x n
u = u / |u|

v = n x u

cos = ( KL . t(v) ) / |KL|
sin = ( KL . t(n) ) / |KL|   

U = [[ u[0],  u[1],  u[2] ],
     [ v[0],  v[1],  v[2] ],
     [ n[0],  n[1],  n[2] ],

R = [[1,    0,    0],
     [0,  cos,  sin],
     [0, -sin,  cos]]

ROT = t(U).R.U

then, one can rotate the segment KL around its midpoint 
M = (K + L)/2

Y = M + ROT (X - M)

Here is a python script version

A = np.array([0,0,0])
B = np.array([3,0,0])
C = np.array([2,3,0])

K = np.array([ -1,0,1])
L = np.array([  2,2,2])
KL = L-K

U = np.empty((3,3), dtype=float)

U[2,:] = np.cross(B-A, C-A)
U[2,:] = U[2,:] / np.linalg.norm(U[2,:])

U[0,:] = np.cross(KL, U[2,:])
U[0,:] = U[0,:] / np.linalg.norm(U[0,:])

U[1,:] = np.cross(U[2,:], U[0,:])

norm_KL = np.linalg.norm(KL)
cos_ = KL.dot(U[1,:]) / norm_KL 
sin_ = KL.dot(U[2,:]) / norm_KL 

R = np.array([[1,    0,    0],
              [0, cos_, sin_],
              [0,-sin_, cos_]])

ROT = (U.T).dot(R.dot(U))

M = (K+L) / 2

K_rot = M + ROT.dot( K - M )
L_rot = M + ROT.dot( L - M )

print(L_rot)
print(K_rot)
print(L_rot-K_rot)
print((L_rot-K_rot).dot(U[2,:]))

A more inspired solution was to use a procedural mesh, generated at runtime, that have all the requirements that I need:

  • Continuously along multiple vertices
  • Easy to apply a UV map for texture tiling
  • Can be updated at runtime
  • Isn't hard to compute/work with it
Related