社区
数据结构与算法
帖子详情
求三维向量组仿射变换的快速算法。
pulley
2003-09-23 10:47:19
加精
对一组三维向量进行仿射变换,也就是与仿射变换矩阵相乘(4*4)。我是每个向量分别与矩阵相乘的,已经考虑到了仿射变换的特殊性,减少了一些乘法运算,可是在应用中还是不够快。
有没有快速算法解决这个问题?由衷感谢。
...全文
181
3
打赏
收藏
求三维向量组仿射变换的快速算法。
对一组三维向量进行仿射变换,也就是与仿射变换矩阵相乘(4*4)。我是每个向量分别与矩阵相乘的,已经考虑到了仿射变换的特殊性,减少了一些乘法运算,可是在应用中还是不够快。 有没有快速算法解决这个问题?由衷感谢。
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
3 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
pulley
2003-09-24
打赏
举报
回复
刚才贴的是错的,应该是这个:
typedef double TMatrix[4][4];
typedef double TVector3d[3];
enum {SizeOfMatrixElmt = 8, SizeOfVectorElmt = 8};
void VectorsMulMatrix(TVector3d* FirstVector, int Count, const TMatrix * AMatrix)
{
__asm
{
LVECT_BEGIN:
MOV EAX, FirstVector;
MOV EDX, Count;
MOV ECX, AMatrix;
FLD QWORD PTR [ECX];
FMUL QWORD PTR [EAX];
FLD QWORD PTR [ECX + SizeOfMatrixElmt];
FMUL QWORD PTR [EAX];
FLD QWORD PTR [ECX + SizeOfMatrixElmt * 2];
FMUL QWORD PTR [EAX];
FLD QWORD PTR [ECX + SizeOfMatrixElmt * 4];
FMUL QWORD PTR [EAX + SizeOfVectorElmt];
FLD QWORD PTR [ECX + SizeOfMatrixElmt * (4 + 1)];
FMUL QWORD PTR [EAX + SizeOfVectorElmt];
FLD QWORD PTR [ECX + SizeOfMatrixElmt * (4 + 2)];
FMUL QWORD PTR [EAX + SizeOfVectorElmt];
FXCH ST(2);
FADDP ST(5), ST(0);
FADDP ST(3), ST(0);
FADDP ST(1), ST(0);
FLD QWORD PTR [ECX + SizeOfMatrixElmt * 4 * 2];
FMUL QWORD PTR [EAX + SizeOfVectorElmt * 2];
FLD QWORD PTR [ECX + SizeOfMatrixElmt * (4 * 2 + 1)];
FMUL QWORD PTR [EAX + SizeOfVectorElmt * 2];
FLD QWORD PTR [ECX + SizeOfMatrixElmt * (4 * 2 + 2)];
FMUL QWORD PTR [EAX + SizeOfVectorElmt * 2];
FXCH ST(2);
FADDP ST(5), ST(0);
FADDP ST(3), ST(0);
FADDP ST(1), ST(0);
FXCH ST(2);
FLD QWORD PTR [ECX + SizeOfMatrixElmt * (4 * 3)];
FADDP ST(1), ST(0)
FXCH ST(1);
FLD QWORD PTR [ECX + SizeOfMatrixElmt * (4 * 3 + 1)];
FADDP ST(1), ST(0);
FXCH ST(2);
FLD QWORD PTR [ECX + SizeOfMatrixElmt * (4 * 3 + 2)];
FADDP ST(1), ST(0);
FXCH ST(1);
FSTP QWORD PTR [EAX];
FSTP QWORD PTR [EAX + SizeOfVectorElmt * 2];
FSTP QWORD PTR [EAX + SizeOfVectorElmt];
LEA EAX, [EAX + SizeOfVectorElmt * 3];
SUB EDX, 1;
JNZ LVECT_BEGIN;
}
}
pulley
2003-09-24
打赏
举报
回复
速度确实很快。谢谢。
我改了一下,改用C,矩阵用double。我把我改的结果也贴上来:
typedef double TMatrix[4][4];
typedef double TVector3d[3];
enum {SizeOfMatrixElmt = 8, SizeOfVectorElmt = 8};
void VectorsMulMatrix(TVector3d* FirstVector, int Count, const TMatrix * AMatrix)
{
__asm
{
LVECT_BEGIN:
MOV EAX, FirstVector;
MOV EDX, Count;
MOV ECX, AMatrix;
FLD TBYTE PTR [ECX];
FMUL QWORD PTR [EAX];
FLD TBYTE PTR [ECX + SizeOfMatrixElmt];
FMUL QWORD PTR [EAX];
FLD TBYTE PTR [ECX + SizeOfMatrixElmt * 2];
FMUL QWORD PTR [EAX];
FLD TBYTE PTR [ECX + SizeOfMatrixElmt * 4];
FMUL QWORD PTR [EAX + SizeOfVectorElmt];
FLD TBYTE PTR [ECX + SizeOfMatrixElmt * (4 + 1)];
FMUL QWORD PTR [EAX + SizeOfVectorElmt];
FLD TBYTE PTR [ECX + SizeOfMatrixElmt * (4 + 2)];
FMUL QWORD PTR [EAX + SizeOfVectorElmt];
FXCH ST(2);
FADDP ST(5), ST(0);
FADDP ST(3), ST(0);
FADDP ST(1), ST(0);
FLD TBYTE PTR [ECX + SizeOfMatrixElmt * 4 * 2];
FMUL QWORD PTR [EAX + SizeOfVectorElmt * 2];
FLD TBYTE PTR [ECX + SizeOfMatrixElmt * (4 * 2 + 1)];
FMUL QWORD PTR [EAX + SizeOfVectorElmt * 2];
FLD TBYTE PTR [ECX + SizeOfMatrixElmt * (4 * 2 + 2)];
FMUL QWORD PTR [EAX + SizeOfVectorElmt * 2];
FXCH ST(2);
FADDP ST(5), ST(0);
FADDP ST(3), ST(0);
FADDP ST(1), ST(0);
FXCH ST(2);
FLD TBYTE PTR [ECX + SizeOfMatrixElmt * (4 * 3)];
FADDP ST(1), ST(0)
FXCH ST(1);
FLD TBYTE PTR [ECX + SizeOfMatrixElmt * (4 * 3 + 1)];
FADDP ST(1), ST(0);
FXCH ST(2);
FLD TBYTE PTR [ECX + SizeOfMatrixElmt * (4 * 3 + 2)];
FADDP ST(1), ST(0);
FXCH ST(1);
FSTP QWORD PTR [EAX];
FSTP QWORD PTR [EAX + SizeOfVectorElmt * 2];
FSTP QWORD PTR [EAX + SizeOfVectorElmt];
LEA EAX, [EAX + SizeOfVectorElmt * 3];
SUB EDX, 1;
JNZ LVECT_BEGIN;
}
}
在VC6中编译运行成功。
短歌如风
2003-09-23
打赏
举报
回复
快速算法我没见过,不过向量乘矩阵是一个高度可并行化的操作,可以通过用汇编代码的方式来充分利用FPU的流水线功能。通过指令顺序的排布,可以达到每条指令一个时钟周期。
我用的一段代码,在D6中实现,fastcall调用方式,第一个参数:EAX,第二个参数:EDX,第三个参数:ECX
矩阵使用80位临时实数格式,向量使用64位长实数格式,你按你的需要改一下吧。
type
TMatrix = array[0..3, 0..3] of Extended;
TVector3d = packed array [0..2] of Double;
procedure VectorsMulMatrix(var FirstVector: TVector3d; Count: Integer;
const AMatrix: TMatrix);
const
SizeOfMatrixElmt = 10;
SizeOfVectorElmt = 8;
asm
@LVECT_BEGIN:
FLD TBYTE PTR [ECX];
FMUL QWORD PTR [EAX];
FLD TBYTE PTR [ECX + SizeOfMatrixElmt];
FMUL QWORD PTR [EAX];
FLD TBYTE PTR [ECX + SizeOfMatrixElmt * 2];
FMUL QWORD PTR [EAX];
FLD TBYTE PTR [ECX + SizeOfMatrixElmt * 4];
FMUL QWORD PTR [EAX + SizeOfVectorElmt];
FLD TBYTE PTR [ECX + SizeOfMatrixElmt * (4 + 1)];
FMUL QWORD PTR [EAX + SizeOfVectorElmt];
FLD TBYTE PTR [ECX + SizeOfMatrixElmt * (4 + 2)];
FMUL QWORD PTR [EAX + SizeOfVectorElmt];
FXCH ST(2);
FADDP ST(5), ST(0);
FADDP ST(3), ST(0);
FADDP ST(1), ST(0);
FLD TBYTE PTR [ECX + SizeOfMatrixElmt * 4 * 2];
FMUL QWORD PTR [EAX + SizeOfVectorElmt * 2];
FLD TBYTE PTR [ECX + SizeOfMatrixElmt * (4 * 2 + 1)];
FMUL QWORD PTR [EAX + SizeOfVectorElmt * 2];
FLD TBYTE PTR [ECX + SizeOfMatrixElmt * (4 * 2 + 2)];
FMUL QWORD PTR [EAX + SizeOfVectorElmt * 2];
FXCH ST(2);
FADDP ST(5), ST(0);
FADDP ST(3), ST(0);
FADDP ST(1), ST(0);
FXCH ST(2);
FLD TBYTE PTR [ECX + SizeOfMatrixElmt * (4 * 3)];
FADDP ST(1), ST(0)
FXCH ST(1);
FLD TBYTE PTR [ECX + SizeOfMatrixElmt * (4 * 3 + 1)];
FADDP ST(1), ST(0);
FXCH ST(2);
FLD TBYTE PTR [ECX + SizeOfMatrixElmt * (4 * 3 + 2)];
FADDP ST(1), ST(0);
FXCH ST(1);
FSTP QWORD PTR [EAX];
FSTP QWORD PTR [EAX + SizeOfVectorElmt * 2];
FSTP QWORD PTR [EAX + SizeOfVectorElmt];
LEA EAX, [EAX + SizeOfVectorElmt * 3];
SUB EDX, 1;
JNZ @LVECT_BEGIN;
end;
详解Python计算机视觉 图像扭曲(仿射扭曲)
对图像块应用
仿射变换
,我们将其称为图像扭曲(或者仿射扭曲)。该操作不仅经常应用在计算机图形学中,而且经常出现在计算机视觉
算法
中。 一、
仿射变换
原理
仿射变换
能够保持图像的“平直性”,包括旋转,缩放,平移,错切操作。对于三个点,
仿射变换
可以将一副图像进行扭曲,使得三对对应点对可以完美地匹配上。
仿射变换
具有6个自由度,有三个对应点对可以给出6个约束条件(对于这三个对应点对,x和y坐标必须都要匹配)
仿射变换
是在几何上定义为两个
向量
空间之间的一个
仿射变换
或者仿射映射。由一个非奇异的线性变换(运用一次函数进行的变换)接上一个平移变换
组
成。在有限维的情况,每个
仿射变换
可以由一个矩阵A和一个
向量
b给出,它
2017年人脸检测、人脸对齐、人脸识别源码
人脸检测 人脸对齐 人脸识别工程,五点人脸特征识别 实时性好
【视觉高级篇】22 # 如何用
仿射变换
来移动和旋转3D物体?
【跟月影学可视化】学习笔记。对于平移变换来说,如果
向量
P(x0x_0x0, y0y_0y0, z0z_0z0) 沿着
向量
Q(x1x_1x1, y1y_1y1, z1z_1z1) 平移,只需要让 P 加上 Q,就能得到变换后的坐标。让
三维
向量
乘上标量,就相当于乘上要缩放的倍数。可以使用齐次矩阵来表示
三维
仿射变换
,通过引入一个新的维度,就可以把
仿射变换
转换为齐次矩阵的线性变换。
三维
物体的旋转变换比较复杂一点,下面先了解一下欧拉角。中文维基百科:欧拉角莱昂哈德·欧拉用欧
刚性
仿射变换
算法
_图像的
仿射变换
目录:概述图像基本变换
仿射变换
原理python实现一、概述图像的几何变换主要包括:平移、缩放、旋转、仿射、透视等等。图像变换是建立在矩阵运算基础上的,通过矩阵运算可以很快的找到不同图像的对应关系。理解变换的原理需要理解变换的构造方法以及矩阵的运算方法。图像的几何变换主要分为三类:刚性变换、
仿射变换
和透视变换,如下图:
仿射变换
是从一个二维坐标系变换到另一个二维坐标系,属于线性变换。通过已知3对坐标点...
3D
仿射变换
矩阵推导
仿射变换
包括线性变换和平移变换,先来说线性变换中的旋转变换,这个稍微要复杂一点.讲这个之前,我假设你已经对线性代数有一定的了解,比如三角函数,
向量
,以及矩阵的相关知识(以及他们所代表的几何意义),如果以上知识不熟悉,很难看懂下面讲的内容.
仿射变换
包括旋转,缩放,平移,切变,反射...等等,在3D空间中,,所有这些效果都是通过矩阵来完成,也就是矩阵乘法实现,矩阵的乘法是满足结合律的,也就是说,我们可...
数据结构与算法
33,028
社区成员
35,337
社区内容
发帖
与我相关
我的任务
数据结构与算法
数据结构与算法相关内容讨论专区
复制链接
扫一扫
分享
社区描述
数据结构与算法相关内容讨论专区
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章