Ориентация 2d патчей matplotlib, преобразованных в 3d с произвольными нормалями, не соответствует ориентации, заданной колчаном - PullRequest
0 голосов
/ 10 февраля 2019

Я следовал Как можно преобразовать 2D-патчи matplotlib в 3D с произвольными нормалями? , чтобы преобразовать 2-й патч matplotlib (окружность) в 3d-патч с произвольным вектором нормалей.Однако, когда я строю этот вектор нормалей, используя колчан , оказывается, что патч и вектор не перпендикулярны.

Вот мой код (где я загружаю функции, заданные как 2-й ответв ссылке выше):


import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d import art3d
from mpl_toolkits.mplot3d import proj3d


def rotation_matrix(v1,v2):
    """
    Calculates the rotation matrix that changes v1 into v2.
    """
    v1/=np.linalg.norm(v1)
    v2/=np.linalg.norm(v2)

    cos_angle=np.dot(v1,v2)
    d=np.cross(v1,v2)
    sin_angle=np.linalg.norm(d)

    if sin_angle == 0:
        M = np.identity(3) if cos_angle>0. else -np.identity(3)
    else:
        d/=sin_angle

        eye = np.eye(3)
        ddt = np.outer(d, d)
        skew = np.array([[    0,  d[2],  -d[1]],
                      [-d[2],     0,  d[0]],
                      [d[1], -d[0],    0]], dtype=np.float64)

        M = ddt + cos_angle * (eye - ddt) + sin_angle * skew

    return M

def pathpatch_2d_to_3d(pathpatch, z = 0, normal = 'z'):
    """
    Transforms a 2D Patch to a 3D patch using the given normal vector.

    The patch is projected into they XY plane, rotated about the origin
    and finally translated by z.
    """
    if type(normal) is str: #Translate strings to normal vectors
        index = "xyz".index(normal)
        normal = np.roll((1,0,0), index)

    path = pathpatch.get_path() #Get the path and the associated transform
    trans = pathpatch.get_patch_transform()

    path = trans.transform_path(path) #Apply the transform

    pathpatch.__class__ = art3d.PathPatch3D #Change the class
    pathpatch._code3d = path.codes #Copy the codes
    pathpatch._facecolor3d = pathpatch.get_facecolor #Get the face color    

    verts = path.vertices #Get the vertices in 2D

    M = rotation_matrix(normal,(0, 0, 1)) #Get the rotation matrix

    pathpatch._segment3d = np.array([np.dot(M, (x, y, 0)) + (0, 0, z) for x, y in verts])

def pathpatch_translate(pathpatch, delta):
    """
    Translates the 3D pathpatch by the amount delta.
    """
    pathpatch._segment3d += delta



fig = plt.figure()
ax = fig.gca(projection='3d')
from matplotlib.patches import Circle, PathPatch

dirvec =(-0.420,  -0.757,  -0.500)
normal=dirvec
p = Circle((0,0), 18., facecolor = 'g', alpha = .6)
ax.add_patch(p)
pathpatch_2d_to_3d(p, z = 0, normal = normal)
pathpatch_translate(p, (0.,0.,0.)  )
ax.quiver( 0.,0.,0., -0.420,  -0.757,  -0.500,   length=50, color='g', lw=2, pivot='tail')
xlim( -50., 50. );ylim( -50., 50. );ax.set_zlim(-50.,50)

Результат не далеко от перпендикуляра, но явно не точно на 90 градусов, как должно быть.Я ценю любую помощь, чтобы уточнить, что происходит.Спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...