2D坐标系下的点的转换矩阵(平移、缩放、旋转、错切)

news/2024/5/20 17:38:04/文章来源:https://blog.csdn.net/wsp_1138886114/article/details/131888684

文章目录

        • 1. 平移 (Translation)
        • 2. 缩放 (Scaling)
        • 3. 旋转 (Rotation)
        • 4. 错切 (Shearing)
        • 5. 镜像 (Reflection)

1. 平移 (Translation)

在2D空间中,我们经常需要将一个点平移到另一个位置。假设空间中的一点 P ( x , y ) P(x,y) P(x,y);将其向 x , y x, y x,y方向分别平移 t x t_x tx t y t_y ty, 假设平移后点的坐标为 ( x ′ , y ′ ) (x',y') (x,y),则上述点的平移操作可以归纳为如下公式:
x ′ = x + t x y ′ = x + t y \begin{alignat}{2} &x'=x + t_x\\ &y'=x + t_y \end{alignat} x=x+txy=x+ty
使用齐次矩阵表示如下:
[ x ′ y ′ 1 ] = [ 1 b t x 0 1 t y 0 0 1 ] [ x y 1 ] \begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = \begin{bmatrix} 1 & b & t_x \\ 0 & 1 & t_y \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} xy1 = 100b10txty1 xy1

import numpy as npdef translation():"""原始数组a 三个点(1,1) (4,4) (7,7)构建齐次矩阵 P构建变换矩阵 T"""a = np.array([[1, 1],[4, 4],[7, 7]])P = np.array([a[:, 0],a[:, 1],np.ones(len(a))])T = np.array([[1, 0, 2],[0, 1, 2],[0, 0, 1]])return np.dot(T, P)print(translation())"""
[[3. 6. 9.][3. 6. 9.][1. 1. 1.]]
"""

动画效果演示

import matplotlib
import matplotlib.pyplot as plt
import numpy as npX, Y = np.mgrid[0:1:5j, 0:1:5j]
x, y = X.ravel(), Y.ravel()def trans_translate(x, y, tx, ty):T = [[1, 0, tx],[0, 1, ty],[0, 0, 1]]T = np.array(T)P = np.array([x, y, [1] * x.size])return np.dot(T, P)fig, ax = plt.subplots(1, 4)
T_ = [[0, 0], [2.3, 0], [0, 1.7], [2, 2]]
for i in range(4):tx, ty = T_[i]x_, y_, _ = trans_translate(x, y, tx, ty)ax[i].scatter(x_, y_)ax[i].set_title(r'$t_x={0:.2f}$ , $t_y={1:.2f}$'.format(tx, ty))ax[i].set_xlim([-0.5, 4])ax[i].set_ylim([-0.5, 4])ax[i].grid(alpha=0.5)ax[i].axhline(y=0, color='k')ax[i].axvline(x=0, color='k')
plt.show()

请添加图片描述

2. 缩放 (Scaling)

在2D空间中,点 ( x , y ) (x,y) (x,y)相对于另一点 ( p x , p y ) (p_x,p_y) (px,py)进行缩放操作,我们不妨缩放因子在 x , y x,y xy方向分别为: s x , s y s_x, s_y sx,sy, 则上述的缩放操作可以归纳为如下公式:
x ′ = s x ( x − p x ) + p x = s x x + p x ( 1 − s x ) y ′ = s y ( y − p y ) + p y = s y y + p y ( 1 − s y ) \begin{alignat}{2} &x'=s_x(x-p_x) + p_x &=s_xx + p_x(1-s_x)\\ &y'=s_y(y-p_y) + p_y &=s_yy + p_y(1-s_y) \end{alignat} x=sx(xpx)+pxy=sy(ypy)+py=sxx+px(1sx)=syy+py(1sy)
使用齐次矩阵表示如下:
[ x ′ y ′ 1 ] = [ s x 0 p x ( 1 − s x ) 0 s y p y ( 1 − s y ) 0 0 1 ] [ x y 1 ] \begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = \begin{bmatrix} s_x& 0 & p_x(1-s_x) \\ 0 & s_y& p_y(1-s_y)\\ 0 & 0& 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} xy1 = sx000sy0px(1sx)py(1sy)1 xy1

