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

JavaScript生成SVG星形多边形时数组规律性出现空项问题

更新位于文末!

SVG一笔画星形多边形生成程序(第一部分)

本程序仅支持单笔绘制完成的星形多边形(如五角星形Pentagram),不支持多图形组合生成的星形(如六角星Hexagram,需2个反向重叠三角形拼接)。
目前程序主体开发接近完成,运行可输出目标结果,但存在已知异常:生成的非因子数组每隔一项就会规律性出现空值,暂未定位原因。

模块功能说明

测试阶段会向控制台输出一个对象:

  • 对象的键为数字,对应正多边形的点数/边数
  • 每个键对应的值为数组,存储该数字下半区间的所有非因子数值,即键值除以数组内的数结果为分数
    输出对象示例
starPolygons {
  '5': [2],
  '7': [3,2],
  '8': [3],
  '9': [4,2],
  …
}

示例对应含义:正五边形、正七边形、正八边形、正九边形…对应的单笔星形绘制步长参数。

qty_test函数说明

函数接收正多边形点数,计算需要遍历的除数总数量:传入值先除以2,若结果为小数则返回向下取整的值,若结果为整数则返回结果减1。
初始化代码:

// 选8作为示例是因为其需要遍历的除数更多,现象更明显
// 正式遍历逻辑points初始值为5
let points = 8;
let starPolygons = {};

函数逻辑示例(传入值为8)

  1. 传入值8除以2得4
  2. 判断结果是否为整数
  3. 是整数则返回4-1=3,是小数则返回结果向下取整的值
    原函数代码:
function qty_test(n) {
    n /= 2;
    let divisorQTY = n - Math.floor(n) !== 0;
    return divisorQTY ? Math.floor(n) : (n - 1);
};

divisor_test函数说明

函数接收正多边形点数,遍历下半区间的所有除数,收集其中的非因子值存入数组返回。
判断规则:点数除以当前除数结果为小数时,该除数为非因子,存入数组后除数自减1;为整数时该除数是因子,直接跳过,除数自减1。
判断逻辑示例(点数为8)

  • 8 / 2 = 4,2是因子,忽略
  • 8 / 3 ≈ 2.667,3是非因子,收集
    原函数代码:
function divisor_test(n) {
    let nonFactors = [];
    n = qty_test(n);
    for (let index = 0; index <= n; index++) {
        let quotient = (points / n) - Math.floor(points / n) !== 0;
        quotient ? nonFactors[index] = n-- : --n;
    };
    return nonFactors;
};

遍历逻辑原代码

遍历5到360的所有点数,以点数为键、对应非因子数组为值,构建最终的星形参数对象输出到控制台。

while (points <= 360) {
    nonFactors = divisor_test(points);
    let testArray = nonFactors.length;
    if (testArray) starPolygons[String(points)] = nonFactors;
    points++;
};
console.log(starPolygons);

运行后可观察到数组空索引/空项呈固定规律分布,后续排查发现空槽的分布具备特殊特征,暂未定位成因。

异常原因

数组空槽是JavaScript稀疏数组的典型表现,由两处逻辑错误导致:

  1. 数组赋值时使用固定自增的index作为下标,遇到因子跳过赋值时,对应下标位置不会被填充,直接留空
  2. 循环判断条件index <= n中的n是动态自减的变量,会导致实际循环次数超出预期,产生多余空索引
    额外代码隐患:while循环中的nonFactors变量未声明,会泄露为全局变量;原循环逻辑会遍历到除数为0的情况,触发除零错误,可能引发其他不可预期的问题。

修复代码

移除多余的index计数,收集非因子时直接用push方法追加到数组,除数从计算得到的最大值向下遍历到2即可(1是所有正整数的因子,无需判断,0为非法除数),同时补全变量声明消除全局污染:

function qty_test(n) {
    n /= 2;
    return Number.isInteger(n) ? n - 1 : Math.floor(n);
}

function divisor_test(pointVal) {
    const nonFactors = [];
    // 除数从最大值向下遍历到2,避免除零错误、多余循环
    let currentDivisor = qty_test(pointVal);
    while (currentDivisor >= 2) {
        const isNonFactor = (pointVal / currentDivisor) % 1 !== 0;
        if (isNonFactor) {
            nonFactors.push(currentDivisor);
        }
        currentDivisor--;
    }
    return nonFactors;
}

// 遍历入口
let points = 5;
const starPolygons = {};
while (points <= 360) {
    const nonFactors = divisor_test(points);
    if (nonFactors.length) {
        starPolygons[String(points)] = nonFactors;
    }
    points++;
}
console.log(starPolygons);

修复后输出的数组无空槽,例如点数8对应输出[3],点数9对应输出[4,2],完全符合预期。

更新说明: 原问题中空槽的分布规律本质是:偶数边数的多边形下半区间因子占比高,跳过赋值的位置与赋值位置刚好交替,因此呈现隔一项空一项的现象;奇数边数的多边形因子占比低,空槽出现频率更低,与之前观察到的现象完全吻合。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 10:45:33