【學Rust寫CAD】17 通用2D仿射變換矩陣結構體(matrix/generic.rs)

源代碼

// matrix.rs
use std::ops::{Add, Mul};use std::ops::{Add, Mul};/// 通用2D仿射變換矩陣(元素僅需Copy)
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Matrix<X, Y, Xx, Xy, Yx, Yy> {pub x: X, pub y: Y,pub xx: Xx, pub xy: Xy,pub yx: Yx, pub yy: Yy,
}impl<X, Y, Xx, Xy, Yx, Yy> Matrix<X, Y, Xx, Xy, Yx, Yy> {/// 通用二元運算接口#[inline]fn binary_op<A, B, C, D, O>(a: A, b: B, c: C, d: D) -> OwhereO: From<(A, B, C, D)>{O::from((a, b, c, d))}
}/// 線性組合運算轉換器
pub struct LinearCombination<A, B, C, D>(pub A, pub B, pub C, pub D);impl<A, B, C, D> From<(A, B, C, D)> for LinearCombination<A, B, C, D> {fn from(t: (A, B, C, D)) -> Self {LinearCombination(t.0, t.1, t.2, t.3)}
}impl<A, B, C, D, AB, CD> From<LinearCombination<A, B, C, D>> for <AB as Add<CD>>::Output
whereA: Mul<B, Output = AB>,C: Mul<D, Output = CD>,AB: Add<CD>
{fn from(lc: LinearCombination<A, B, C, D>) -> Self {lc.0 * lc.1 + lc.2 * lc.3}
}impl<X1, Y1, Xx1, Xy1, Yx1, Yy1,X2, Y2, Xx2, Xy2, Yx2, Yy2,
> Mul<Matrix<X2, Y2, Xx2, Xy2, Yx2, Yy2>> for Matrix<X1, Y1, Xx1, Xy1, Yx1, Yy1>
where// 基礎約束(僅Copy)X1: Copy, Y1: Copy, Xx1: Copy, Xy1: Copy, Yx1: Copy, Yy1: Copy,X2: Copy, Y2: Copy, Xx2: Copy, Xy2: Copy, Yx2: Copy, Yy2: Copy,// 平移運算約束(不限制Output類型)Xx2: Mul<X1>,Xy2: Mul<Y1>,Yx2: Mul<X1>,Yy2: Mul<Y1>,// 線性變換約束(不限制Output類型)Xx1: Mul<Xx2>,Xx1: Mul<Yx2>,Xy1: Mul<Xy2>,Xy1: Mul<Yy2>,Yx1: Mul<Xx2>,Yx1: Mul<Yx2>,Yy1: Mul<Xy2>,Yy1: Mul<Yy2>,// 加法約束(自動推導)<Xx1 as Mul<Xx2>>::Output: Add<<Xy1 as Mul<Yx2>>::Output>,<Xx1 as Mul<Xy2>>::Output: Add<<Xy1 as Mul<Yy2>>::Output>,<Yx1 as Mul<Xx2>>::Output: Add<<Yy1 as Mul<Yx2>>::Output>,<Yx1 as Mul<Xy2>>::Output: Add<<Yy1 as Mul<Yy2>>::Output>,
{type Output = Matrix<<X1 as Add<<Xx2 as Mul<X1>>::Output>>::Output,  // X<Y1 as Add<<Yy2 as Mul<Y1>>::Output>>::Output,  // Y<<Xx1 as Mul<Xx2>>::Output as Add<<Xy1 as Mul<Yx2>>::Output>>::Output, // Xx<<Xx1 as Mul<Xy2>>::Output as Add<<Xy1 as Mul<Yy2>>::Output>>::Output, // Xy<<Yx1 as Mul<Xx2>>::Output as Add<<Yy1 as Mul<Yx2>>::Output>>::Output, // Yx<<Yx1 as Mul<Xy2>>::Output as Add<<Yy1 as Mul<Yy2>>::Output>>::Output  // Yy>;fn mul(self, rhs: Matrix<X2, Y2, Xx2, Xy2, Yx2, Yy2>) -> Self::Output {Matrix {// 平移計算(完全自由類型推導)x: self.x + rhs.x * self.xx + rhs.y * self.yx,y: self.y + rhs.x * self.xy + rhs.y * self.yy,// 通過轉換器計算線性變換xx: Self::binary_op::<_, _, _, _, _>(self.xx, rhs.xx, self.xy, rhs.yx),xy: Self::binary_op::<_, _, _, _, _>(self.xx, rhs.xy, self.xy, rhs.yy),yx: Self::binary_op::<_, _, _, _, _>(self.yx, rhs.xx, self.yy, rhs.yx),yy: Self::binary_op::<_, _, _, _, _>(self.yx, rhs.xy, self.yy, rhs.yy),}}
}

