二维几何变换

个人博客

  二维几何变换有如下几种:平移变换、比例变换、对称变换、旋转变换、错切变换

  本文会给出:平移变换、旋转变换、比例变换、相对任意参考点的二维变换的算法和代码实现

平移变换

  平移是指将物体沿直线路径从一个坐标位置 ( x 1 , y 1 ) (x1,y1) (x1,y1)移动到另一个坐标位置 ( x 2 , y 2 ) (x2,y2) (x2,y2)的变换。设 t x t_x tx为沿X轴的平移量, t y t_y ty为沿Y轴的平移量。

平移变换的二维表示为:

{ x 2 = x 1 + t x y 2 = y 1 + t y \begin{cases}x_2=x_1+t_x\\ y_2=y_1+t_y\end{cases} {x2=x1+txy2=y1+ty

平移变换的齐次表示为:

[ x 2 y 2 1 ] = [ x 1 y 1 1 ] [ 1 0 0 0 1 0 t x t y 1 ] \begin{gathered} \begin{bmatrix} x_2 & y_2 & 1\end{bmatrix}= \begin{bmatrix} x_1 & y_1 & 1\end{bmatrix} \begin{bmatrix} 1 & 0 & 0\\0 & 1 & 0\\t_x & t_y & 1 \end{bmatrix} \end{gathered} [x2y21]=[x1y11]10tx01ty001

代码实现
def translate(p_list, dx, dy):
	"""
	:param p_list:(list of lsit of int:[[x0,x1], [x1,y1], ...]) point set of p
	:param dx: (int) delta x
	:param dy: (int) delta y
	:result: (list of list of int:[[x0, y0], [x1, y1], ...])
	"""
	n = len(p_list)
	result = []
	for i in range(0, n):
		x2 = p_list[i][0] + dx
		y2 = p_list[i][1] + dy
		result.append([x2, y2])
	return result

旋转变换

  二维旋转是将物体沿着xy平面内的圆弧路径重定位。旋转角 θ \theta θ取值逆时针为正,顺时针为负

旋转变换的二维表示

  如图所示:

在这里插入图片描述
显见有如下关系:
{ x 2 = r ∗ c o s ( α + θ ) = r ∗ c o s α ∗ c o s θ − r ∗ s i n α ∗ s i n θ y 2 = r ∗ s i n ( α + θ ) = r ∗ c o s α ∗ s i n θ + r ∗ s i n α ∗ c o s θ \begin{cases} x_2=r*cos(\alpha+\theta)=r*cos\alpha*cos\theta-r*sin\alpha*sin\theta\\ y_2=r*sin(\alpha+\theta)=r*cos\alpha*sin\theta+r*sin\alpha*cos\theta \end{cases} {x2=rcos(α+θ)=rcosαcosθrsinαsinθy2=rsin(α+θ)=rcosαsinθ+rsinαcosθ

又因为有 x 1 = r ∗ c o s α , y 1 = r ∗ s i n α x_1=r*cos\alpha,y_1=r*sin\alpha x1=rcosα,y1=rsinα,所以有

{ x 2 = r ∗ c o s ( α + θ ) = x 1 ∗ c o s θ − y 1 ∗ s i n θ y 2 = r ∗ s i n ( α + θ ) = x 1 ∗ s i n θ + y 1 ∗ c o s θ \begin{cases} x_2=r*cos(\alpha+\theta)=x_1*cos\theta-y_1*sin\theta\\ y_2=r*sin(\alpha+\theta)=x_1*sin\theta+y_1*cos\theta \end{cases} {x2=rcos(α+θ)=x1cosθy1sinθy2=rsin(α+θ)=x1sinθ+y1cosθ

旋转变换的齐次表示

[ x 2 y 2 1 ] = [ x 1 y 1 1 ] [ c o s θ s i n θ 0 − s i n θ c o s θ 0 0 0 1 ] \begin{gathered} \begin{bmatrix} x_2 & y_2 & 1\end{bmatrix}= \begin{bmatrix} x_1 & y_1 & 1\end{bmatrix} \begin{bmatrix} cos\theta & sin\theta & 0\\-sin\theta & cos\theta & 0\\0 & 0 & 1 \end{bmatrix} \end{gathered} [x2y21]=[x1y11]cosθsinθ0sinθcosθ0001

代码实现
def rotate(p_list, x, y, r):
	"""
	:param p_list:(list of lsit of int:[[x0,x1], [x1,y1], ...]) point set of p
	:param x: (int) coordinate x
	:param y: (int) coordinate y
	:param r: (float) degree
	:result: (list of list of int:[[x0, y0], [x1, y1], ...])
	"""
	n = len(p_list)
	sin = math.sin(math.radians(r))
	cos = math.cos(math.radians(r))
	result = []
	for x1, y1 in p_list:
		x2 = int(x1 * cos - y1 * sin)
		y2 = int(x1 * sin + y1 * cos)
		result.append([x2, y2])
	return result

比例变换

  二维比例变换改变物体的尺寸。通过顶点值 ( x 1 , y 1 ) (x_1,y_1) (x1,y1)乘以比例系数 S x S_x Sx S y S_y Sy得到变换的坐标 ( x 2 , y 2 ) (x_2,y_2) (x2,y2);

  比例系数 S x S_x Sx为在x方向对物体的缩放, S y S_y Sy在y方向的缩放。比例系数可以赋予任何正数,小于1缩小,大于1则放大;若 S x = S y S_x=S_y Sx=Sy为等比例变换,若 S x ≠ S y S_x\neq S_y Sx=Sy则是非均匀比例变换。

比例变换的二维表示为:

{ x 2 = x 1 ∗ S x y 2 = y 1 ∗ S y \begin{cases}x_2=x_1*S_x\\ y_2=y_1*S_y\end{cases} {x2=x1Sxy2=y1Sy

比例变换的齐次表示为:

[ x 2 y 2 1 ] = [ x 1 y 1 1 ] [ S x 0 0 0 S y 0 0 0 1 ] \begin{gathered} \begin{bmatrix} x_2 & y_2 & 1\end{bmatrix}= \begin{bmatrix} x_1 & y_1 & 1\end{bmatrix} \begin{bmatrix} S_x & 0 & 0\\0 & S_y & 0\\0 & 0 & 1 \end{bmatrix} \end{gathered} [x2y21]=[x1y11]Sx000Sy0001

代码实现
def scale(p_list, x, y, s):
	"""
	:param p_list:(list of lsit of int:[[x0,x1], [x1,y1], ...]) point set of p
	:param x: (int) coordinate x
	:param y: (int) coordinate y
	:param s: (float) times
	:result: (list of list of int:[[x0, y0], [x1, y1], ...])
	"""
	n = len(p_list)
	result = []
	for i in range(0, n):
		x2 = int(p_list[i][0] + s)
		y2 = int(p_list[i][1] + s)
		result.append([x2, y2])
	return result

相对任意参考点的二维变换

  如果要对某参考点(x,y)作二维几何变换,比如比例变换,旋转变换等。变换过程如下:

  • 将参考点移至坐标原点
  • 对原点进行二维几何变换
  • 进行反平移,将参考点移回原来的位置
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值