В общем, пришел пока к следующему:
1. После обхода контура на выходе каждая фигура описана координатами первой точки и массивом байт, каждый из которых описывает следующую точку. В байте четыре значимых бита: влево, вправо, вниз, вверх. То есть, если следующая точка по диагонали вверх и влево, то установлены биты "вверх" и "влево".
- Код: Выделить всё
Private Enum V_UDLR
V_U = &H1 'up
V_L = &H2 'left
V_D = &H4 'down
V_R = &H8 'right
V_UL = V_U Or V_L
V_LD = V_L Or V_D
V_DR = V_D Or V_R
V_RU = V_R Or V_U
End Enum
То есть, каждая точка описана одним из восьми байтов. При таком подходе легко сравнивать участки контура с эталонами.
2. Теперь поиск вершин. Есть несколько сочетаний, которые заведомо вершины. Их совсем немного: U-D, UR-DR, R-D и ещё девять, им симметричных. Обычным InStrB ищу вхождение этих сочетаний в массив, описывающий фигуру. Несколько вершин у меня уже есть.
3. Если ни одной вершины не найдено, то значит контур довольно-таки округлый, плавный. Сравниваю с другими эталонами, которые могут быть вершинами, а могут и не быть. Получаю несколько точек с подозрением на вершины.
3. По алгоритму Брезенхэма строю эталонные отрезки между вершинами или подозреваемыми вершинами. При сбое алгоритма добавляю сбойную точку в список вершин и рекурсионно перепроверяю участок от точки до точки.
4. Если участок контура распадается на отрезки короче пяти точек, то считаю этот участок плавно изогнутым и добавляю в список вершин все точки, на которых изменилось направление.
Пока что контур масштабируется довольно угловато
И есть ещё несколько неучтенных вариантов.