动态网格线计算:实现适配缩放的类GeoGebra网格间隔逻辑
原代码运行原理
你当前的代码逻辑本质是把缩放比例按2的幂次做阶梯式规整:
- 先计算
scale_x以2为底的对数并向下取整,得到当前缩放落在2的几次方区间 - 用100除以2的该次方,得到最终的网格间隔,所以间隔只会在100、50、25、12.5... 或者200、400、800...这类2的幂次相关的数值上跳变,不会出现其他数值
1/2/5规整网格间隔实现方案
你要的a*10^b(a∈{1,2,5})规则是可视化领域通用的轴刻度/网格规整算法,实现步骤如下:
- 先确定基准像素间隔:可以沿用你当前用的100,即缩放比例为1时,理想网格间隔为100像素
- 计算当前缩放对应的原始间隔:
raw_step = 基准像素间隔 / 缩放比例 - 对原始间隔做1/2/5归一化规整:
- 计算原始间隔的数量级:
b = Math.floor(Math.log10(raw_step)) - 把原始间隔缩放到[1,10)区间:
normalized_val = raw_step / (10 ** b) - 匹配到最近的1/2/5系数:
- normalized_val < 1.5 → a=1
- 1.5 ≤ normalized_val < 3.5 → a=2
- 3.5 ≤ normalized_val < 7.5 → a=5
- normalized_val ≥7.5 → a=1,b = b+1
- 最终网格间隔为
a * (10 ** b)
完整代码示例
// 通用网格间隔计算函数 function getGridStep(scale, basePixel = 100) { const rawStep = basePixel / scale; if (rawStep === 0) return basePixel; // 边界保护 // 计算数量级 const b = Math.floor(Math.log10(rawStep)); const magnitude = 10 ** b; const normalized = rawStep / magnitude; // 匹配1/2/5系数 let a; if (normalized < 1.5) { a = 1; } else if (normalized < 3.5) { a = 2; } else if (normalized < 7.5) { a = 5; } else { a = 1; return a * (10 ** (b + 1)); } return a * magnitude; } // 调用示例 var distance_x = getGridStep(scale_x); var distance_y = getGridStep(scale_y);
你可以调整basePixel参数修改默认的网格密度,数值越小网格越密,数值越大网格越疏。
内容的提问来源于stack exchange,提问作者Magnus Enebakk
相关产品推荐
相关产品推荐

