Итак, я написал функцию заливки заливкой, которая работает как инструмент ведра в приложении для рисования: вы щелкаете внутри замкнутой формы, и она заполняется цветом.
У меня две проблемы с этим:
производительность - допустим, мой холст имеет размер 600 * 600 (370000 пикселей), и я рисую на нем большой круг, который, например, имеет около 100 тыс. Пикселей, это может занять около 40 (!! !) секунд, чтобы заполнить этот круг! это безумие! Создание sqaure размером ровно 10 000 пикселей занимает в среднем 0,4-0,5 секунды, но (я полагаю), поскольку размеры массивов, используемых программой, так сильно растут, для заполнения sqaure, в 10 раз превышающего размер, требуется примерно в 100 раз больше длины.
в начинке есть что-то странное. Я не совсем уверен, как это происходит, но всегда остается несколько незаполненных пикселей. Совсем немного, но это действительно странно.
Моя функция заливки заливкой использует 4 вспомогательные функции: получение и установка цвета пикселя, проверка того, является ли цвет для заливки, и проверка того, является ли это пиксель, проверенный ранее. Вот все функции:
getPixelColor = (x, y) => {
let pixelColor = [];
for (let i = 0; i < pixDens; ++i) {
for (let j = 0; j < pixDens; ++j) {
index = 4 * ((y * pixDens + j) * width * pixDens + (x * pixDens + i));
pixelColor[0] = pixels[index];
pixelColor[1] = pixels[index + 1];
pixelColor[2] = pixels[index + 2];
pixelColor[3] = pixels[index + 3];
}
}
return pixelColor;
};
setPixelColor = (x, y, currentColor) => { //Remember to loadPixels() before using this function, and to updatePixels() after.
for (let i = 0; i < pixDens; ++i) {
for (let j = 0; j < pixDens; ++j) {
index = 4 * ((y * pixDens + j) * width * pixDens + (x * pixDens + i));
pixels[index] = currentColor[0];
pixels[index + 1] = currentColor[1];
pixels[index + 2] = currentColor[2];
pixels[index + 3] = currentColor[3];
}
}
}
isDuplicate = (posHistory, vector) => {
for (let i = 0; i < posHistory.length; ++i) {
if (posHistory[i].x === vector.x && posHistory[i].y === vector.y) {
return true;
}
}
return false;
}
compareColors = (firstColor, secondColor) => {
for (let i = 0; i < firstColor.length; ++i) {
if (firstColor[i] !== secondColor[i]) {
return false;
}
}
return true;
}
floodFill = () => {
loadPixels();
let x = floor(mouseX);
let y = floor(mouseY);
let startingColor = getPixelColor(x, y);
if (compareColors(startingColor, currentColor)) {
return false;
}
let pos = [];
pos.push(createVector(x, y));
let posHistory = [];
posHistory.push(createVector(x, y));
while (pos.length > 0) {
x = pos[0].x;
y = pos[0].y;
pos.shift();
if (x <= width && x >= 0 && y <= height && y >= 0) {
setPixelColor(x, y, currentColor);
let xMinus = createVector(x - 1, y);
if (!isDuplicate(posHistory, xMinus) && compareColors(getPixelColor(xMinus.x, xMinus.y), startingColor)) {
pos.push(xMinus);
posHistory.push(xMinus);
}
let xPlus = createVector(x + 1, y);
if (!isDuplicate(posHistory, xPlus) && compareColors(getPixelColor(xPlus.x, xPlus.y), startingColor)) {
pos.push(xPlus);
posHistory.push(xPlus);
}
let yMinus = createVector(x, y - 1);
if (!isDuplicate(posHistory, yMinus) && compareColors(getPixelColor(yMinus.x, yMinus.y), startingColor)) {
pos.push(yMinus);
posHistory.push(yMinus);
}
let yPlus = createVector(x, y + 1);
if (!isDuplicate(posHistory, yPlus) && compareColors(getPixelColor(yPlus.x, yPlus.y), startingColor)) {
pos.push(yPlus);
posHistory.push(yPlus);
}
}
}
updatePixels();
}
Я бы очень оценил, если бы кто-нибудь помог мне решить проблемы с функциями. Большое спасибо !!
РЕДАКТИРОВАТЬ: Итак, я обновил свою функцию заливки заливки и удалил массив цветов, который никогда не использовал. этот массив был довольно большим, и несколько методов pu sh () и shift () вызывали его практически при каждом запуске. К сожалению, время выполнения на 99,9% одинаково для небольших форм (например, заливка 10000 занимает те же 0,5 секунды, но большие заливки, такие как 100000 пикселей, теперь занимают около 30 секунд, а не 40, так что это шаг вправо Я предполагаю, что использование ОЗУ также снизилось, поскольку это был довольно большой массив, но я не измерял его. Странная проблема, когда остаются незаполненные пиксели, все еще существует.