查找在另外两个向量之间创建特定角度的向量

Finding vector that creates specific angle between two other vectors

提问人:satindressedup4 提问时间:7/24/2023 最后编辑:MBosatindressedup4 更新时间:7/24/2023 访问量:194

问:

给定点 A、点 B、点 J 和角度 X,找到角度 ACB 等于 X 的每个点 C。这一切都在 3D 空间中,其中点 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
数学 3D 几何 线性代数

评论

0赞 Mike 'Pomax' Kamermans 7/24/2023
把它画出来,告诉我们你为什么写你写的代码。

答:

1赞 MBo 7/24/2023 #1

有无限数量的点。C

它们位于具有中心角的圆弧上(D 情况)或 for(图片中的 C 情况)(内切角定理)。ABJ飞机上的图片:AOB = 2*XAOB = 2*(180-X)X>90

enter image description here

请注意,对于 是圆直径,可能位于圆的任何地方。X=90ABC

另请注意,有两个圆相对于同一和弦具有镜面对称性。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) 

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

0赞 Spektre 7/24/2023 #2

我们知道:

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

为了简化 let make 单位:a

a/=|a|

现在是已知的,也是未知的,它的单位受到约束,所以我们可以制作方程组:a,angleb

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)

对于非零,有无限的解决方案,所以你要么对齐到某个平面,将其简化为二维问题,导致 2 个方程组和 2 个未知数的系统,要么你只需选择一个坐标并将其设置为零并计算其余的坐标......如果未找到解决方案,请选择不同的坐标并重新计算。angbabb