所有shape都转为run编码
转为run编码后再运算可以节约大量内存
subtractIntervals 函数的逻辑:目前的实现假设了所有的 subIntervals 都会与 intervals 完全重叠,这可能导致计算不准确。应该将 subIntervals 从 intervals 中去除时,考虑到可能的部分重叠。
差集计算:subtractIntervals 函数需要更准确地处理部分重叠和完整重叠的情况。
效果图
关键代码
/*** 绘制矩形* @param {CanvasRenderingContext2D} ctx - Canvas 2D 渲染上下文* @param {number[]} rect - 矩形 [x, y, width, height]* @param {string} color - 颜色*/function drawRect(ctx, rect, color) {ctx.fillStyle = color;ctx.fillRect(rect[0], rect[1], rect[2], rect[3]);}/*** 绘制 RLE 区域* @param {CanvasRenderingContext2D} ctx - Canvas 2D 渲染上下文* @param {Object[]} rle - RLE 区域数组* @param {string} color - 颜色*/function drawRLE(ctx, rle, color) {ctx.fillStyle = color;rle.forEach(({ row, intervals }) => {intervals.forEach(({ startCol, runLength }) => {ctx.fillRect(startCol, row, runLength, 1);});});}/*** 将矩形转换为 RLE 编码* @param {number[]} rect - 矩形 [x, y, width, height]* @returns {Object[]} - RLE 区域数组*/function rectangleToRLE(rect) {const [x, y, w, h] = rect;const rle = [];for (let i = y; i < y + h; i++) {rle.push({row: i,intervals: [{ startCol: x, runLength: w }]});}return rle;}/*** 计算两个 RLE 区域的交集* @param {Object[]} rle1 - 第一个 RLE 区域数组* @param {Object[]} rle2 - 第二个 RLE 区域数组* @returns {Object[]} - 交集 RLE 区域数组*/function intersectRLE(rle1, rle2) {const intersected = [];const rleMap = (rle) => {const map = new Map();rle.forEach(({ row, intervals }) => {if (!map.has(row)) {map.set(row, []);}map.get(row).push(...intervals);});return map;};const rleMap1 = rleMap(rle1);const rleMap2 = rleMap(rle2);const allRows = new Set(