Search code examples
pythonnumpycomputational-geometry

Finding the angle between all positive and negative combinations of two 3D vectors


Following this problem for calculating the angle between two 3D angles, I want to expand it in a way that it calculates all the possible positive and negative combinations of the angles.

For instance I have the following code from the same link that calculates the angle between the (1,1,5) and (-1,1,2):

import numpy as np
import vg

vec1 = np.array([1, 1, 5])
vec2 = np.array([-1, 1, 2])

angle= vg.angle(vec1, vec2)
print(angle)

Now I want a small function that calculates all the possible comibations of positive and negatives of each vector and gives a list of all the angles.

For instance it calculates the following pairs: (1,1,5)(-1,1,2), (1,1,-5)(-1,1,2), (1,-1,-5)(-1,1,2) etc. This seems to be quite easy but I couldn't figure it out.

Side question: how I can ask the input() function to get a vector? I know how it works for strings and numbers but can you ask it to get the input data in a special format from user? Like (1,2,3)?


Solution

  • vec_comb[:,:3] has all the combinations of vec1, and vec_comb[:,3:] has all the combinations for vec2

    import numpy as np
    import vg
    import itertools
    
    
    vec1 = np.array([1, 1, 5])
    vec2 = np.array([-1, 1, 2])
    
    vec_concat = np.hstack((vec1, vec2))
    
    
    l = [1,-1]
    comb = np.array(list(itertools.product(l, repeat=vec_concat.shape[0])))
    
    vec_comb = np.einsum('i, ji -> ji', vec_concat, comb)
    angle_comb = vg.angle(vec_comb[:,:3], vec_comb[:, 3:])
    print(angle_comb)
    
    

    Output:

    [ 38.2169233  141.7830767   51.05755873 160.52877937  19.47122063
     128.94244127  38.2169233  141.7830767  141.7830767   38.2169233
     160.52877937  51.05755873 128.94244127  19.47122063 141.7830767
      38.2169233   51.05755873 160.52877937  38.2169233  141.7830767
      38.2169233  141.7830767   19.47122063 128.94244127 160.52877937
      51.05755873 141.7830767   38.2169233  141.7830767   38.2169233
     128.94244127  19.47122063  19.47122063 128.94244127  38.2169233
     141.7830767   38.2169233  141.7830767   51.05755873 160.52877937
     128.94244127  19.47122063 141.7830767   38.2169233  141.7830767
      38.2169233  160.52877937  51.05755873  38.2169233  141.7830767
      19.47122063 128.94244127  51.05755873 160.52877937  38.2169233
     141.7830767  141.7830767   38.2169233  128.94244127  19.47122063
     160.52877937  51.05755873 141.7830767   38.2169233 ]