代码之家  ›  专栏  ›  技术社区  ›  satindressedup4

查找在其他两个矢量之间创建特定角度的矢量

  •  0
  • satindressedup4  · 技术社区  · 1 年前

    给定点A、点B、点J和角度X,找到角度ACB等于X的每个点C。它都在三维空间中,点J与A和B形成一个平面,所以所有的解C都应该位于该平面上。

    解点C从来没有给我正确的角度。此外,当X=90时,有多少个解决方案?X怎么样=90?

    def angle_between_vectors(v1, v2):
        # Calculate the angle between two vectors in degrees
        angle_rad = np.arccos(np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2)))
        return np.degrees(angle_rad)
    
    def find_points_with_angle_3d(A, B, J, X):
    
        # J forms a plane with A and B on which any solution C must lie
        # X is the angle (degrees) at which any solution C should make with A and B
    
        # set A, B, J as vectors
        A = np.array(A)
        B = np.array(B)
        J = np.array(J)
    
        # calculate vectors AB and AJ
        AB = B - A
        AJ = J - A
    
        # unit vector AB
        uAB = AB / np.linalg.norm(AB)
    
        # normal vector of the plane
        N = np.cross(AB, AJ)
    
        # unit vector N
        uN = N / np.linalg.norm(N)
    
        # project AJ onto plane
        AJ_proj = np.dot(AJ, uN) * uN
    
        # vector orthogonal to N and AB
        perpendicular_vector = np.cross(uN, AB)
    
        C1 = A + math.cos(np.radians(X)) * AJ_proj + math.sin(np.radians(X)) * perpendicular_vector
    
        C2 = A + math.cos(np.radians(X)) * AJ_proj - math.sin(np.radians(X)) * perpendicular_vector
    
        print("C1:", C1)
        print("C2:", C2)
    
        # Calculate angles ACB for C1 and C2
        AC1 = C1 - A
        BC1 = C1 - B
        angle_C1 = angle_between_vectors(AC1, BC1)
    
        AC2 = C2 - A
        BC2 = C2 - B
        angle_C2 = angle_between_vectors(AC2, BC2)
    
        print("Angle ACB for C1:", angle_C1)
        print("Angle ACB for C2:", angle_C2)
    
        return C1, C2
    
    A = (2, 1, 3)
    B = (4, 5, 4)
    J = (7, 7, 7)
    angle_X_deg = 45
    C1, C2 = find_points_with_angle_3d(A, B, J, angle_X_deg)
    

    输出

    C1: [ 3.55904966 -0.39776866  5.47297532]
    C2: [0.44095034 2.39776866 0.52702468]
    Angle ACB for C1: 54.735610317245346
    Angle ACB for C2: 54.735610317245346
    
    1 回复  |  直到 1 年前
        1
  •  1
  •   MBo    1 年前

    有无限多 C 点。

    它们位于圆心角的圆弧上 AOB = 2*X (D情况)或 AOB = 2*(180-X) 对于 X>90 (图片中的C案例)( Inscribed angle theorem ). ABJ平面上的图片:

    enter image description here

    请注意,对于 X=90 AB 是圆直径, C 可能在圆圈的任何位置。

    还要注意的是 相对于同一圆镜像对称的圆 AB 和弦


    要获得所有可能的C点的公式,我们可以执行以下操作:

    查找平面的法线:

     N = AB.cross.AJ
    

    获取垂直于平面中AB的向量,并对其进行归一化:

    P = AB.cross.N
    uP = P / len(P)
    

    同样标准化AB:

    uAB = AB / len(AB)  
    

    进入中间 AB 和弦

    M = A + AB/2
    

    获取的角度 AB 和弦

    if X > Pi/2:
        Alpha = 2 * (Pi - X)
    else:
        Alpha = 2 * X
    

    获取圆心和半径

    HalfLen = len(AB) / 2
    O = M + uP * HalfLen / Tan(Alpha/2)   // M - uP... for mirrored circle
    
    R = HalfLen / Cos(Alpha/2)
    

    现在我们可以使用角度参数生成所有点 t 在范围内 (-Alpha/2.. +Alpha/2)

    C = O + R * uP * Cos(t) + R * uAB * Sin(t) 
    

    (注意,我们需要检查和更改标志来描述所有情况)

        2
  •  0
  •   Spektre    1 年前

    我们知道:

    cos(ang) = dot(a,b)/(|a|*|b|)
    

    简化let make a 单元

    a/=|a|
    

    现在 a,angle 已知且 b 是未知的,其单位受到约束,因此我们可以建立方程组:

    cos(ang) = (a.x * b.x) + (a.y * b.y) + (a.z * b.z)
           1 = (b.x * b.x) + (b.x * b.x) + (b.x * b.x)
    

    对于非零 ang 有无限的解决方案 b 所以你要么对准某个平面 在于将其简化为二维问题,导致2个方程和2个未知数的系统,或者您只需选择一个坐标 b 并将其设置为零,然后计算其余的。。。如果没有找到解决方案,则选择的不同坐标 b 并再次计算。