代碼分析

  1. 矩陣布局
    矩陣采用以下布局:

[ 1 x y 0 x x x y 0 y x y y ] \begin{bmatrix}1 & x & y \\ 0 & xx & xy \\ 0 & yx & yy \end{bmatrix} ?100?xxxyx?yxyyy? ?

這種布局的特點是:

  • 平移分量 x 和 y 位于第一行

  • 線性變換部分位于右下2x2子矩陣

  • 左下保持 [0, 0] 以保證是仿射變換

  1. 核心功能
    矩陣乘法
    兩個矩陣相乘的結果計算如下:

[ 1 x 1 y 1 0 x x 1 x y 1 0 y x 1 y y 1 ] ? [ 1 x 2 y 2 0 x x 2 x y 2 0 y x 2 y y 2 ] = [ 1 x 1 + x 2 ? x x 1 + y 2 ? y x 1 y 1 + x 2 ? x y 1 + y 2 ? y y 1 0 x x 1 ? x x 2 + x y 1 ? y x 2 x x 1 ? x y 2 + x y 1 ? y y 2 0 y x 1 ? x x 2 + y y 1 ? y x 2 y x 1 ? x y 2 + y y 1 ? y y 2 ] \begin{bmatrix}1 & x1 & y1 \\ 0 & xx1 & xy1 \\ 0 & yx1 & yy1 \end{bmatrix} * \begin{bmatrix}1 & x2 & y2 \\ 0 & xx2 & xy2 \\ 0 & yx2 & yy2 \end{bmatrix}= \begin{bmatrix}1 & x1+x2*xx1+y2*yx1 & y1+x2*xy1+y2*yy1 \\ 0 & xx1*xx2+xy1*yx2 & xx1*xy2+xy1*yy2 \\ 0 & yx1*xx2+yy1*yx2 & yx1*xy2+yy1*yy2 \end{bmatrix} ?100?x1xx1yx1?y1xy1yy1? ?? ?100?x2xx2yx2?y2xy2yy2? ?= ?100?x1+x2?xx1+y2?yx1xx1?xx2+xy1?yx2yx1?xx2+yy1?yx2?y1+x2?xy1+y2?yy1xx1?xy2+xy1?yy2yx1?xy2+yy1?yy2? ?

實現特點
  1. 泛型設計:支持不同類型的矩陣元素

  2. trait約束:確保類型安全

  • 乘法約束:Mul trait

  • 加法約束:Add trait

  • 克隆約束:Clone trait

  1. 精確控制:可以控制每種運算的輸出類型

  2. 性能優化:使用#[inline]提示編譯器優化

使用場景

這種矩陣適用于:

  • 2D圖形變換(平移、旋轉、縮放、傾斜)

  • 需要高精度計算的場景

  • 需要組合多個變換的場景(通過矩陣乘法)

優勢
  1. 靈活性:支持不同的數值類型(f32, f64, 定點數等)

  2. 類型安全:編譯時檢查所有操作的有效性

  3. 明確語義:矩陣布局更直觀反映變換參數

  4. 可組合性:通過矩陣乘法組合多個變換

這個實現提供了強大而類型安全的2D仿射變換操作基礎,適合用于圖形引擎、物理模擬等需要精確數學計算的領域。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/75244.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/75244.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/75244.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Spring Boot @RequestParam 解析參數時的常見問題及解決方案

