Three-dimensional transformation matrix practice – rotation, scaling, mirroring, cross-cutting, translation, and orthogonal projection of three-dimensional point clouds

1. Rotation matrix (right-handed coordinate system)

Rotate around the x-axis

Rotation matrix: The matrix on the right is the original coordinates of the point cloud, and the matrix on the left is the rotation matrix

\begin{bmatrix} 1 & amp;0 & amp;0 \ 0 & amp;cos\beta & amp;-sin\beta \ 0 & amp;sin \beta & cos\beta \end{bmatrix} \begin{bmatrix } x\ y \z \end{bmatrix}

Visualization: Rotate 90 degrees around the x-axis

Code:

import vtk
import numpy as np
import math

def pointPolydataCreate(pointCloud):
    points = vtk.vtkPoints()
    cells = vtk.vtkCellArray()
    i = 0
    for point in pointCloud:
        points.InsertPoint(i, point[0], point[1], point[2])
        cells.InsertNextCell(1)
        cells.InsertCellPoint(i)
        i+=1
    PolyData = vtk.vtkPolyData()
    PolyData.SetPoints(points)
    PolyData.SetVerts(cells)

    mapper = vtk.vtkPolyDataMapper()
    mapper.SetInputData(PolyData)

    actor = vtk.vtkActor()
    actor.SetMapper(mapper)
    actor.GetProperty().SetColor(0.0, 0.1, 1.0)

    return actor

def visiualize(pointCloud, pointCloud2):
    colors = vtk.vtkNamedColors()
    actor1 = pointPolydataCreate(pointCloud)
    actor2 = pointPolydataCreate(pointCloud2)
    Axes = vtk.vtkAxesActor()

    # Visualization
    renderer1 = vtk.vtkRenderer()
    renderer1.SetViewport(0.0, 0.0, 0.5, 1)
    renderer1.AddActor(actor1)
    renderer1.AddActor(Axes)
    renderer1.SetBackground(colors.GetColor3d('skyblue'))

    renderer2 = vtk.vtkRenderer()
    renderer2.SetViewport(0.5, 0.0, 1.0, 1)
    renderer2.AddActor(actor2)
    renderer2.AddActor(Axes)
    renderer2.SetBackground(colors.GetColor3d('skyblue'))

    renderWindow = vtk.vtkRenderWindow()
    renderWindow.AddRenderer(renderer1)
    renderWindow.AddRenderer(renderer2)
    renderWindow.SetSize(1040, 880)
    renderWindow.Render()
    renderWindow.SetWindowName('PointCloud')

    renderWindowInteractor = vtk.vtkRenderWindowInteractor()
    renderWindowInteractor.SetRenderWindow(renderWindow)
    renderWindowInteractor.Initialize()
    renderWindowInteractor.Start()


pointCloud = np.loadtxt("C:/Users/A/Desktop/pointCloudData/model.txt") #Read point cloud data

angel_x = 90 # rotation angle
radian = angel_x * np.pi / 180 # Rotation radian
Rotation_Matrix_1 = [ # Three-dimensional rotation matrix around the x-axis
    [1, 0, 0],
    [0, math.cos(radian), -math.sin(radian)],
    [0, math.sin(radian), math.cos(radian)]]

Rotation_Matrix_1 = np.array(Rotation_Matrix_1)

p = np.dot(Rotation_Matrix_1, pointCloud.T) # Calculation
p = p.T
visiualize(pointCloud, p)

Rotate around the y-axis

Rotation matrix:

\begin{bmatrix} cos\beta & amp;0 & amp;sin\beta \ 0 & amp;1 & amp;0 \ -sin\beta & amp;0 & amp;cos\beta \end{bmatrix} \begin{bmatrix } x\ y \z \end{bmatrix}

Visualization: Rotate 180 degrees around the y-axis

Code:

angel_y = 180 # Rotation angle
radian = angel_y * np.pi / 180 # Rotation radian
Rotation_Matrix_2 = [ # Three-dimensional rotation matrix around the y-axis
    [math.cos(radian), 0, math.sin(radian)],
    [0, 1, 0],
    [-math.sin(radian), 0, math.cos(radian)]]