def trans_scale(x, y, px, py, sx, sy):T = [[sx, 0 , px*(1 - sx)],[0 , sy, py*(1 - sy)],[0 , 0 , 1          ]]T = np.array(T)P = np.array([x, y, [1]*x.size])return np.dot(T, P)fig, ax = plt.subplots(1, 4)
S_ = [[1, 1], [1.8, 1], [1, 1.7], [2, 2]]
P_ = [[0, 0], [0, 0], [0.45, 0.45], [1.1, 1.1]]
for i in range(4):sx, sy = S_[i]; px, py = P_[i]x_, y_, _ = trans_scale(x, y, px, py, sx, sy)ax[i].scatter(x_, y_)ax[i].scatter(px, py)ax[i].set_title(r'$p_x={0:.2f}$ , $p_y={1:.2f}$'.format(px, py) + '\n'r'$s_x={0:.2f}$ , $s_y={1:.2f}$'.format(sx, sy))ax[i].set_xlim([-2, 2])ax[i].set_ylim([-2, 2])ax[i].grid(alpha=0.5)ax[i].axhline(y=0, color='k')ax[i].axvline(x=0, color='k')plt.show()

请添加图片描述

3. 旋转 (Rotation)

在2D空间中,对点 ( x , y ) (x,y) (x,y)相对于另一点 ( p x , p y ) (p_x,p_y) (px,py)进行旋转操作,一般来说逆时针为正,顺时针为负,假设旋转角度为 β \beta β, 则上述点 x , y x,y x,y 相对于点 p x , p y p_x,p_y px,py的旋转角度 β \beta β 的操作使用齐次矩阵表示如下:
[ x ′ y ′ 1 ] = [ cos ⁡ β − sin ⁡ β p x ( 1 − cos ⁡ β ) + p y sin ⁡ β sin ⁡ β cos ⁡ β p y ( 1 − cos ⁡ β ) + p x sin ⁡ β 0 0 1 ] [ x y 1 ] \begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = \begin{bmatrix} \cos \beta& -\sin \beta & p_x(1-\cos \beta) + p_y \sin \beta \\ \sin \beta & \cos \beta& p_y(1-\cos \beta) + p_x \sin \beta \\ 0 & 0& 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} xy1 = cosβsinβ0sinβcosβ0px(1cosβ)+pysinβpy(1cosβ)+pxsinβ1 xy1

def trans_rotate(x, y, px, py, beta):beta = np.deg2rad(beta)T = [[np.cos(beta), -np.sin(beta), px*(1 - np.cos(beta)) + py*np.sin(beta)],[np.sin(beta),  np.cos(beta), py*(1 - np.cos(beta)) - px*np.sin(beta)],[0           ,  0           , 1                                      ]]T = np.array(T)P = np.array([x, y, [1]*x.size])return np.dot(T, P)fig, ax = plt.subplots(1, 4)R_ = [0, 225, 40, -10]
P_ = [[0, 0], [0, 0], [0.5, -0.5], [1.1, 1.1]]for i in range(4):beta = R_[i]; px, py = P_[i]x_, y_, _ = trans_rotate(x, y, px, py, beta)ax[i].scatter(x_, y_)ax[i].scatter(px, py)ax[i].set_title(r'$\beta={0}°$ , $p_x={1:.2f}$ , $p_y={2:.2f}$'.format(beta, px, py))ax[i].set_xlim([-2, 2])ax[i].set_ylim([-2, 2])ax[i].grid(alpha=0.5)ax[i].axhline(y=0, color='k')ax[i].axvline(x=0, color='k')plt.show()

请添加图片描述

4. 错切 (Shearing)

在2D空间中,对点 ( x , y ) (x,y) (x,y) 相对于另一点 ( p x , p y ) (p_x,p_y) (px,py)进行错切操作,错切一般用于弹性物体的变形处理。 假设沿x 方向与y方向错切参数分别为 λ x , λ y \lambda _x,\lambda _y λxλy, 则的错切操作可以归纳使用齐次矩阵表示如下:

