Zig-Zag Triangle Traversal mise en œuvre
Je tentais de suivre "On the Hardware Implementation of Triangle Traversal Algorithms for Graphics Processing" (Royer, Ituero, Lopez-Vallejo, & Barrio) (page 4) pour mettre en œuvre l'algorithme de traversal Zig-Zag pour triangle triversal/pixellisation. Cependant, l'explication dans le document est contre-intuitive pour moi et je n'étais pas capable de le faire fonctionner.
J'ai essayé de mettre en œuvre une machine à états finis mais je n'arrive pas à déterminer exactement les états exacts. Pour l'instant, j'ai (direction, e_1, e_2, e_3) où e_n représente la sortie du test de bord pour chaque arête. Pseudo:
if (right, true, true, true):
x++; // Move towards right
else if (left, true, true, true):
x--; // Move towards left
else:
// This is where I stuck. There should be two cases where in one of them
// y goes down and x doesn't change direction, in the other case x simply
// flips its direction. But I wasn't able to figure it out.
Toute aide serait appréciée!
Éditer: Mon effort jusqu'à présent: Alors que le test de bord fonctionne correctement, seulement quelques parties du graphique ont été pixellisées.
/// Zig Zag (not working)
int top_row = floor(fmin(y0, fmin(y1, y2)));
int bot_row = floor(fmax(y0, fmax(y1, y2)));
if (y0 > y1) {
swap(x0, x1); swap(y0, y1);
}
if (y0 > y2) {
swap(x0, x2); swap(y0, y2);
}
if (y1 > y2) {
swap(x1, x2); swap(y1, y2);
}
assert(top_row == floor(y0));
assert(bot_row == floor(y2));
bool direction = true;
bool changed = false;
int x = floor(x0); int y = floor(y0);
while (y <= bot_row) {
bool e1, e2, e3;
e1 = edge_test((float)x+0.5, (float)y+0.5, x0, y0, x1, y1) < 0.0f;
e2 = edge_test((float)x+0.5, (float)y+0.5, x1, y1, x2, y2) < 0.0f;
e3 = edge_test((float)x+0.5, (float)y+0.5, x2, y2, x0, y0) < 0.0f;
if ((e1 == e2) && (e2 == e3)) {
if (x < 0 || x >= width) continue;
if (y < 0 || y >= height) continue;
samplebuffer[y][x].fill_pixel(color);
if (direction) x++;
else x--;
} else if (changed) {
y++;
changed = false;
} else {
direction = !direction;
changed = true;
if (direction) x++;
else x--;
}
}
J'ai essayé de mettre en œuvre ce et il semble que cela fonctionne pour les cas communs. Cependant, pour certains cas de bord comme Imaginez deux pixels empilés verticalement, disons $ p_1 $, $ p_2 $, et le triangle est si mince que ses deux bords passent entre $ x_1 + 0.5, y_1 + 0.5 $ et $ x_2 + 0.5, y_2 + 0,5 $. Le test de bord des deux pixels échouera, et lorsque (x, y) passera de $ p_1 $ à $ p_2 $, state_1 est déclenché et la direction est inversée, ce qui peut amener x à s'éloigner du triangle. Comment puis-je faire face à cela? –