Rotation_Matrix_1 = np.array(Rotation_Matrix_1)

p = np.dot(Rotation_Matrix_1, pointCloud.T) # Calculation
p = p.T
visiualize(pointCloud, p)

Rotate around the z-axis

Rotation matrix:

\begin{bmatrix} cos\beta & amp;-sin\beta & amp;0 \ sin\beta & amp;cos\beta & amp; 0\\ \ 0 & amp;0 & amp; 1 \end{bmatrix} \ begin{bmatrix} x\ y \z \end{bmatrix}

Visualization: Rotate 90 degrees around the z-axis

Code:

angel_z = 90 # Rotation angle
radian = angel_z * np.pi / 180 # Rotation radian
Rotation_Matrix_1 = [ # Three-dimensional rotation matrix around the z-axis
    [math.cos(radian), -math.sin(radian), 0],
    [math.sin(radian), math.cos(radian), 0],
    [0, 0, 1]]

Rotation_Matrix_1 = np.array(Rotation_Matrix_1)

p = np.dot(Rotation_Matrix_1, pointCloud.T) # Calculation
p = p.T
visiualize(pointCloud, p)

The line rotates around the z-axis and then around the x-axis:

Rotation matrix: Which axis the line rotates around, the xyz matrix is calculated first and the rotation matrix of that axis is calculated first.

\begin{bmatrix} 1 & amp;0 & amp;0 \ 0 & amp;cos\beta & amp;-sin\beta \ 0 & amp;sin \beta & cos\beta \end{bmatrix} \begin{bmatrix } cos\beta & amp;-sin\beta & amp;0 \ sin\beta & amp;cos\beta & amp; 0\ 0 & amp;0 & amp; 1 \ \end{bmatrix} \begin{bmatrix} x\ y \ \\z \end{bmatrix}

Visualization: first rotate 90 degrees around the z-axis, then rotate 90 degrees around the x-axis

Code:

angel_z = 90 # Rotation angle
radian = angel_z * np.pi / 180 # Rotation radian
Rotation_Matrix_z = [ # Three-dimensional rotation matrix around the z-axis
    [math.cos(radian), -math.sin(radian), 0],
    [math.sin(radian), math.cos(radian), 0],
    [0, 0, 1]]

angel_x = 90 # rotation angle
radian = angel_x * np.pi / 180 # Rotation radian
Rotation_Matrix_x = [ # Three-dimensional rotation matrix around the x-axis
    [1, 0, 0],
    [0, math.cos(radian), -math.sin(radian)],
    [0, math.sin(radian), math.cos(radian)]]


Rotation_Matrix_z = np.array(Rotation_Matrix_z)
Rotation_Matrix_x = np.array(Rotation_Matrix_x)

p = np.dot(Rotation_Matrix_z, pointCloud.T) # Calculation
p = np.dot(Rotation_Matrix_x, p) # Calculation
p = p.T
visiualize(pointCloud, p)

2. Scaling matrix

Scaling matrix:

\begin{bmatrix} k_{x} & amp;0 & amp;0 \ 0 & amp; k_{y} & amp;0 \ 0 & amp;0 & amp;k_{z} \end{bmatrix}

Calculation process: The three k are the scaling coefficients corresponding to xyz

\begin{bmatrix} k_{x} & amp;0 & amp;0 \ 0 & amp; k_{y} & amp;0 \ 0 & amp;0 & amp;k_{z} \end{bmatrix} \begin{bmatrix} x\ y \ \\z \end{bmatrix}= \begin{bmatrix} k_{x}x\k_{y} y \k_{z }z \end{bmatrix}

The x coordinate becomes 1.5 times the original, y becomes 0.7 times, and z remains unchanged

\begin{bmatrix} 1.5 & amp;0 & amp;0 \ 0 & amp; 0.7 & amp;0 \ 0 & amp;0 & amp;1 \end {bmatrix} \begin{bmatrix} x\ y \z \end{bmatrix}= < img alt="\begin{bmatrix} 1.5x\0.7 y \1z \end{bmatrix}" class="mathcode" src="//i2.wp.com /latex.csdn.net/eq?\begin{bmatrix} 1.5x\0.7 y \1z \end{bmatrix}">