[ x ′ y ′ 1 ] = [ 1 λ x − λ x p x λ y 1 − λ y p y 0 0 1 ] [ x y 1 ] \begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = \begin{bmatrix} 1& \lambda _x & -\lambda _x p_x \\ \lambda _y & 1& -\lambda _y p_y \\ 0 & 0& 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} xy1 = 1λy0λx10λxpxλypy1 xy1

import matplotlib.pyplot as plt
import numpy as npX, Y = np.mgrid[0:1:5j, 0:1:5j]
x, y = X.ravel(), Y.ravel()def trans_shear(x, y, px, py, lambdax, lambday):T = [[1      , lambdax, -lambdax*px],[lambday, 1      , -lambday*py],[0      , 0      ,  1         ]]T = np.array(T)P = np.array([x, y, [1]*x.size])return np.dot(T, P)fig, ax = plt.subplots(1, 4)L_ = [[0, 0], [2, 0], [0, -2], [-2, -2]]
P_ = [[0, 0], [0, 0], [0, 1.5], [1.1, 1.1]]for i in range(4):lambdax, lambday = L_[i]; px, py = P_[i]x_, y_, _ = trans_shear(x, y, px, py, lambdax, lambday)ax[i].scatter(x_, y_)ax[i].scatter(px, py)ax[i].set_title(r'$p_x={0:.2f}$ , $p_y={1:.2f}$'.format(px, py) + '\n'r'$\lambda_x={0:.2f}$ , $\lambda_y={1:.2f}$'.format(lambdax, lambday))ax[i].set_xlim([-3, 3])ax[i].set_ylim([-3, 3])ax[i].grid(alpha=0.5)ax[i].axhline(y=0, color='k')ax[i].axvline(x=0, color='k')plt.show()

在这里插入图片描述

5. 镜像 (Reflection)

对于镜像,对称轴的法向量 v ( v x , v y ) v(v_x,v_y) v(vx,vy), 镜像矩阵 T m T_{m} Tm表示为:
[ 1 − 2 x v 2 − 2 x v y v 0 − 2 x v y v 1 − 2 y v 2 0 0 0 1 ] \left[ \begin{array}{ccc} 1-2 x_{v}{ }^{2} & -2 x_{v} y_{v} & 0 \\ -2 x_{v} y_{v} & 1-2 y_{v}{ }^{2} & 0 \\ 0 & 0 & 1 \end{array} \right] 12xv22xvyv02xvyv12yv20001
另外就是需要一个表示对称轴位置的点(对称轴2点中任意一点),表示为 M ( x m , y m ) M\left(x_{\mathrm{m}}, y_{m}\right) M(xm,ym),变换矩阵 H = T t ∗ T m ∗ T t − 1 H = T_{t}*T_{m}*T_{t}^{-1} H=TtTmTt1,即:
H = [ 1 0 0 0 1 0 x m y m 1 ] [ 1 − 2 x v 2 − 2 x v y v 0 − 2 x v y v 1 − 2 y v 2 0 0 0 1 ] [ 1 0 0 0 1 0 − x m − y m 1 ] H = \left[ \begin{array}{ccc} 1 & 0 & 0 \\ 0 & 1 & 0 \\ x_{\mathrm{m}} & y_{m} & 1 \end{array} \right] \left[ \begin{array}{ccc} 1-2 x_{v}{ }^{2} & -2 x_{v} y_{v} & 0 \\ -2 x_{v} y_{v} & 1-2 y_{v}{ }^{2} & 0 \\ 0 & 0 & 1 \end{array} \right] \left[ \begin{array}{ccc} 1 & 0 & 0 \\ 0 & 1 & 0 \\ -x_{\mathrm{m}} & -y_{m} & 1 \end{array} \right] H= 10xm01ym001 12xv22xvyv02xvyv12yv20001 10xm01ym001
镜像后的坐标即为 T o ∗ T t ∗ T m ∗ T t − 1 T_{o}*T_{t}*T_{m}*T_{t}^{-1} ToTtTmTt1

沿 X 轴 镜像的镜像矩阵:
[ 1 0 0 0 − 1 0 1 0 1 ] \left[ \begin{array}{ccc} 1 & 0 & 0 \\ 0 & -1 & 0 \\ 1 & 0 & 1 \end{array} \right] 101010001
沿 Y 轴 镜像的镜像矩阵:
[ − 1 0 0 0 1 0 0 1 1 ] \left[ \begin{array}{ccc} -1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 1 & 1 \end{array} \right] 100011001

