为了找出优化代码的方案,梳理矩阵类现有代码。现汇总转换矩阵所有代码在同一个文件中,同时调整了与矩阵类重载的代码的先后次序。完整代码如下:
/*矩阵类编程思路总说明:
平面CAD对象主要包括点(point)、线(line 含线段、直线、射线,宽线、多段线)、平面形状(shap 含矩形、圆形、椭圆、文字、图块实体、外部参照实体及各种标注等)。我们先用点(point)来说明矩阵功能。
点(P),可以用向量(1,x, y)表示。
一、如果点发生平移时,转换矩阵(Move)为
1 Dx Dy
0 1 0
0 0 1
即P.move(Dx,Dy)=(x+Dx,y+Dy)=P*Move;
平移(Move)矩阵是本矩阵类(Matrix)的泛型特例,单独说明
二、如果点发生旋转时(旋转角度为a),转换矩阵Rotate为
1 0 0
0 cos(a) sin(a)
0 -sin(a) cos(a)
即P.rotation(a)=(x * cos(a) - y * sin(a),x * sin(a) + y *cos(a))=P*M;
旋转(Rotate)矩阵是本矩阵类(Matrix)的泛型特例,单独说明,为提高效率,角度类(Angle)参与矩阵乘法计算。
三、如果点发生缩放时,比例为(Sx,Sy),转换矩阵(Scale)为
1 0 0
0 Sx 0
0 0 Sy
即P.rotation(a)=(x * Sx,y * Sy)=P*Scale;
缩放(Scale)矩阵是本矩阵类(Matrix)的泛型特例,单独说明,为提高效率,实数(f64)参与矩阵乘法计算。
四、平移、旋转、缩放的组合矩阵(M2D)可以表示为
1 Dx Dy
0 Xx Xy
0 Yx Yy
即P.M=(1,x*Xx+y*Yx+1*Dx,x*Xy+y*Yy+1*Dy)=P*M2D;
组合(M2D)矩阵是本矩阵类(Matrix)的泛型特例,单独说明。
五、转换矩阵通过乘法运算的重载,实现其功能。该乘法支持结合律,如P*M1*M2*M3=P*(M1*M2*M3)
根据上面叙述,总结出如下编程思路:
1、平面几何转换,都可以使用转换矩阵实现,不需要在各几何体类中单独实现平移、旋转、缩放功能;
2、多次平面几何转换,如P*M1*M2*M3,可以使用结合律,让多个矩阵合并成一个转换矩阵。
3、考虑到纯平移、旋转或缩放转换用组合矩阵计算时,会出现大量已知的0或1参加计算,影响计算速度。因此定义了3个零大小的类Zero、One和NegOne用于表示0、1、-1,该定义在number.rs文件中实现。转换矩阵为泛型类,泛型定义在本文件实现,通过泛型特例实现的平移(Move)、旋转(Rotate)、缩放(Scale)、组合(M2D)等矩阵独立解说。
4、为了汇总几何体与转换矩阵的计算(如 P*M),方便系统维护,几何体类的参数写成矩阵格式。初步意向如下,后面单独解说。
(1)点(point)(x,y)可以认为是点(0,0)平移到(x,y)后形成的,即表示为:
1 x y
0 0 0
0 0 0
(2) 线段(line)有起点(x1,y1)和终点(x2,y2),可以认为是起点(0,0),终点为(1,0)的线段经过变换得来的,即:
1 x1 y1
0 x2-x1 y2-y1
0 0 0
(3) 圆有圆心(Ox,Oy)、半径r(等价于圆过点(Ox+r,Oy) ),可以理解为圆心在(0,0),半径为1(等价于圆过点(1,0))的单位圆变换过来的,即:
1 Ox Oy
0 r 0
0 0 0
(4) 椭圆有圆心(Ox,Oy)、长半轴长 Ra,短半轴长Rb,与圆类似,表示如下:
1 Ox Oy
0 Ra 0
0 0 Rb
(5) 图块实体有插入点(x,y),x轴比例Sx、y轴比例Sy、旋转角度a,表示如下:
Sx*cos(a) Sx*sin(a) 0
-Sy*sin(a) Sy*cos(a) 0
x y 1
六、 根据运算结果,增加一个类非切变矩阵(NonShear),结构如下
1 Dx Dy
0 Xx 0
0 0 Yy
*/
/*
* 编制人: $ource
* 修改版次:0版完成版
* 本版次创建时间: 2024年8月24日
* 最后修改时间: 无
* 待完善问题:无
* 说明:
* 转换矩阵Matrix有大量已知的0和1及-1参与计算。为标识这些特征,提高编译后代码效率,实现零大小的Zero、One、NegOne类型。
*/
#[derive(Debug,Copy,Clone)]
pub struct Zero{
}
#[derive(Debug,Copy,Clone)]
pub struct One{
}
#[derive(Debug,Copy,Clone)]
pub struct NegOne{
}
/*转换矩阵通用类Matrix
* 编制人: $ource
* 修改版次:0.2.0版完成版
* 本版次创建时间: 2024年8月16日
* 最后修改时间: 2024年8月26日
* 待完善问题:无
*/
use std::ops::{Mul,Div};
// 变换矩阵数据格式(TransformMatrix)
// 1 dx dy 1 Dx Dy 1 m01 m02
// 0 sx ry 0 Xx Xy 0 m11 m12
// 0 rx sy 0 Yx Yy 0 m21 m22
#[derive(Clone,Copy)]
pub struct Matrix<Tdx:Clone+Copy,Tdy:Clone+Copy,Txx:Clone+Copy,Txy:Clone+Copy,Tyx:Clone+Copy,Tyy:Clone+Copy>{
pub m01:Tdx,pub m02:Tdy,
pub m11:Txx,pub m12:Txy,
pub m21:Tyx, pub m22:Tyy
}
pub type M2D=Matrix<f64,f64,f64,f64,f64,f64>;//组合矩阵M2D
pub type NonShear=Matrix<f64,f64,f64,Zero,Zero,f64>;//非切变矩阵NonShear
pub type Rotate=Matrix<Zero,Zero,f64,f64,f64,f64>;//旋转矩阵Rotate
pub type Scale=Matrix<Zero,Zero,f64,Zero,Zero,f64>;//缩放矩阵Scale
pub type Move=Matrix<f64,f64,One,Zero,Zero,One>;//平移矩阵Move
/*
* 矩阵基本变换,组合矩阵类 M2D
** 编制人: $ource
* 修改版次及创建时间:0版完成版(2024年8月25日)
* 修改内容及时间:无
* 待完善问题:无
* 内容说明:组合矩阵是一个2X3 实数(f64)类型的矩阵,实现了“组合矩阵*组合矩阵”的乘法重载。矩阵格式如下
* 1 m01 m02
* 0 m11 m12
* 0 m21 m22
*/
impl M2D{
pub fn new(dx:f64,dy:f64,xx:f64,xy:f64,yx:f64,yy:f64)->M2D{
M2D{
m01:dx, m02:dy,
m11:xx, m12:xy,
m21:yx, m22:yy
}
}
}
impl Mul<M2D> for M2D{//“组合矩阵*组合矩阵”
type Output = M2D;
fn mul(self, tm:M2D) ->M2D{
M2D{
m01:self.m01 * tm.m11 + self.m02 * tm.m21 + tm.m01,m02:self.m01 * tm.m12 + self.m02 * tm.m22 + tm.m02,
m11:self.m11 * tm.m11 + self.m12 * tm.m21 ,m12:self.m11 * tm.m12 + self.m12 * tm.m22,
m21:self.m21 * tm.m11 + self.m22 * tm.m21 ,m22:self.m21 * tm.m12 + self.m22 * tm.m22
}
}
}
impl Mul<NonShear> for M2D{//“组合矩阵*非切变矩阵”
type Output = M2D;
fn mul(self, tm:NonShear) ->M2D{
M2D{
m01:self.m01 * tm.m11 + tm.m01, m02:self.m02 * tm.m22 + tm.m02,
m11:self.m11 * tm.m11 , m12:self.m12 * tm.m22,
m21:self.m21 * tm.m11 , m22:self.m22 * tm.m22
}
}
}
impl Mul<Rotate> for M2D{//组合矩阵*旋转矩阵
type Output = M2D;
fn mul(self, tm:Rotate) ->M2D{
M2D{
m01:self.m01 * tm.m11 + self.m02 * tm.m21 ,m02:self.m01 * tm.m12 + self.m02 * tm.m22,
m11:self.m11 * tm.m11 + self.m12 * tm.m21 ,m12:self.m11 * tm.m12 + self.m12 * tm.m22,
m21:self.m21 * tm.m11 + self.m22 * tm.m21 ,m22:self.m21 * tm.m12 + self.m22 * tm.m22
}
}
}
impl Mul<Scale> for M2D{//组合矩阵*缩放矩阵
type Output = M2D;
fn mul(self, tm:Scale) ->M2D{
M2D{
m01:self.m01 * tm.m11, m02:self.m02 * tm.m22,
m11:self.m11 * tm.m11, m12:self.m12 * tm.m22,
m21:self.m21 * tm.m11, m22:self.m22 * tm.m22
}
}
}
impl Mul<Move> for M2D{//组合矩阵*平移矩阵
type Output = M2D;
fn mul(self, tm:Move) ->M2D{
M2D{
m01:self.m01 + tm.m01,m02:self.m02+ tm.m02,
m11:self.m11 ,m12:self.m12,
m21:self.m21 ,m22:self.m22
}
}
}
/*
* 矩阵变换,非切变类NonShear
** 编制人: $ource
* 修改版次及创建时间:0版完成版(2024年8月26日)
* 修改内容及时间:无
* 待完善问题:无
* 内容说明:非切变是“平移矩阵*缩放矩阵”的产物,分别实现了“非切变矩阵*各矩阵”的运算符重载。非切变矩阵格式如下。
1 m01 m02
0 m11 0
0 0 m22
*/
impl NonShear{
pub fn new(dx:f64,dy:f64,xx:f64,yy:f64)->NonShear{
NonShear{
m01:dx , m02:dy,
m11:xx , m12:Zero{},
m21:Zero{}, m22:yy
}
}
}
impl Mul<M2D> for NonShear{//“非切变矩阵*组合矩阵”
type Output = M2D;
fn mul(self, tm:M2D) ->M2D{
M2D{
m01:self.m01 * tm.m11 + self.m02 * tm.m21 + tm.m01, m02:self.m01 * tm.m12 + self.m02 * tm.m22 + tm.m02,
m11:self.m11 * tm.m11 , m12:self.m11 * tm.m12,
m21:self.m22 * tm.m21 , m22:self.m22 * tm.m22
}
}
}
impl Mul<NonShear> for NonShear{//“非切变矩阵*非切变矩阵”
type Output = NonShear;
fn mul(self, tm:NonShear) ->NonShear{
NonShear::new(self.m01 * tm.m11 + tm.m01, self.m02 * tm.m22 + tm.m02,
self.m11 * tm.m11
, self.m22 * tm.m22
)
}
}
impl Mul<Rotate> for NonShear{//“非切变矩阵*旋转矩阵”
type Output = M2D;
fn mul(self, tm:Rotate) ->M2D{
M2D{
m01:self.m01 * tm.m11 + self.m02 * tm.m21, m02:self.m01 * tm.m12 + self.m02 * tm.m22,
m11:self.m11 * tm.m11 , m12:self.m11 * tm.m12,
m21:self.m22 * tm.m21 , m22:self.m22 * tm.m22
}
}
}
impl Mul<Scale> for NonShear{//非切变矩阵*缩放矩阵
type Output = NonShear;
fn mul(self, tm:Scale) ->NonShear{
NonShear::new(self.m01 * tm.m11,self.m02 * tm.m22,
self.m11 * tm.m11
,self.m22 * tm.m22
)
}
}
impl Mul<Move> for NonShear{//“非切变矩阵*平移矩阵”
type Output = NonShear;
fn mul(self, tm:Move) ->NonShear{
NonShear::new(self.m01 + tm.m01, self.m01 + tm.m02,
self.m11
, self.m22
)
}
}
/*
* 矩阵基本变换,旋转类Rotate
** 编制人: $ource
* 修改版次及创建时间:0版完成版(2024年8月26日)
* 修改内容及时间:无
* 待完善问题:无
* 内容说明:旋转是矩阵基本功能,分别实现了“组合矩阵*各矩阵”的运算符重载。旋转矩阵格式如下。
1 0 0
0 cos(a) sin(a)
0 -sin(a) cos(a)
*/
use super::angle::Angle;
impl Rotate{
pub fn new(xx:f64,xy:f64,yx:f64,yy:f64)->Rotate{
Rotate{
m01:Zero{}, m02:Zero{},
m11:xx, m12:xy,
m21:yx, m22:yy
}
}
pub fn from(ang:Angle)->Rotate{
let ang_x=ang.unit_x();
let ang_y=ang.unit_y();
Rotate::new(ang_x,ang_y,-ang_y,ang_x)
}
}
impl Mul<M2D> for Rotate{//旋转矩阵*组合矩阵
type Output = M2D;
fn mul(self, tm:M2D) ->M2D{
M2D{
m01:tm.m01 , m02:tm.m02,
m11:self.m11 * tm.m11 + self.m12 * tm.m21, m12:self.m11 * tm.m12 + self.m12 * tm.m22,
m21:self.m21 * tm.m11 + self.m22 * tm.m21 ,m22:self.m21 * tm.m12 + self.m22 * tm.m22
}
}
}
impl Mul<NonShear> for Rotate{//“旋转矩阵*非切变矩阵”
type Output = M2D;
fn mul(self, tm:NonShear) ->M2D{
M2D{
m01:tm.m01 , m02:tm.m02,
m11:self.m11 * tm.m11, m12:self.m12 * tm.m22,
m21:self.m21 * tm.m11, m22:self.m22 * tm.m22
}
}
}
impl Mul<Rotate> for Rotate{//旋转矩阵*旋转矩阵
type Output = Rotate;
fn mul(self, tm:Rotate) ->Rotate{
Rotate::new(
self.m11 * tm.m11 + self.m12 * tm.m21, self.m11 * tm.m12 + self.m12 * tm.m22,
self.m21 * tm.m11 + self.m22 * tm.m21, self.m21 * tm.m12 + self.m22 * tm.m22
)
}
}
impl Mul<Scale> for Rotate{//旋转矩阵*缩放矩阵
type Output = Rotate;
fn mul(self, tm:Scale) ->Rotate{
Rotate::new(
self.m11 * tm.m11, self.m12 * tm.m22,
self.m21 * tm.m11,self.m22 * tm.m22
)
}
}
impl Mul<Move> for Rotate{//旋转矩阵*平移矩阵
type Output = M2D;
fn mul(self, tm:Move) ->M2D{
M2D{
m01:tm.m01, m02:tm.m02,
m11:self.m11, m12:self.m12,
m21:self.m21,m22:self.m22
}
}
}
/*
* 矩阵基本变换,缩放类Scale
** 编制人: $ource
* 修改版次及创建时间:0版完成版(2024年8月26日)
* 修改内容及时间:无
* 待完善问题:无
* 内容说明:缩放是矩阵基本功能,分别实现了“组合矩阵*各矩阵”的运算符重载。缩放矩阵格式如下。
1 0 0
0 Sx 0
0 0 Sy
*/
impl Scale{
pub fn new(sx:f64,sy:f64)->Scale{
Scale{
m01:Zero{}, m02:Zero{},
m11:sx , m12:Zero{},
m21:Zero{}, m22:sy
}
}
pub fn from(scale:f64)->Scale{
Scale::new(scale,scale)
}
}
impl Mul<M2D> for Scale{//缩放矩阵*组合矩阵
type Output = M2D;
fn mul(self, tm:M2D) ->M2D{
M2D{
m01:tm.m01 , m02:tm.m02,
m11:self.m11 * tm.m11, m12:self.m11 * tm.m12,
m21:self.m22 * tm.m21,m22:self.m22 * tm.m22
}
}
}
impl Mul<NonShear> for Scale{//缩放矩阵*非切变矩阵
type Output = NonShear;
fn mul(self, tm:NonShear) ->NonShear{
NonShear::new(tm.m01 , tm.m02,
self.m11 * tm.m11
,self.m22 * tm.m22
)
}
}
impl Mul<Rotate> for Scale{//缩放矩阵*旋转矩阵
type Output = Rotate;
fn mul(self, tm:Rotate) ->Rotate{
Rotate::new(self.m11+tm.m11, self.m11*tm.m12, self.m22*tm.m21, self.m22*tm.m22)
}
}
impl Mul<Scale> for Scale{//缩放矩阵*缩放矩阵
type Output = Scale;
fn mul(self, tm:Scale) ->Scale{
Scale::new(self.m11 * tm.m11, self.m22 * tm.m22)
}
}
impl Mul<Move> for Scale{//缩放矩阵*平移矩阵
type Output = NonShear;
fn mul(self, tm:Move) ->NonShear{
NonShear::new(tm.m01,tm.m02,self.m11,self.m22)
}
}
/*
* 矩阵基本变换,平移类Move
** 编制人: $ource
* 修改版次及创建时间:0版完成版(2024年8月25日)
* 修改内容及时间:无
* 待完善问题:无
* 内容说明:平移是矩阵基本功能,分别实现了“组合矩阵*各矩阵”的运算符重载。平移矩阵格式如下。
* 1 m01 m02
* 0 1 0
* 0 0 1
*/
impl Move{
pub fn new(dx:f64,dy:f64)->Move{
Move{
m01:dx , m02:dy,
m11:One{}, m12:Zero{},
m21:Zero{}, m22:One{}
}
}
}
impl Mul<M2D> for Move{//平移矩阵*组合矩阵
type Output = M2D;
fn mul(self, tm:M2D) ->M2D{
M2D{
m01:self.m01 * tm.m11 + self.m02 * tm.m21 + tm.m01,m02:self.m01 * tm.m12 + self.m02 * tm.m22 + tm.m02,
m11:tm.m11 ,m12:tm.m12,
m21:tm.m21 ,m22:tm.m22
}
}
}
impl Mul<NonShear> for Move{//“平移矩阵*非切变矩阵”
type Output =NonShear;
fn mul(self, tm:NonShear) ->NonShear{
NonShear::new(self.m01 * tm.m11 + tm.m01, self.m02 * tm.m22 + tm.m02,
tm.m11
, tm.m22
)
}
}
impl Mul<Scale> for Move{//平移矩阵*缩放矩阵
type Output = NonShear;
fn mul(self, tm:Scale) ->NonShear{
NonShear::new(self.m01 * tm.m11,self.m02 * tm.m22,tm.m11,tm.m22)
}
}
impl Mul<Rotate> for Move{//平移矩阵*旋转矩阵
type Output = M2D;
fn mul(self, tm:Rotate) ->M2D{
M2D{
m01:self.m01 * tm.m11 + self.m02 * tm.m21,m02:self.m01 * tm.m12 + self.m02 * tm.m22,
m11:tm.m11 ,m12:tm.m12,
m21:tm.m21 ,m22:tm.m22
}
}
}
impl Mul<Move> for Move{//平移矩阵*平移矩阵
type Output = Move;
fn mul(self, tm:Move) ->Move{
Move::new(self.m01 + tm.m01,self.m02+ tm.m02)
}
}
impl Div<Move> for Move{//平移矩阵/平移矩阵
type Output = Move;
fn div(self, tm:Move) ->Move{
Move::new(self.m01 - tm.m01,self.m02- tm.m02)
}
}
标签:矩阵,self,汇总,m22,m11,tm,m01,CAD
From: https://blog.csdn.net/weixin_43219667/article/details/141635021