<svg width="2838.739990" height="2482.179932" viewBox="0 0 2838.74 2482.18" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path id="矢量 12" d="M245.468 1782.95L238.376 1778.48C237.665 1778.04 237.458 1777.13 237.905 1776.42C238.352 1775.71 239.262 1775.5 239.973 1775.95L250.131 1782.33C250.842 1782.78 251.049 1783.69 250.601 2220.84Z" fill="#000000" fill-opacity="1.000000" fill-rule="evenodd"/>
</svg>
如上是一個svg 的path 路徑, 我們會遇到一個問題就是精度誤差
當圖形 移動 x,y / wh 內部的path 可能需要左上角對齊, 我們一偏移/或者矩陣運算
那么會有一定的精度誤差
比如 某個坐標點 1775.95 變為 1775.96 這種情況其實肉眼不可見
但是一些第三方的平臺會檢測到數值變動 例如 diff 或者 圖標上傳系統中
我明明沒有改變svg的數據 為啥變了個值啊 就攔截住了
我了解了一下原因 其實核心原因就在于 c/cpp 無法精確處理浮點數小數位的問題,我上篇文章也說了, 這種情況 sketch/figma pixso都會出現且做不到, mastergo 能做到是因為他對偏移舍棄了,無法保證外觀ui的一致性,所以這種方法不采納 如下圖
我們能做的就是減少誤差出現的幾率 要保證外觀的一致性
對精度進行小數位保留, 因為大部分誤差出現在 小數后第3 4 5 6位 , 正好寫入是string類型 我們直接截斷保留兩位小數就好了
我寫了個函數
// 對svg path路徑坐標進行2位小數保留
std::string formatSvgPath(const std::string& path) {if (path.empty())return "";std::string result;auto str = path;std::string number = "";while (str.size() > 0){auto c = str.front();str = str.erase(0, 1);if (std::isalpha(c) || std::isspace(c)) {if (!number.empty()) {std::istringstream iss(number);float f;iss >> f;double truncatedNumber = std::floor(f * 100) / 100; // 直接截斷小數部分std::ostringstream oss;oss << truncatedNumber;number = oss.str();}result += number;result += c;number.clear();}else {number += c;}}return result;
}