Given point A, point B, point J, and an angle X, find every point C where angle ACB is equal to X. Its all in 3d space where point J forms a plane with A and B so all of the solutions C should lie on that plane.
The solution points C never give me the correct angles. Also, how many solutions are there when X=90? How about 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)
Output:
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
There is infinite number of C
points.
They lie on the circle arc with central angle AOB = 2*X
(D case) or AOB = 2*(180-X)
for X>90
(C case at the picture) (Inscribed angle theorem). Picture on ABJ plane:
Note that for X=90
AB
is circle diameter, C
might be in any place of the circle.
Also note there are two circles with mirror symmetry relative to the same AB
chord.
To get formula for all possible C points, we can do the next:
Find normal to the plane:
N = AB.cross.AJ
Get vector perpendicular to AB in the plane and normalize it:
P = AB.cross.N
uP = P / len(P)
Also normalized AB:
uAB = AB / len(AB)
Get middle of AB
chord
M = A + AB/2
Get angle for AB
chord:
if X > Pi/2:
Alpha = 2 * (Pi - X)
else:
Alpha = 2 * X
Get circle center and radius
HalfLen = len(AB) / 2
O = M + uP * HalfLen / Tan(Alpha/2) // M - uP... for mirrored circle
R = HalfLen / Cos(Alpha/2)
Now we can generate all points using angle parameter t
in range (-Alpha/2.. +Alpha/2)
C = O + R * uP * Cos(t) + R * uAB * Sin(t)
(Note we need to check and change signs to describe all cases)