p5.js鼠标拖拽绘制连续线条异常问题求助
问题分析
你的代码只能生成离散点的核心原因是:mouseDragged函数仅更新当前鼠标帧所在的单个网格格子,但当鼠标移动速度较快时,相邻两帧的鼠标位置会跳过中间的格子,导致这些格子没有被填充,最终呈现离散点效果。
解决方案
要实现连续线条,需要记录鼠标拖拽的上一个网格位置,然后用**画线算法(如Bresenham算法)**计算出两个位置之间的所有网格点,逐个更新数组中的对应值。这样无论鼠标移动多快,路径上的所有格子都会被填充。
修改后的完整代码
let N = 64; let SCALE = 10; let arr = []; // 记录上一次的鼠标网格坐标 let prevGridX, prevGridY; function Index(N, i, j) { return i + j * N; } function Render() { for (let i = 0; i < N; i++) { for (let j = 0; j < N; j++) { let d = arr[Index(N, i, j)]; fill(d); noStroke(); square(i * SCALE, j * SCALE, SCALE); } } } // Bresenham算法:生成两个网格点之间的所有路径点 function drawLine(x0, y0, x1, y1) { let dx = Math.abs(x1 - x0); let dy = Math.abs(y1 - y0); let sx = x0 < x1 ? 1 : -1; let sy = y0 < y1 ? 1 : -1; let err = dx - dy; while (true) { // 确保坐标在网格范围内 if (x0 >= 0 && x0 < N && y0 >=0 && y0 < N) { arr[Index(N, x0, y0)] += 100; } if (x0 === x1 && y0 === y1) break; let e2 = 2 * err; if (e2 > -dy) { err -= dy; x0 += sx; } if (e2 < dx) { err += dx; y0 += sy; } } } function mousePressed() { // 初始化拖拽起点的网格坐标 prevGridX = Math.floor(mouseX / SCALE); prevGridY = Math.floor(mouseY / SCALE); } function mouseDragged() { let currentGridX = Math.floor(mouseX / SCALE); let currentGridY = Math.floor(mouseY / SCALE); // 绘制上一位置到当前位置的路径 drawLine(prevGridX, prevGridY, currentGridX, currentGridY); // 更新上一位置为当前位置 prevGridX = currentGridX; prevGridY = currentGridY; } function setup() { createCanvas(N * SCALE, N * SCALE); for (let i = 0; i < N; i++) { for (let j = 0; j < N; j++) { arr.push(0); } } } function draw() { background(0); Render(); }
关键修改说明
- 添加位置记录变量:
prevGridX和prevGridY用于存储上一帧的鼠标网格坐标,确保拖拽路径的连续性。 - Bresenham画线算法:
drawLine函数会计算两个网格点之间的所有中间点,逐个更新数组值,保证路径上的每个格子都被填充。 - 鼠标按下初始化:在
mousePressed中记录拖拽的起点,避免第一帧没有上一位置的问题。 - 边界检查:在更新数组时确保坐标在0到N-1之间,防止数组越界错误。
内容的提问来源于stack exchange,提问作者astle dsa
相关产品推荐
相关产品推荐