import numpy as npa = np.array([[1, 2],[2, 2],[3, 5],[4, 6]])
a = np.array([a[:,0], a[:,1], np.ones(len(a))])
print("\n",a)
print("--------------------------------")T_x = np.array( [[ 1,  0,  0],[ 0, -1,  0],[ 1,  0,  1]])
print("\n",np.dot(T_x, a))
print("=================================")
T_y = np.array( [[-1,  0,  0],[ 0,  1,  0],[ 0,  1,  1]])
print("\n",np.dot(T_y, a))

参考:
https://zhuanlan.zhihu.com/p/387578291
https://zhuanlan.zhihu.com/p/187411029
https://blog.csdn.net/Akiyama_sou/article/details/122144415

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_146845.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数学建模】时间序列分析

文章目录 1. 条件2. 模型分类3. SPSS处理时间序列 1. 条件 1.使用于具有时间、数值两种要素 2.数据具有周期性可以使用时间序列分解 2. 模型分类 叠加模型【YTSCI】 序列的季节波动变化越来越大,反映变动之间的关系发生变化乘积序列【YTSC*I】 时间序列波动保持恒…

【致敬未来的攻城狮计划】第3期 作业汇总贴 + 获奖公布(文末荐书)

目录 一、写在前面 二、种子学员介绍 三、作业贴汇总 四、小小总结 五、获奖公布 六、学员有话说 七、特别致谢 八、友情荐书 一、写在前面 时间过得真快,距离 【致敬未来的攻城狮计划】第3期 的发起,已经过去有些时间了,让我们一起…

opencv对相机进行畸变矫正,及矫正前后的坐标对应

文章目录 1.背景2.需求分析3.解决方案3.1.镜头畸变矫正3.2.知道矫正后的画面坐标(x,y),求其在原画面的坐标(x,y)3.2.知道原画面坐标(x1,y1),求其在…

jQuery的DOM操作之笔记总结

jQuery的DOM操作之笔记总结 首先我们来介绍一下什么是DOM 简述: 1.DOM全称Document Object Model(文档对象模型)。 2.每个文档都是一棵DOM结构的树,文档里的很多元素,就像树上的很多节点,或是分叉的树枝…

集成学习——Boosting算法:Adaboost、GBDT、XGBOOST和lightGBM的简要原理和区别

1、Boosting算法 Boosting算法是通过串联的方式,将一组弱学习器提升为强学习器算法。它的工作机制如下: (1)用初始训练集训练出一个基学习器; (2)依据基学习器的表现对训练样本分布进行调整&…

WPF实现DiagramChart

1、文件架构 2、FlowChartStencils.xaml <ResourceDictionary xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:s"clr-namespace:DiagramDesigner"xmlns:c&…

算法通关村第一关-链表白银挑战笔记|公共子节点

两个链表公共子节点问题 提示&#xff1a;大家都在做什么&#xff1f; 不做什么。就是等夏天结束 文章目录 两个链表公共子节点问题前言题目&#xff1a;提供四种解决方法的思路&#xff1a;拿到题目要怎么思考&#xff1a;审题哈希表或集合实现使用栈来实现拼接字符串实现 (组…

短视频矩阵源码开发搭建分享--多账号授权管理

目录 文章目录 前言 一、矩阵号系统是什么&#xff1f; 二、使用步骤 1.创建推广项目 2.多账号授权 3.企业号智能客服系统 总结 前言 短视频多账号矩阵系统&#xff0c;通过多账号一键授权管理的方式&#xff0c;为运营人员打造功能强大及全面的“矩阵式“管理平台。…

从零构建深度学习推理框架-1 简介和Tensor

源代码作者&#xff1a;https://github.com/zjhellofss 本文仅作为个人学习心得领悟 &#xff0c;将原作品提炼&#xff0c;更加适合新手 什么是推理框架&#xff1f; 深度学习推理框架用于对已训练完成的神经网络进行预测&#xff0c;也就是说&#xff0c;能够将深度训练框…

