[Python] Draw the projection as the observer moves

Discussão em 'Python' iniciado por Stack, Junho 10, 2025.

  1. Stack

    Stack Membro Participativo

    I am not sure where to ask this question, but I will still go ahead.

    I am trying to draw this scenario in python. Please, see the image.

    My code is the following:

    from matplotlib import pyplot as plt
    import numpy as np

    fig = plt.figure(figsize=(15, 7))
    ax = fig.add_subplot(111, projection='3d')

    # --- Observer position (change this to move observer) ---
    O = np.array([2, 0, 0]) # Change these coordinates to move observer
    ax.scatter(*O, color='black')
    ax.text(*O, "O (Observer)", fontsize=10, verticalalignment='bottom')

    # --- Fixed Image Plane P at z = 5 ---
    plane_z = 5
    xx, yy = np.meshgrid(np.linspace(-2.5, 2.5, 10), np.linspace(-2.5, 2.5, 10))
    zz = np.ones_like(xx) * plane_z
    ax.plot_surface(xx, yy, zz, alpha=0.2, color='gray')
    ax.text(0, -2.8, plane_z, "P (Image Plane)", fontsize=10)

    # --- Circle C at z = 10 (Fixed) ---
    theta = np.linspace(0, 2 * np.pi, 200)
    r = 1.5
    x_c = r * np.cos(theta)
    y_c = r * np.sin(theta)
    z_c = np.ones_like(x_c) * 10
    ax.plot(x_c, y_c, z_c, color='blue', label='C (Original Circle)')
    ax.text(0, -2, 10, "C", fontsize=10)

    # --- Project each point on C to plane P from observer O ---
    projected_points = []
    for i in range(len(x_c)):
    Px, Py, Pz = x_c, y_c, z_c
    D = np.array([Px - O[0], Py - O[1], Pz - O[2]])
    t = (plane_z - O[2]) / D[2] # Solve for intersection with z = plane_z
    P_proj = O + t * D
    projected_points.append(P_proj)

    projected_points = np.array(projected_points)
    x_proj, y_proj, z_proj = projected_points[:,0], projected_points[:,1], projected_points[:,2]

    # --- Plot the projected ellipse (no centering adjustment) ---
    ax.plot(x_proj, y_proj, z_proj, color='red', label="C' (Projected Ellipse)")
    ax.text(np.mean(x_proj), np.mean(y_proj) + 2, plane_z, "C'", fontsize=10)

    # --- Draw projection rays ---
    for i in range(0, len(x_c), 15):
    ax.plot([O[0], x_c], [O[1], y_c], [O[2], z_c], color='gray', linestyle='dashed', linewidth=0.5)

    # --- Axes setup ---
    ax.set_xlim(-3, 3)
    ax.set_ylim(-3, 3)
    ax.set_zlim(-1, 12)
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_zlabel('Z')
    ax.view_init(elev=10, azim=0)

    ax.set_title(f'Observer at ({O[0]}, {O[1]}, {O[2]}) Projecting Circle C to Fixed Plane P')
    plt.legend()
    plt.tight_layout()
    plt.show()


    Problem is that if I change the observer's position in the code: i.e
    from O = np.array([2, 0, 0]) to O = np.array([10, 0, 0]) what happens is that red circle also moves with the observer. The goal is that only observer moves and everything else stays fixed. This should cause red circle to become the ellipse the more observer moves.

    I am not an expert in python, so don't know how to fix this.

    Continue reading...

Compartilhe esta Página