На самом деле не ожидаю от сюда большой помощи, но все же может кто-то знает что-то.
Делаю игру-рисовалку. Нужно реализовать нормальную заливку фигур.
Я использую что-то типа рекурсии и зарисовываю части не точками, а линиями.
В коде ниже я использую Unity3d, но там в принципе всё должно быть интуитивно понятно:
Код
void Fill(IntVector2 pos, Texture2D canvas, Color newColor)
{
// For speed control
float time = Time.realtimeSinceStartup;
int points=0;
// DEBUGGG
IntVector2 point;
Stack pixelStack = new Stack(); // point from where start filling
bool spanTop = false; // Does line above need to be filled?
bool spanBot = false; // below
Color oldColor = canvas.GetPixel(pos.x,pos.y); // Set color that will be replaced
pixelStack.Push(pos); // Start
while(pixelStack.Count>0) // Рекурсия
{
point = pixelStack.Pop() as IntVector2; // Get new point
spanBot = false; spanTop = false;
while(point.x>=0 && canvas.GetPixel(point.x,point.y)==oldColor) // FInd most left pixel
{
point.x--;
}
point.x++;
// Start fill line from left to right
while(point.x<canvas.width && canvas.GetPixel(point.x,point.y)==oldColor) // until we meet another pixel
{
canvas.SetPixel(point.x,point.y,newColor);
// Is there line above needs filling?
if(spanTop==false && point.y>0 && canvas.GetPixel(point.x,point.y-1)==oldColor)
{
IntVector2 newpoint = new IntVector2(point.x,point.y-1);
pixelStack.Push(newpoint); // add new point from where we will start fill line
spanTop = true;
points++; // for debug
} else if(spanTop==true && point.y>0 && canvas.GetPixel(point.x,point.y-1)!=oldColor) {
spanTop = false;
}
// Below?
if(spanBot==false && point.y<canvas.height && canvas.GetPixel(point.x,point.y+1)==oldColor)
{
IntVector2 newpoint = new IntVector2(point.x,point.y+1);
pixelStack.Push(newpoint);
spanBot = true;
points++; // for debug
} else if(spanBot==true && point.y<canvas.height && canvas.GetPixel(point.x,point.y+1)!=oldColor) {
spanBot = false;
}
point.x++; // next pixet left->right
}
}
time = time - Time.realtimeSinceStartup; // for debug
canvas.Apply(); // Change material (takes rly little time)
print("CalculateTime:"+(-time)+", points detected:"+points);
}
Разрешение полотна: 900х675
Первый тест:
Простое белое полотно
CalculateTime:0.7691972, points detected:674
Второй тест:
Очень сложная фигура, небольшая по площади
CalculateTime:0.3095117, points detected: 19011
(линии оказались быстрее чем точки, может прямоугольники быстрее линий? ;D)