math3dgeometryunreal-engine4normals

Positioning objects parallel with a mesh


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:

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.


Solution

  • 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,:]))