UE虚幻引擎教程_生成云平台指定路径下的exe文件

市面上大量优秀的游戏都是基于UE制作的&#xff0c;UE虚幻引擎制作的作品可以在windows、mac、linux以及ps4、x-boxone、ios、android甚至是html5等平台上运行。本文介绍了UE虚幻引擎如何生成云平台指定路径下的EXE。 一、云平台会运行打包文件夹下指定路径的EXE文件 但有时候…

【多选框、表格全选】element el-checkbox、el-table

话不多说 先看效果&#xff1a; 多选框&#xff1a; 表格全选&#xff1a; <template><div><div class"titleLabel"><div class"lineStyle"></div>统计部门</div><div style"display: flex"><e…

项目开启启动命令整合

启动RabbitMQ管理插件 1.启动 RabbitMQ 管理插件。 rabbitmq-plugins enable rabbitmq_management rabbitmq-server # 直接启动&#xff0c;如果关闭窗⼝或需要在该窗⼝使⽤其他命令时应⽤就会停⽌ rabbitmq-server -detached # 后台启动 rabbitmq-server start # 启⽤服务 rab…

(二)安装部署InfluxDB

以下内容来自 尚硅谷&#xff0c;写这一系列的文章&#xff0c;主要是为了方便后续自己的查看&#xff0c;不用带着个PDF找来找去的&#xff0c;太麻烦&#xff01; 第 2 章 安装部署InfluxDB 1、linux 安装方式如下 通过包管理工具安装&#xff0c;比如apt 和yum直接下载可执…

springboot()—— 集成redis

1、新建一个springboot项目 2、添加redis依赖包 可以在新建项目的时候就选上 也可以建完项目以后手动导入pom.xml <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </d…

2023年基准Kubernetes报告:6个K8s可靠性失误

云计算日益成为组织构建应用程序和服务的首选目的地。尽管一年来经济不确定性的头条新闻主要集中在通货膨胀增长和银行动荡方面&#xff0c;但大多数组织预计今年的云使用和支出将与计划的相同&#xff08;45%&#xff09;&#xff0c;或高于计划的&#xff08;45%&#xff09;…

装饰模式-扩展系统功能

买了新车后&#xff0c;不少人会对车进行装饰&#xff0c;比如给车贴膜&#xff0c;喷上骚粉的漆等。某天&#xff0c;小李和小张都买了辆车&#xff0c;小李想给车贴膜&#xff0c;小张想给车先喷漆然后再贴膜。现在中的做法是&#xff0c;把车开到改装店&#xff0c;如果要喷…

浏览器调试Android App

浏览器调试Android App 1. 背景2. 调试工具3. 手机设置4. 打开浏览器(edge)5. 连接手机6. 点击inspect 开始调试 1. 背景 在工作中经常会遇到在原生app中嵌套h5&#xff0c; 但是在某些需要在app里面调试的内容&#xff0c; 却没有像chrome开发者工具这样的工具来帮助我们快速…

react 在build读取env 数据

默认会读取.env 文件 npm install dotenv --save npm install dotenv-cli --save-dev例如读取.env.test "build:test": "dotenv -e .env.test react-app-rewired build",.env.test REACT_APP_CURRENTMODE devREACT_APP_Public_Path "https://baid…

[NLP]使用Alpaca-Lora基于llama模型进行微调教程

Stanford Alpaca 是在 LLaMA 整个模型上微调&#xff0c;即对预训练模型中的所有参数都进行微调&#xff08;full fine-tuning&#xff09;。但该方法对于硬件成本要求仍然偏高且训练低效。 [NLP]理解大型语言模型高效微调(PEFT) 因此&#xff0c; Alpaca-Lora 则是利用 Lora…

算法竞赛入门【码蹄集新手村600题】(MT1040-1060)

算法竞赛入门【码蹄集新手村600题】(MT1040-1060&#xff09; 目录MT1041 求圆面积和周长MT1042 求矩形的面积和周长MT1043 椭圆计算MT1044 三角形面积MT1045 平行四边形MT1046 菱形MT1047 梯形MT1048 扇形面积MT1049 三角形坐标MT1050 空间三角形MT1051 四边形坐标MT1052 直角…