旋转、缩放和平移二维坐标? [英] Rotate, scale and translate 2D coordinates?
问题描述
我正在处理一个项目,我正在尝试使用 Python 成像库创建 Hilbert 曲线.我创建了一个函数,它将通过每次迭代为曲线生成新坐标,并将它们放入各种列表中,然后我希望能够移动、旋转和缩放.我想知道是否有人可以给我一些提示或方法来做到这一点,因为我完全一无所知.仍在处理大量代码.
I'm am working on a project at the moment where I am trying to create a Hilbert curve using the Python Imaging Library. I have created a function which will generate new coordinates for the curve through each iteration and place them into various lists which then I want to be able to move, rotate and scale. I was wondering if anyone could give me some tips or a way to do this as I am completely clueless. Still working on the a lot of the code.
#! 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()
推荐答案
这里有一个处理矩阵的解决方案(这对于这种类型的计算是有意义的,最终,2D 坐标是具有 1 列的矩阵!),
Here is a solution working on matrices (which makes sense for this type of calculations, and in the end, 2D coordinates are matrices with 1 column!),
缩放非常简单,只需要将矩阵的每个元素乘以缩放因子:
Scaling is pretty easy, just have to multiply each element of the matrix by the scale factor:
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
移动很容易,你要做的就是给矩阵的每个元素加上偏移量,这里有一个使用矩阵乘法的方法:
Moving is pretty easy to, all you have to do is to add the offset to each element of the matrix, here's a method using matrix multiplication:
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)
最后,旋转有点棘手(你知道你的旋转角度吗?):
And finally, rotation is a tiny bit trickier (do you know your angle of rotation?):
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)
进一步阅读我所做的事情:
Some further reading on what I've done:
- http://en.wikipedia.org/wiki/Transformation_matrix#Affine_transformations
- http://en.wikipedia.org/wiki/Homogeneous_coordinates
- http://www.essentialmath.com/tutorial.htm(关于所有代数变换)
- http://en.wikipedia.org/wiki/Transformation_matrix#Affine_transformations
- http://en.wikipedia.org/wiki/Homogeneous_coordinates
- http://www.essentialmath.com/tutorial.htm (concerning all the algebra transformations)
所以基本上,如果将这些操作插入代码中,将向量乘以旋转/平移矩阵,它应该可以工作
So basically, it should work if you insert those operations inside your code, multiplying your vectors by the rotation / translation matrices
编辑
我刚刚发现这个 Python 库似乎提供了所有类型的转换:http://toblerity.org/shapely/index.html
I just found this Python library that seems to provide all type of transformations: http://toblerity.org/shapely/index.html
这篇关于旋转、缩放和平移二维坐标?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!