1&#xff0c;遇到的問題&#xff1a;將后端接口寫完后我想通過PostMan進行簡單的測試一下&#xff0c;一不小心就遇到了這樣的情況&#xff1a; org.springframework.web.bind.MissingServletRequestParameterException: Required Integer parameter contractId is not prese…

Golang中間件的原理與實現

一. 什么是 Middleware&#xff1f; 中間件&#xff08;Middleware&#xff09; 是一種 高階函數&#xff0c;它接受一個函數作為輸入&#xff0c;并返回一個經過增強的函數。它的核心思想是通過函數的遞歸嵌套&#xff0c;動態地為函數添加功能。在 Golang 中&#xff0c;中間…

算法設計學習3

實驗目的及要求&#xff1a; 1.加強對結構體的應用。 2.熟悉字符計數排序。 實驗設備環境&#xff1a; 1.微型計算機 2.DEV C(或其他編譯軟件) 實驗步驟&#xff1a; 任務&#xff1a;要求使用自定義函數來實現 輸入一段文本&#xff0c;統計每個字符出現的次數&#xff0c;按…

Vue2和3的vue-router:生命周期、懶加載

Vue2 vue-router 在 Vue 2 中使用 vue-router 可以方便地管理單頁面應用&#xff08;SPA&#xff09;中的路由。理解 vue-router 的生命周期和懶加載機制對于構建高效的 Vue 應用至關重要。以下是一些關鍵點和示例代碼來幫助你理解這些概念。 Vue Router 的生命周期 vue-rou…

【408--考研復習筆記】計算機網絡----知識點速覽

目錄 一、計算機網絡體系結構 1.計算機網絡的定義與功能&#xff1a; 2.網絡體系結構相關概念&#xff1a; 3.OSI 七層模型與 TCP/IP 模型&#xff1a; 4.通信方式與交換技術&#xff1a; 電路交換 報文交換 分組交換 5.端到端通信和點到點通信&#xff1a; 6.計算機…

MySQL-- 多表查詢的分類,SQL92與SQL99,7種JOIN的實現,SQL99語法的新特性

目錄 一&#xff0c;多表查詢的分類 角度1&#xff1a;等值連接 vs 非等值連接 角度2&#xff1a;自連接 vs 非自連接 角度3&#xff1a;內連接 vs 外連接 二&#xff0c;SQL92語法實現內連接&#xff1a;見上&#xff0c;略SQL92語法實現外連接&#xff1a;使用 -…

時間輪算法:原理、演進與應用實踐指南

目錄 1. 時間輪算法基礎 1.1 什么是時間輪算法&#xff1f; 1.2 核心組成部分 2. 基本時間輪的實現機制 2.1 時間輪的構成要素 2.2 工作原理詳解 3. 基本時間輪的局限性 3.1 時間范圍限制問題 3.2 簡單解決方案及其缺陷 4. 時間輪算法的演進 4.1 Round機制&#xff…

Unity 常見報錯 定位和查找方法

1.控制臺 直接看報錯信息 2.打log 例子&#xff1a; for(int i 0;i < 8;i) {Debug.Log(i);//這是打的log,看看到底i是幾的時候出問題gameObject.name strs[i];} 3.斷點調試 &#xff08;1&#xff09;在你想打斷點的行&#xff0c;左邊空白處點擊可以打斷點&#xff…

第十八章:Python實戰專題:北京市水資源數據可視化與圖書館書籍管理應用開發

今天我要和大家分享兩個非常有趣的Python實戰項目&#xff1a;一個是北京市2001-2017年水資源數據的可視化分析&#xff0c;另一個是圖書館書籍管理應用程序的開發。這兩個項目都使用了Python的主流庫&#xff0c;比如Pandas、Matplotlib和Tkinter&#xff0c;非常適合初學者學…

音視頻基礎(音視頻的錄制和播放原理)

文章目錄 一、錄制原理**1. 音視頻數據解析****2. 音頻處理流程****3. 視頻處理流程****4. 同步控制****5. 關鍵技術點****總結** 二、播放原理**1. 音視頻數據解析****2. 音頻處理流程****3. 視頻處理流程****4. 同步控制****5. 關鍵技術點****總結** 一、錄制原理 這張圖展示…

Nginx多域名HTTPS配置全攻略:從證書生成到客戶端安裝

