前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >线性代数:坐标系转换

线性代数:坐标系转换

原创
作者头像
Jean
发布2021-11-02 10:30:03
7880
发布2021-11-02 10:30:03
举报
文章被收录于专栏:Web行业观察Web行业观察

问题描述:

已知一个全局坐标系,还有若干局部坐标系,如何将局部坐标系的坐标转成全局坐标系的坐标?反过来又如何进行?

这里的坐标系都是直角坐标系。

本文通过下面几个方面的研究来回答上面的问题。

1、简单示例

2、求解过程

3、nodejs编程验证

简单示例

已知点A(6,6),B(14,14),C(-2,14),G(12,12),求当A为原点 ,AB为X轴,AC为Y轴时 G点的坐标。可以见下图:

图片
图片

通过查看图形,我们可以很快的计算出点G新的坐标如下:

图片
图片

但是如果G为任意一点,我们还能轻松求出来么?显然我们不行。我们需要一种通用的方法来一次到位,这里就引入了矩阵变换的概念。

求解过程

重新理解坐标系的(x,y)。看下图:

图片
图片

我们的某个点的坐标实际上表达的是坐标轴单位向量的个数。x表示X轴单位向量个数,y表示Y轴单位向量个数。有了这个概念之后,我们重新来看待上面的问题:

假设AB单位向量为p(px,py),AC单位向量为q(qx,qy)。点G在新坐标系下为(x1,y1)

图片
图片

换成矩阵计算的写法:

图片
图片

由于AG向量可以很容易的求出来,单位向量p,q也很容易求出来,所以我们的新的坐标系下面的(x1,y1)也可以很容易求出来。通过逆矩阵变换可以求出下面公式:

图片
图片

就这样,我们通过重新理解坐标x和y的含义,通过引入了一个变换矩阵就轻松解决了坐标系的变换,是不是非常简单?这也是出乎我意料之外的,开始我也觉得好难好难。不过上述方法每次需要先求出AG的向量再进行计算,我们能否做到一步到位?当时答案是肯定的,我们通过引入一个三维矩阵,就可以轻松搞定。

我们将上述变换矩阵由二维扩展到三维,如下:假设A点的坐标为(Ax,Ay)。点G新坐标下(x1,x2),老坐标下(x0,y0)

这里我们换成三维矩阵的表达形式:

图片
图片

最左边的三维变换矩阵可以很容易求出来,那么我们可以根据G新坐标求出老坐标。再通过逆矩阵也可以根据老坐标求出新坐标。

总结:

解决这个问题非常简单只需要两步就搞定了。

第一步:我们需要求出新坐标系的x轴和y轴的单位向量,

第二步:构建一个三维变换矩阵,完成坐标的转换。

nodejs编程验证

这里通过编程的方式来验证变换矩阵的正确性,验证的示例就是上面简单示例。

这里矩阵计算我们采用gl-matrix库,github地址如下:

代码语言:javascript
复制
https://github.com/toji/gl-matrix
图片
图片

安装如下:这个库不需要再安装ts的定义,已经自带了。

代码语言:javascript
复制
npm i gl-matrix

第一步:定义点

代码语言:javascript
复制
let A 
    = gl.vec3.fromValues(6, 6, 1)let B 
    = gl.vec3.fromValues(14, 14, 1)let C 
    = gl.vec3.fromValues(-2, 14, 1)let G 
    = gl.vec3.fromValues(12, 12, 1)

第二步:求新坐标系的X轴和Y轴的单位向量

代码语言:javascript
复制
let AB: gl.vec3 = gl.vec3.create()let AC: gl.vec3 = gl.vec3.create()
gl.vec3.subtract(AB, B, A)gl.vec3.subtract(AC, C, A)
let UnitAB: gl.vec3 = gl.vec3.create()let UnitAC: gl.vec3 = gl.vec3.create()
gl.vec3.normalize(UnitAB, AB)gl.vec3.normalize(UnitAC, AC)

第三步:构造计算矩阵

代码语言:javascript
复制
let mat = gl.mat3.fromValues( 
    UnitAB[0],
    UnitAB[1], 
    UnitAB[2],  
    UnitAC[0],  
    UnitAC[1],  
    UnitAC[2], 
A[0],  A[1],  A[2])

第四步:求逆矩阵

代码语言:javascript
复制
let matInvert: gl.mat3 = gl.mat3.create()gl.mat3.invert(matInvert, mat)

第五步:求新坐标系下的坐标G1

代码语言:javascript
复制
let G1: gl.vec3 = gl.vec3.create()gl.vec3.transformMat3(G1, G, matInvert)

第六步:根据新求出的坐标反过来求原坐标系坐标G2

代码语言:javascript
复制
let G2 = gl.vec3.create()gl.vec3.transformMat3(G2, G1, mat)

第七步:设置人工算出的值G3

代码语言:javascript
复制
let G3 = gl.vec3.fromValues(3 * Math.sqrt(8), 0, 1)

输出结果如下:验证矩阵变换结果符合预期

代码语言:javascript
复制
G:12,12,1G1:8.485280990600586,0,1G2:12,12,1G3:8.485280990600586,0,1

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档