You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript计算归一化角度相似度:基于朝向的0-1评分实现方案

角度朝向相似度计算实现方案

问题根因

原有代码的问题是将角度差值除以360做归一化,而朝向的最大有效差异为180度(差值超过180度时实际为反向的更小夹角),因此会出现0°和90°、0°和270°计算结果相同的错误。

实现方案

方案1:线性相似度(差值与评分线性负相关)

逻辑:朝向完全相同时相似度为1,完全相反(差180度)时相似度为0,差值和评分呈线性负相关。
实现代码:

function modulo(x, y){
    return (x % y + y) % y;
}

function angleSimilarity(angle1, angle2) {
    let relativeAngle = angle2 - angle1;
    // 计算范围在-180~180之间的相对角度
    relativeAngle = modulo((relativeAngle + 180), 360) - 180;
    let diff = Math.abs(relativeAngle);
    // 最大差异180度对应相似度0,除以180做归一化
    const baseScore = 1 - (diff / 180);
    // 可选校准:如果需要10度差输出接近0.9的结果,可保留1位小数
    // return Number(baseScore.toFixed(1));
    return baseScore;
}

测试结果:

  • angleSimilarity(90, 100) ≈ 0.94,保留1位小数为0.9,符合示例要求
  • angleSimilarity(0, 90) = 0.5
  • angleSimilarity(0, 180) = 0(完全相反)

方案2:余弦相似度(更符合人眼感知)

逻辑:基于方向向量的点积计算,小角度差异时评分下降更慢,大角度差异时下降更快,更符合人对朝向接近程度的感知。
实现代码:

function angleSimilarity(angle1, angle2) {
    // 角度差转弧度
    const radDiff = (angle1 - angle2) * Math.PI / 180;
    // 余弦值映射到0~1区间
    return (Math.cos(radDiff) + 1) / 2;
}

如果需要匹配示例中红-绿相似度0.9、红-橙相似度0.8、相反朝向接近0.1的效果,可对结果做幂次调整:

function angleSimilarity(angle1, angle2) {
    const radDiff = (angle1 - angle2) * Math.PI / 180;
    const baseScore = (Math.cos(radDiff) + 1) / 2;
    // 调整幂次校准评分分布,数值越大小差异评分越高
    return Math.pow(baseScore, 3);
}

内容的提问来源于stack exchange,提问作者Ood

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 02:15:03