一、業務背景 在現代Web開發中&#xff0c;HTTPS已成為保障數據傳輸安全的標準協議。特別是對于地圖類API服務&#xff08;如高德地圖&#xff09;&#xff0c;往往需要同時支持多個子域名&#xff08;如webapi.amap.com、restapi.amap.com等&#xff09;的HTTPS訪問。傳統方式…

Redis原理:rename命令

RENAME key newkey 將一個key重命名為新key&#xff0c;如果key不存在&#xff0c;則會返回異常。如果newKey已經存在&#xff0c;則會被覆蓋&#xff0c;其實newKey會被顯示的刪除&#xff0c;所以如果newKey是一個大key&#xff0c;則會引起延遲。 源碼 void renameCommand…

k8s污點與容忍

k8s污點與容忍 k8s污點管理常用命令effect標記值查看污點添加污點刪除污點 node污點與容忍污點容忍yaml示例容忍放大基于污點的驅逐驅逐時排除指定服務 設置master調度設置master盡量不調度允許master節點調度pod恢復Master Only狀態將node標記為不可調度狀態(節點警戒)設置nod…

(BFS)題解:P9425 [藍橋杯 2023 國 B] AB 路線

題解&#xff1a;P9425 [藍橋杯 2023 國 B] AB 路線 題目傳送門 P9425 [藍橋杯 2023 國 B] AB 路線 一、題目描述 給定一個NM的迷宮&#xff0c;每個格子標記為A或B。從左上角(1,1)出發&#xff0c;需要移動到右下角(N,M)。移動規則是&#xff1a;必須交替走K個A格子和K個B…

python-leetcode 62.搜索插入位置

題目&#xff1a; 給定一個排序數組和一個目標值&#xff0c;在數組中找到目標值&#xff0c;并返回其索引。如果目標值不存在于數組中&#xff0c;返回它將會被按順序插入的位置 方法一&#xff1a;二分查找 假設題意是在排序數組中尋找是否存在一個目標值&#xff0c;則可以…

【計網速通】計算機網絡核心知識點和高頻考點——數據鏈路層(一)

數據鏈路層核心知識點&#xff08;一&#xff09; 一、數據鏈路層概述 1.1 基本概念 數據鏈路層位于OSI模型的第二層&#xff0c;介于物理層和網絡層之間&#xff0c;主要負責在相鄰節點之間傳輸和識別數據幀。 1.2 主要功能 幀同步&#xff1a;識別幀的開始和結束差錯控制…

模型部署與調用

目錄 部署 ollama下載 模型版本選擇 ?編輯 對照表 控制臺執行 調用 部署 大模型部署我使用的是Ollama&#xff0c;點擊跳轉 接下來我將在本地使用ollama就行模型部署的演示 ollama下載 模型版本選擇 對照表 大家可以根據自己的顯卡配置選擇對應的模型版本 控制臺執…

Rstudio如何使用Conda環境配置的R

前言 Rstudio作為一款流行的R語言集成開發環境&#xff08;IDE&#xff09;&#xff0c;為用戶提供了便捷的編程體驗。然而&#xff0c;不同項目可能需要不同版本的R&#xff0c;這就需要我們靈活切換R版本。除了在之前文章中提到的使用 Docker 部署不同版本的 R 的方法之外&am…

C++---RAII模式

一、RAII模式概述 1. 定義 RAII&#xff08;Resource Acquisition Is Initialization&#xff09;即資源獲取即初始化&#xff0c;是C中用于管理資源生命周期的一種重要編程模式。其核心在于將資源的獲取和釋放操作與對象的生命周期緊密綁定。當對象被創建時&#xff0c;資源…

【功能開發】DSP F2837x 檢測中斷所有函數運行一次的時間

要查看 DSP F28377 的 CPU 在 50 微秒一次的中斷內所有程序運行完總共占用了中斷多長時間&#xff0c;可以采用硬件定時器測量和軟件計時兩種常見方法。 方法一&#xff1a;使用硬件定時器測量 原理 利用 DSP 內部的高精度硬件定時器&#xff0c;在中斷開始時記錄定時器的值…