Visualization:

3. Mirror matrix

3D mirror matrix:

\begin{bmatrix} 1-2n_x{}^{2} & amp; -2n_x{}n_{y} & amp;-2n_x{}n_{z} \ -2n_x{ }n_{y} & amp;1-2n_y{}^{2} & amp;-2n_y{}n_{z} \ -2n_x{}n_{z} & amp;-2n_y{}n_{z } & amp; 1-2n_z{}^{2} \end{bmatrix}

n=\begin{bmatrix}n_{x}&n_{y}&n_{z}\end{bmatrix}

Vector n is the unit vector perpendicular to the mirror plane

Mirror image of three-dimensional point cloud on xz plane:

①First, determine a unit vector perpendicular to the xz plane n=[0, 1, 0]

②Bring this unit vector into the above 3D mirror matrix

Visualization:

Code:

import vtk
import numpy as np
import math

def pointPolydataCreate(pointCloud):
    points = vtk.vtkPoints()
    cells = vtk.vtkCellArray()
    i = 0
    for point in pointCloud:
        points.InsertPoint(i, point[0], point[1], point[2])
        cells.InsertNextCell(1)
        cells.InsertCellPoint(i)
        i+=1
    PolyData = vtk.vtkPolyData()
    PolyData.SetPoints(points)
    PolyData.SetVerts(cells)

    mapper = vtk.vtkPolyDataMapper()
    mapper.SetInputData(PolyData)

    actor = vtk.vtkActor()
    actor.SetMapper(mapper)
    actor.GetProperty().SetColor(0.0, 0.1, 1.0)

    return actor

def visiualize(pointCloud, pointCloud2):
    colors = vtk.vtkNamedColors()
    actor1 = pointPolydataCreate(pointCloud)
    actor2 = pointPolydataCreate(pointCloud2)
    Axes = vtk.vtkAxesActor()

    # Visualization
    renderer1 = vtk.vtkRenderer()
    renderer1.SetViewport(0.0, 0.0, 0.5, 1)
    renderer1.AddActor(actor1)
    renderer1.AddActor(Axes)
    renderer1.SetBackground(colors.GetColor3d('skyblue'))

    renderer2 = vtk.vtkRenderer()
    renderer2.SetViewport(0.5, 0.0, 1.0, 1)
    renderer2.AddActor(actor1)
    renderer2.AddActor(actor2)
    renderer2.AddActor(Axes)
    renderer2.SetBackground(colors.GetColor3d('skyblue'))

    renderWindow = vtk.vtkRenderWindow()
    renderWindow.AddRenderer(renderer1)
    renderWindow.AddRenderer(renderer2)
    renderWindow.SetSize(1040, 880)
    renderWindow.Render()
    renderWindow.SetWindowName('PointCloud')

    renderWindowInteractor = vtk.vtkRenderWindowInteractor()
    renderWindowInteractor.SetRenderWindow(renderWindow)
    renderWindowInteractor.Initialize()
    renderWindowInteractor.Start()


pointCloud = np.loadtxt("C:/Users/A/Desktop/pointCloudData/model.txt") #Read point cloud data

nx = 0
n = 0
nz = 1
n = [nx, ny, nz] # Unit vector perpendicular to the xy plane
# Mirror matrix
Mirror_Matrix = [
    [1-2*nx**2, -2*nx*ny, -2*nx*nz],
    [-2*nx*ny, 1-2*ny**2, -2*ny*nz],
    [-2*nx*nz, -2*ny*nz, 1-2*nz**2]]

Mirror_Matrix = np.array(Mirror_Matrix)

p = np.dot(Mirror_Matrix, pointCloud.T) # Calculation
p = p.T
visiualize(pointCloud, p)

4. Miscut matrix

Off-cut along the xy plane (z remains unchanged)

matrix calculation process

H_{xy}(s, t)=\begin{bmatrix} 1 & amp;0 & amp;s \ 0 & amp;1 & amp;t \ 0 & amp;0 & amp;1 \end{bmatrix} \begin{bmatrix} 1 & amp;0 & amp;s \ 0 & amp;1 & amp;t \ 0 & amp;0 & amp;1 \end{bmatrix} \begin{bmatrix} x\ y \\ \ z \end{bmatrix}=\begin{bmatrix} x + sz\y + tz \ z \end{bmatrix}

