<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;
}