C# | GDI+圖像測距輔助線的實現思路
文章目錄
- C# | GDI+圖像測距輔助線的實現思路
- 一、輔助線需求概述
- 二、坐標系與角度計算
- 2.1 笛卡爾坐標系
- 2.2 線長和角度計算方法
- 2.3 文本角度矯正計算方法
- 2.4 坐標變換實現步驟
- 三、與if判斷方式對比
- 四、總結
一、輔助線需求概述
在圖像測量工具中,動態輔助線的數值標簽需要滿足兩個核心要求:其一,標簽方向需與輔助線走向保持一致;其二,無論輔助線處于何種角度,文本必須保持正面朝上顯示。
二、坐標系與角度計算
2.1 笛卡爾坐標系
在屏幕坐標系中,Y軸方向與數學坐標系相反(向下為正方向)。兩點間連線形成的角度范圍在-π到π之間,對應屏幕空間的360度方向。
2.2 線長和角度計算方法
計算兩點之間的距離:
double length = Math.Sqrt(Math.Pow(endPoint.X - startPoint.X, 2) + Math.Pow(endPoint.Y - startPoint.Y, 2));
計算線的反正切值,Math.Atan2 返回的值在 (-π, π] 之間,用于表示線的方向:
double atan = Math.Atan2(endPoint.Y - startPoint.Y, endPoint.X - startPoint.X);
2.3 文本角度矯正計算方法
調整反正切值,以確保顯示的長度文本始終保持向上的方向。如果反正切值的絕對值大于 π/2,說明線的傾斜方向可能導致文本倒著顯示。
此時通過 -(Math.PI - atan) 來調整反正切值,使其對應的文本方向向上。
atan = Math.Abs(atan) > Math.PI / 2 ? -(Math.PI - atan) : atan;
2.4 坐標變換實現步驟
- 平移坐標系至線段中點
- 應用旋轉變換
- 垂直偏移避免覆蓋線段
關鍵代碼段:
// 計算中點位置
PointF midPoint = new PointF((startPoint.X + endPoint.X) / 2, (startPoint.Y + endPoint.Y) / 2);// 調整原點至兩點中心
g.TranslateTransform(midPoint.X, midPoint.Y);
g.RotateTransform((float)(atan * 180 / Math.PI));
三、與if判斷方式對比
使用if連環判斷不但啰嗦還存在除零風險。
if (deltaX >= 0 && deltaY >= 0) // 第一象限
{angle = Math.Atan(deltaY / deltaX);
}
else if (deltaX <= 0 && deltaY >= 0) // 第二象限
{angle = Math.PI - Math.Atan(deltaY / -deltaX);
}
// 三、四...
四、總結
通過坐標變換矩陣驗證法可檢測實現效果:
- 當輔助線處于水平方向(0度)時,旋轉角度為0
- 當輔助線垂直向上(-90度)時,實際應用90度旋轉
- 當輔助線傾斜135度時,自動校正為-45度顯示
綜上,在0-360度全范圍內均能保持文本正向顯示,感謝閱讀。