三维空间中旋转两个面使其平行python代码

三维空间中旋转两个面使其平行: 平面的法向量代表这个面的方向,只需要求解两个法向量的旋转矩阵即可。

如果输出的两个面的法向量的夹角为0 或 3.14(近似为)则成功。

#归一化
def normal(vertex):
    _range = np.max(vertex) - np.min(vertex)
    vertex = (vertex - np.min(vertex)) / _range
    return vertex

#罗德里格斯公式
def rodrigues_rotation(r, theta):
    # n旋转轴[3x1]
    # theta为旋转角度
    # 旋转是过原点的,n是旋转轴
    r = np.array(r).reshape(3, 1)
    rx, ry, rz = r[:, 0]
    M = np.array([
        [0, -rz, ry],
        [rz, 0, -rx],
        [-ry, rx, 0]
    ])
    R = np.eye(3)
    R[:3, :3] = np.cos(theta) * np.eye(3) +        \
                (1 - np.cos(theta)) * r @ r.T +    \
                np.sin(theta) * M
    return R

if __name__ == '__main__':
    inject_path = 'test1.obj'  # basic_gem.obj
    obj_path = 'test2.obj' # T5.obj
    inject_target_face_index = 0 #6
    obj_target_face_index = 0
    inject = trimesh.load(inject_path)
    # 将inject归一化
    inject.vertices = normal(inject.vertices)
    obj = trimesh.load(obj_path)
    inject_faces_list = inject.faces.tolist()
    obj_faces_list = obj.faces.tolist()

    # 计算两个面间的旋转矩阵
    # 得到两个物体中一个平面的法向量
    inject_normal = inject.face_normals[inject_target_face_index]
    inject_face_points = inject.vertices[inject.faces[inject_target_face_index]]

    obj_normal = obj.face_normals[obj_target_face_index]
    obj_face_points = obj.vertices[obj.faces[obj_target_face_index]]

    # 计算的是以pi为单位的两个平面法线的角度,
    deta = math.acos(np.dot(inject_normal, obj_normal) / (np.linalg.norm(inject_normal) * np.linalg.norm(obj_normal)))
    print('original_deta: {}'.format(deta))
    # 得到两个法线组成的平面的法线
    np.cross([0,0,1], [0,1,0])
    plane_normal = np.cross(inject_normal, obj_normal)
    # 此时得到的平面的法线指的是垂直于 obj_normal 和 inject_normal 组成的平面的法线, 过原点
    # 使用罗德里格斯公式计算两个平面的旋转
    R = rodrigues_rotation(plane_normal, deta)
    np.transpose(np.matrix(R)) * np.matrix(R)

    for i in range(len(inject.vertices)):
        inject.vertices[i] = np.matrix(inject.vertices[i]) * np.transpose(np.matrix(R))

    # 计算两个面间的平移向量
    inject_point = inject.vertices[inject_faces_list[inject_target_face_index][0]]
    obj_point = obj.vertices[obj_faces_list[obj_target_face_index][0]]
    v = inject_point - obj_point

    inject_face_points = inject.vertices[inject.faces[inject_target_face_index]]
    inject_normal = np.cross(inject_face_points[0]-inject_face_points[2], inject_face_points[1]-inject_face_points[2])
    deta = math.acos(np.dot(inject_normal, obj_normal) / (np.linalg.norm(inject_normal) * np.linalg.norm(obj_normal)))
    print('after_deta: {}'.format(deta))```

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值