Off-cut along the xz plane (y remains unchanged)

matrix calculation process

H_{xz}(s, t)=\begin{bmatrix} 1 & amp;0 & amp;s \ 0 & amp;1 & amp;0 \ 0 & amp;t & amp;1 \end{bmatrix} \begin{bmatrix} 1 & amp;0 & amp;s \ 0 & amp;1 & amp;0 \ 0 & amp;t & amp;1 \end{bmatrix} \begin{bmatrix} x\ y \\ \ z \end{bmatrix}=\begin{bmatrix} x + sz\y \ z + ty \end{bmatrix}

Staggered cutting along the yz plane (x remains unchanged)

matrix calculation process

H_{yz}(s, t)=\begin{bmatrix} 1 & amp;0 & amp;0 \ s & amp;1 & amp;0 \ t & amp;0 & amp;1 \end{bmatrix} \begin{bmatrix} 1 & amp;0 & amp;0 \ s & amp;1 & amp;0 \ t & amp;0 & amp;1 \end{bmatrix} \begin{bmatrix} x\ y \\ \ z \end{bmatrix}=\begin{bmatrix} x\y + sx \ z + tx \end{bmatrix}

Visualization: staggered cutting along the yz plane

Code:

pointCloud = np.loadtxt("C:/Users/A/Desktop/pointCloudData/model.txt") #Read point cloud data

s = 0.3
t=0.3
# Stagger the matrix along the yz plane
Shear_Matrix = [
    [1, 0, 0],
    [s, 1, 0],
    [t, 0, 1]]

Shear_Matrix = np.array(Shear_Matrix)

p = np.dot(Shear_Matrix, pointCloud.T) # Calculation
p = p.T
visiualize(pointCloud, p)

5. Orthographic projection

Orthogonal projection matrix (projected to any plane in three-dimensional space):

\begin{bmatrix} 1-n_{x}^{2} & amp;-n_{x}n_{y} & amp;-n_{x}n_{z} \ -n_{x}n_{y} & amp;1-n_{y}^{2} & amp;-n_{y}n_{z} \ -n_{x}n_{z} & amp; -n_{y}n_{z} & amp; 1-n_{z}^{2} \end{bmatrix}

n=\begin{bmatrix}n_{x}&n_{y}&n_{z}\end{bmatrix}

Vector n is the unit vector normal to the projection plane

Visualization: orthogonal projection of point cloud on xy plane

6. Translation matrix

The translation matrix requires the use of a homogeneous matrix (4*4 matrix). The following is a translation matrix

The rightmost column is the displacement of xyz

\begin{bmatrix} 1 & amp;0 & amp;0 & amp; \Delta x \ 0 & amp;1 & amp;0 & amp;\Delta y \ \ 0 & amp;0 & amp;1 & amp; \Delta z\ 0 & amp;0 & amp; 0 & amp; 1 \end{bmatrix}

Calculation process:

\begin{bmatrix} 1 & amp;0 & amp;0 & amp; \Delta x \ 0 & amp;1 & amp;0 & amp;\Delta y \ \ 0 & amp;0 & amp;1 & amp; \Delta z\ 0 & amp;0 & amp; 0 & amp; 1 \end{bmatrix} \begin{bmatrix} x\y \z \\ \1 \end{bmatrix}=\begin{bmatrix} x + \Delta x\ y + \Delta y \ z + \Delta z \ 1 \end{ bmatrix}

Linear transformation + translation:

The added translation has no effect on the original linear transformation. You can combine the transformation matrix and translation introduced earlier.

For example: miscut + translation along the xy plane

\begin{bmatrix} 1 & amp;0 & amp;s & amp;\Delta x \ 0 & amp;1 & amp;t & amp;\Delta y \ \ 0 & amp;0 & amp;1 & amp;\Delta z \ 0 & amp; 0 & amp; 0 & amp; 1 \end{bmatrix}

The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge. Python entry skill treeHomepageOverview 386,908 people are learning the system