mirror of
https://github.com/lospec/pixel-editor.git
synced 2023-08-10 21:12:51 +03:00
Got back to BFS
This commit is contained in:
parent
bd1a806f11
commit
bb657976e8
@ -97,59 +97,87 @@ class LassoSelectionTool extends SelectionTool {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isBorderOfBox(pixel) {
|
||||||
|
return pixel[0] == this.boundingBox.minX || pixel[0] == this.boundingBox.maxX ||
|
||||||
|
pixel[1] == this.boundingBox.minY || pixel[1] == this.boundingBox.maxY;
|
||||||
|
}
|
||||||
|
|
||||||
|
visit(pixel, visited) {
|
||||||
|
let toVisit = [pixel];
|
||||||
|
let selected = [];
|
||||||
|
|
||||||
|
while (toVisit.length > 0) {
|
||||||
|
pixel = toVisit.pop();
|
||||||
|
selected.push(pixel);
|
||||||
|
visited.push(pixel);
|
||||||
|
|
||||||
|
let col = currFile.VFXLayer.context.getImageData(pixel[0], pixel[1], 1, 1).data;
|
||||||
|
if (col[3] == 255)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
let top, bottom, left, right;
|
||||||
|
if (pixel[1] > 0)
|
||||||
|
top = [pixel[0], pixel[1] - 1];
|
||||||
|
else
|
||||||
|
top = undefined;
|
||||||
|
|
||||||
|
if (pixel[0] > 0)
|
||||||
|
left = [pixel[0] - 1, pixel[1]];
|
||||||
|
else
|
||||||
|
left = undefined;
|
||||||
|
|
||||||
|
if (pixel[1] < currFile.canvasSize[1])
|
||||||
|
bottom = [pixel[0], pixel[1] + 1];
|
||||||
|
else
|
||||||
|
bottom = undefined;
|
||||||
|
|
||||||
|
if (pixel[0] < currFile.canvasSize[0])
|
||||||
|
right = [pixel[0] + 1, pixel[1]];
|
||||||
|
else
|
||||||
|
right = undefined;
|
||||||
|
|
||||||
|
if ((right != undefined && this.isBorderOfBox(right)) || (left != undefined && this.isBorderOfBox(left))
|
||||||
|
|| (top != undefined && this.isBorderOfBox(top)) || (bottom != undefined && this.isBorderOfBox(bottom)))
|
||||||
|
return [];
|
||||||
|
|
||||||
|
// The include problem: https://stackoverflow.com/questions/19543514/check-whether-an-array-exists-in-an-array-of-arrays
|
||||||
|
if (right != undefined && !visited.includes(right))
|
||||||
|
toVisit.push(right);
|
||||||
|
if (left != undefined && !visited.includes(left))
|
||||||
|
toVisit.push(left);
|
||||||
|
if (top != undefined && !visited.includes(top))
|
||||||
|
toVisit.push(top);
|
||||||
|
if (bottom != undefined && !visited.includes(bottom))
|
||||||
|
toVisit.push(bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
return selected;
|
||||||
|
}
|
||||||
|
|
||||||
getSelection() {
|
getSelection() {
|
||||||
let selected = [];
|
let selected = [];
|
||||||
|
let visited = [];
|
||||||
if (this.currentPixels.length <= 1){
|
if (this.currentPixels.length <= 1){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** I'm once again asking you to make a BFS
|
||||||
|
* - This time since I'm dumb check all pixels in the bounding box
|
||||||
|
* - Start a BFS: stop when you reach the border of the bounding box:
|
||||||
|
* - In that case all the pixels you visited aren't part of the selection
|
||||||
|
* - Also stop when you touch black:
|
||||||
|
* - If you haven't found the border of the bounding box, then all the pixels you visited
|
||||||
|
* are inside the selection
|
||||||
|
*/
|
||||||
|
|
||||||
for (let x=this.boundingBox.minX; x<this.boundingBox.maxX; x++) {
|
for (let x=this.boundingBox.minX; x<this.boundingBox.maxX; x++) {
|
||||||
for (let y=this.boundingBox.minY; y<this.boundingBox.maxY; y++) {
|
for (let y=this.boundingBox.minY; y<this.boundingBox.maxY; y++) {
|
||||||
let toCheck = [x, y];
|
if (!visited.includes([x, y])) {
|
||||||
let intersectionCount = 0;
|
let insidePixels = this.visit([x,y], visited);
|
||||||
|
|
||||||
if (!this.currentPixels.includes(toCheck)) {
|
for (let i=0; i<insidePixels; i++) {
|
||||||
for (let index = 1; index < this.currentPixels.length; index ++){
|
selected.push(insidePixels[i]);
|
||||||
let start = this.currentPixels[index - 1];
|
|
||||||
let end = this.currentPixels[index];
|
|
||||||
|
|
||||||
let ray = {Start: toCheck, End: [9999, 0]};
|
|
||||||
let segment = {Start: start, End: end};
|
|
||||||
let rayDistance = {
|
|
||||||
x: ray.End[0] - ray.Start[0],
|
|
||||||
y: ray.End[1] - ray.Start[1]
|
|
||||||
};
|
|
||||||
let segDistance = {
|
|
||||||
x: segment.End[0] - segment.Start[0],
|
|
||||||
y: segment.End[1] - segment.Start[1]
|
|
||||||
};
|
|
||||||
|
|
||||||
let rayLength = Math.sqrt(Math.pow(rayDistance.x, 2) + Math.pow(rayDistance.y, 2));
|
|
||||||
let segLength = Math.sqrt(Math.pow(segDistance.x, 2) + Math.pow(segDistance.y, 2));
|
|
||||||
|
|
||||||
if ((rayDistance.x / rayLength == segDistance.x / segLength) &&
|
|
||||||
(rayDistance.y / rayLength == segDistance.y / segLength))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
let T2 = (rayDistance.x * (segment.Start[1] - ray.Start[1]) + rayDistance.y * (ray.Start[0] - segment.Start[0])) / (segDistance.x * rayDistance.y - segDistance.y * rayDistance.x);
|
|
||||||
let T1 = (segment.Start[0] + segDistance.x * T2 - ray.Start[0]) / rayDistance.x;
|
|
||||||
|
|
||||||
//Parametric check.
|
|
||||||
if (T1 < 0) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
if (T2 < 0 || T2 > 1) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (isNaN(T1)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
intersectionCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (intersectionCount & 1)
|
|
||||||
selected.push(toCheck);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user