Как преобразовать 2D-точку на определенной плоскости в плоские координаты uv обратно в 3D-координаты xyz?

У меня есть определенная плоскость (которая оказывается ортогональной вектору, определяемому двумя точками xyz в трехмерном пространстве). Я могу спроецировать любую точку xyz на плоскость и представить эту проекцию координатного пространства uv. Я хотел бы взять произвольную точку в координатном пространстве uv и узнать, каковы ее координаты в пространстве xyz.

a = x2 - x1
b = y2 - y1
c = z2 - z1
d = -1*(a*x1 + b*y1 + c*z1)
magnitude = (a**2 + b**2 + c**2)**.5
u_magnitude = (b**2 + a**2)**.5

normal = [a/magnitude, b/magnitude, c/magnitude]
u = [b/u_magnitude, -a/u_magnitude, 0]
v = np.cross(normal, u)

p_u = np.dot(u,[x1,y1,z1])
p_v = np.dot(v,[x1,y1,z1])

Я считаю, что этот код точно создает нужную мне плоскость и назначит точку x1, y1, z1 в координатах uv для p_u, p_v. Я чувствую, что у меня есть все, что мне нужно, чтобы сделать обратную операцию, но я не знаю, как это сделать. Если у меня есть точка u0,v0, как мне найти x0,y0,z0, описывающую ее положение в трехмерном пространстве?


person jipkin    schedule 30.05.2019    source источник
comment
Как бы вы нашли уникальную пару осей на плоскости для любого произвольного нормального направления?   -  person meowgoesthedog    schedule 31.05.2019


Ответы (1)


Судя по определению в тексте (не читая код), проблема определена нечетко - так как существует бесконечное количество плоскостей, ортогональных заданному вектору (представьте все варианты как плоскости на разных "смещениях" вдоль линии от первое указывает на второе). Что вам нужно, так это сначала выбрать точку, через которую должен пройти самолет.

Во-вторых, когда мы преобразуем пару (U, V) в трехмерную точку, я предполагаю, что вы имеете в виду трехмерную точку на плоскости.

Однако, пытаясь быть более конкретным, вот ваш код с документацией о том, как я его понимаю, и как сделать обратное:

# ### The original computation of the plane equation ###
# Given points p1 and p2, the vector through them is W = (p2 - p1)
# We want the plane equation Ax + By + Cz + d = 0, and to make
# the plane prepandicular to the vector, we set (A, B, C) = W
p1 = np.array([x1, y1, z1])
p2 = np.array([x2, y2, z2])

A, B, C = W = p2 - p1

# Now we can solve D in the plane equation. This solution assumes that
# the plane goes through p1.
D = -1 * np.dot(W, p1)

# ### Normalizing W ###
magnitude = np.linalg.norm(W)
normal = W / magnitude

# Now that we have the plane, we want to define
# three things:
# 1. The reference point in the plane (the "origin"). Given the
#    above computation of D, that is p1.
# 2. The vectors U and V that are prepandicular to W
#    (and therefore spanning the plane)

# We take a vector U that we know that is perpendicular to
# W, but we also need to make sure it's not zero.
if A != 0:
    u_not_normalized = np.array([B, -A, 0])
else:
    # If A is 0, then either B or C have to be nonzero
    u_not_normalized = np.array([0, B, -C])
u_magnitude = np.linalg.norm(u_not_normalized)

# ### Normalizing W ###
U = u_not_normalized / u_magnitude
V = np.cross(normal, U)

# Now, for a point p3 = (x3, y3, z3) it's (u, v) coordinates would be
# computed relative to our reference point (p1)
p3 = np.array([x3, y3, z3])

p3_u = np.dot(U, p3 - p1)
p3_v = np.dot(V, p3 - p1)

# And to convert the point back to 3D, we just use the same reference point
# and multiply U and V by the coordinates
p3_again = p1 + p3_u * U + p3_v * V
person Barak Itkin    schedule 30.05.2019
comment
Спасибо, вы были правы в том, что мне действительно нужна трехмерная точка на плоскости. Я считаю, что это то, что мне нужно, и это заработает. (И чтобы уточнить, я считаю, что в последней строке вашего кода u и v должны быть U и V?) - person jipkin; 31.05.2019
comment
Также я считаю, что u_magnitude = np.linalg.norm(u) должно быть u_magnitude = np.linalg.norm(u_not_normalized) - person jipkin; 31.05.2019
comment
@jipkin - Исправлены небольшие проблемы в коде, на который вы указали, вы были правы в обоих комментариях :) - person Barak Itkin; 01.06.2019