Kom op, zo moeilijk is dat niet
Sorteer de punten eerst op de x-as, van links naar rechts, en voeg vervolgens de eerste twee punten aan je lijst toe. Zoals je aan je eigen plaatje al kunt zien, mag er, als je de lijn volgt, alleen een bocht naar rechts gemaakt worden. Zodra er ergens een bocht naar links voorkomt is het fout, en moet je een aantal punten verwijderen.
Dus je hebt al de 2 punten. Ga nu elke keer een punt toevoegen, en kijk hoe de bocht is over de laatste 3 punten in je lijst. Zolang er een bocht naar links is bij die laatste drie punten, dan moet je het een-na-laatste punt in je lijst verwijderen, totdat er dus een bocht naar rechts is, of totdat je nog maar 2 punten over hebt. Ga dan weer verder met het toevoegen.
Je hebt nu de hele bovenste rand van de convexe omhulling. De onderste rand gaat natuurlijk op dezelfde manier, maar dan van rechts naar links (de bochten blijven wel hetzelfde overigens)
Bepalen of een bochts naar links of naar rechts gaat kan heel simpel met behulp uitwendig product tussen 2 vectoren. In 3D, een uitwendig product tussen 2 vectoren geeft altijd een vector dat loodrecht staat op die 2 vectoren. Aangezien je 2D coordinaten gebruikt, betekent dat dat je altijd een vector terugkrijgt die door je scherm heen gaat. Oftewel, we zijn dan ook alleen maar geïnteresseerd in de z-coordinaat van het resultaat. Als de vector naar je toe gaat, dus een negatieve z, dan is er een bocht naar links. Bij een positieve z is er een bocht naar rechts. Als z=0, dan liggen de 3 punten op één lijn. Aangezien het middelste punt in dat geval dan óók op de convexe omhulling ligt, noemen we dat voor het gemak ook even rechtsom
Een heel verhaal, maar uiteindelijk komt het hier op neer:
code:
1
2
3
4
5
6
7
8
9
| bocht (p1, p2, p3)
{
v1 = p2 - p1;
v2 = p3 - p2;
if ((v1.x * v2.y - v1.y * v2.x) >= 0)
return RECHTSOM;
else
return LINKSOM;
} |