將目標畫布每個像素 反向投影 回源圖座標,避免「洞洞」與重疊。完整函數簽名:
void S_PicXZ(Graphics::TBitmap *Source, Graphics::TBitmap *NewPic, int angle);
if (angle > 180) angle = 360 - angle;
if (angle < -180) angle = 360 + angle;
float radians = (2 * 3.1416f * angle) / 360.0f;
float cosine = cosf(radians);
float sine = sinf(radians);
將角度限制在 [-180, 180],使用 cosf/sinf 單精度版本提升效能。
float p1x = -Source->Height * sine;
float p1y = Source->Height * cosine;
float p2x = Source->Width * cosine - Source->Height * sine;
float p2y = Source->Height * cosine + Source->Width * sine;
float p3x = Source->Width * cosine;
float p3y = Source->Width * sine;
對應源圖三個頂點(左下、右下、右上)旋轉後的位置;左上原點 (0,0) 旋轉不變。
float minx = min(0.0f, min(p1x, min(p2x, p3x)));
float miny = min(0.0f, min(p1y, min(p2y, p3y)));
float maxx = max(p1x, max(p2x, p3x));
float maxy = max(p1y, max(p2y, p3y));
int dstW, dstH;
if (angle > 90 && angle < 180) dstW = (int)ceil(-minx);
else dstW = (int)ceil(maxx - minx);
if (angle > -180 && angle < -90) dstH = (int)ceil(-miny);
else dstH = (int)ceil(maxy - miny);
NewPic->Width = dstW;
NewPic->Height = dstH;
根據象限調整寬高計算公式,確保畫布剛好容納旋轉後影像。
for (int x = 0; x < dstW; ++x) {
for (int y = 0; y < dstH; ++y) {
int srcX = (int)((x + minx) * cosine + (y + miny) * sine);
int srcY = (int)((y + miny) * cosine - (x + minx) * sine);
if (srcX >= 0 && srcX < Source->Width &&
srcY >= 0 && srcY < Source->Height) {
NewPic->Canvas->Pixels[x][y] = Source->Canvas->Pixels[srcX][srcY];
}
}
}
| 方向 | 做法 | 預期增益 |
|---|---|---|
| 像素存取 | 改用 ScanLine[] 取得行指標,避免 Pixels[][] 巨大開銷 |
10-50x |
| 插值升級 | 實作雙線性插值:取 4 點加權平均 | 畫質大幅提升 |
| SIMD/平行化 | OpenMP 平行化外層迴圈,或手寫 SSE/AVX 內聯 | 多核心線性加速 |
| 快速三角函數 | 查表或多項式近似替代 cosf/sinf |
微幅提升 |
// 假設 24-bit RGB
for (int y = 0; y < dstH; ++y) {
BYTE *dstRow = (BYTE*)NewPic->ScanLine[y];
for (int x = 0; x < dstW; ++x) {
int srcX = ...; int srcY = ...;
if (in_bounds) {
BYTE *srcRow = (BYTE*)Source->ScanLine[srcY];
dstRow[x*3+0] = srcRow[srcX*3+0]; // B
dstRow[x*3+1] = srcRow[srcX*3+1]; // G
dstRow[x*3+2] = srcRow[srcX*3+2]; // R
}
}
}
此函數展示了經典的「逆向映射 + 包絡盒計算」旋轉核心邏輯。實際專案中請務必:
ScanLine 存取像素TGPGraphics::RotateTransform (GDI+) 替代手寫,穩定且硬體加速