旋转、缩放和平移二维坐标?

5 投票
1 回答
19848 浏览
提问于 2025-04-18 05:45

我现在正在做一个项目,想用Python图像库创建一个希尔伯特曲线。我写了一个函数,可以在每次迭代中生成曲线的新坐标,并把这些坐标放进不同的列表里。接下来,我希望能对这些坐标进行移动、旋转和缩放。我在这方面完全没有头绪,不知道该怎么做。如果有人能给我一些建议或者方法就太好了。我还在继续完善代码。

#! usr/bin/python
import Image, ImageDraw
import math

# Set the starting shape
img = Image.new('RGB', (1000, 1000))
draw = ImageDraw.Draw(img)

curve_X = [0, 0, 1, 1]
curve_Y = [0, 1, 1, 0]

combinedCurve = zip(curve_X, curve_Y)
draw.line((combinedCurve), fill=(220, 255, 250))
iterations = 5

# Start the loop
for i in range(0, iterations):
    # Make 4 copies of the curve

    copy1_X = list(curve_X)
    copy1_Y = list(curve_Y)

    copy2_X = list(curve_X)
    copy2_Y = list(curve_Y)

    copy3_X = list(curve_X)
    copy3_Y = list(curve_Y)

    copy4_X = list(curve_X)
    copy4_Y = list(curve_Y)

    # For copy 1, rotate it by 90 degree clockwise
    # Then move it to the bottom left
    # For copy 2, move it to the top left
    # For copy 3, move it to the top right
    # For copy 4, rotate it by 90 degrees anticlockwise
    # Then move it to the bottom right

    # Finally, combine all the copies into a big list
    combinedCurve_X = copy1_X + copy2_X + copy3_X + copy4_X
    combinedCurve_Y = copy1_Y + copy2_Y + copy3_Y + copy4_Y

# Make the initial curve equal to the combined one
curve_X = combinedCurve_X[:]
curve_Y = combinedCurve_Y[:]

# Repeat the loop

# Scale it to fit the canvas
curve_X = [x * xSize for x in curve_X]
curve_Y = [y * ySize for y in curve_Y]
# Draw it with something that connects the dots
curveCoordinates = zip(curve_X, curve_Y)
draw.line((curveCoordinates), fill=(255, 255, 255))

img2=img.rotate(180)
img2.show()

1 个回答

8

这里有一个适用于矩阵的解决方案(对于这种计算来说是合理的,最后,二维坐标可以看作是只有一列的矩阵!)

缩放其实很简单,只需要把矩阵中的每个元素都乘以缩放因子:

scaled = copy.deepcopy(original)
for i in range(len(scaled[0])):
    scaled[0][i]=scaled[0][i]*scaleFactor
    scaled[1][i]=scaled[1][i]*scaleFactor

移动也很简单,只需要在矩阵的每个元素上加上偏移量,这里有一个使用矩阵乘法的方法:

import numpy as np
# Matrix multiplication
def mult(matrix1,matrix2):
    # Matrix multiplication
    if len(matrix1[0]) != len(matrix2):
        # Check matrix dimensions
        print 'Matrices must be m*n and n*p to multiply!'
    else:
        # Multiply if correct dimensions
        new_matrix = np.zeros(len(matrix1),len(matrix2[0]))
        for i in range(len(matrix1)):
            for j in range(len(matrix2[0])):
                for k in range(len(matrix2)):
                    new_matrix[i][j] += matrix1[i][k]*matrix2[k][j]
        return new_matrix

然后创建你的平移矩阵

import numpy as np
TranMatrix = np.zeros((3,3))
TranMatrix[0][0]=1
TranMatrix[0][2]=Tx
TranMatrix[1][1]=1
TranMatrix[1][2]=Ty
TranMatrix[2][2]=1

translated=mult(TranMatrix, original)

最后,旋转就稍微复杂一点(你知道你的旋转角度吗?):

import numpy as np
RotMatrix = np.zeros((3,3))
RotMatrix[0][0]=cos(Theta)
RotMatrix[0][1]=-1*sin(Theta)
RotMatrix[1][0]=sin(Theta)
RotMatrix[1][1]=cos(Theta)
RotMatrix[2][2]=1

rotated=mult(RotMatrix, original)

关于我所做的事情,进一步阅读:

所以基本上,如果你把这些操作放进你的代码里,乘以旋转/平移矩阵,你的代码应该能正常工作

编辑

我刚发现这个Python库,似乎提供了各种类型的变换: http://toblerity.org/shapely/index.html

撰写回答