pythonmathgraphics2dcoordinate-transformation

2d cartesian plane transformation, mapping from one plane to other


If you have 4 points (xi,yi); 1<=i<=4 And you want to transform them like projective transformation to new points (Xi,Yi), how do you do it?

It can be done with matrixes... Refer here for indepth explanation transformation for css

I just answered the question myself so yeah...I hope that it helps somebody.


Solution

  • import numpy as np
    
    def derive_transformation_matrix(points, mapped_points):
        # Create the matrix A for the linear equations
        A = []
        for i in range(len(points)):
            xi, yi = points[i]
            ui, vi = mapped_points[i]
            A.append([xi, yi, 1, 0, 0, 0, -ui * xi, -ui * yi, -ui])
            A.append([0, 0, 0, xi, yi, 1, -vi * xi, -vi * yi, -vi])
        
        # Convert A to a numpy array
        A = np.array(A)
    
        # Perform Singular Value Decomposition to solve the linear equations
        _, _, V = np.linalg.svd(A)
        H = V[-1] / V[-1, -1]
    
        # Reshape H to a 3x3 transformation matrix
        H_matrix = H.reshape((3, 3))
    
        return H_matrix
    
    
    def apply_transformation(matrix, x, y):
        # Create the homogeneous point (x, y, 1)
        point = np.array([x, y, 1])
    
        # Perform the transformation using matrix multiplication
        transformed_point = np.dot(matrix, point)
    
        # Convert the transformed point to Cartesian coordinates (u, v)
        u = transformed_point[0] / transformed_point[2]
        v = transformed_point[1] / transformed_point[2]
    
        return round(u, 8), round(v, 8)  # Rounding to 8 decimal places
    
    

    Give 4 points as source and destination

    # Given points and mapped_points
    points = [(0, 0), (1, 0), (1, -1), (0, -1)]
    mapped_points = [(0, 0), (2, 0), (2, -2), (0, -2)]
    
    # Derive the transformation matrix
    transformation_matrix = derive_transformation_matrix(points, mapped_points)
    
    # Given point (x, y)
    x = 32.5
    y = 32.5
    
    # Apply the transformation to get the new coordinates (u, v)
    point = np.dot(transformation_matrix, [x, y, 1])
    point /= point[2]
    
    # Round the transformed coordinates (u, v) to 8 decimal places
    u, v = round(point[0], 8), round(point[1], 8)
    
    print(f"Original Point: ({x}, {y})")
    print(f"Transformed Point: ({u}, {v})")