2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 Делоне триангуляция выпуклость
Сообщение25.04.2010, 17:57 
Всем привет!
Как найти граничные точки и достроить триангуляцию до выпуклой?
Вот что есть (на циферки можно не обращать внимания, это номера узлов и треугольников):
Изображение
Собственно, интересует, как найти эти самые граничные узлы. Сейчас в голову пришла сжимающаяся окружность, но это, наверное, уже слишком.
Делал сначала веером, потом перестраивал (по 09.pdf Скворцова).
Ручками не хочется достраивать, дальше планируется измельчение сетки.

 
 
 
 Re: Делоне триангуляция выпуклость
Сообщение26.04.2010, 04:47 
Аватара пользователя
Если к ребру примыкает только один треугольник, то ребро граничное. Концы граничных рёбер являются граничными узлами.

 
 
 
 Re: Делоне триангуляция выпуклость
Сообщение27.04.2010, 17:33 
точно, спасибо!!!
я сделал немного по-другому, учитывая веер:
1. Сначала все точки - граничные.
2. Проверяем последовательно для каждых 3 точек границы условие выпуколсти.
3. Если не выполняется - добавляем треугольник, убираем среднюю с границы и шагаем на 2 дальше. Если выполняется, шагаем на 1 точку дальше.
4. И так, пока еще добавляются треугольники при полном обходе границы.

вот что получилось, если кому надо будет
Код:
typedef struct _Point {
   float x, y;
   double angle;
   int border;
} Point;

typedef struct _Triangle {
   int Node[3];
} Triangle;

Point    Node   [MAX_POINTS+1]   ;
Triangle Element[MAX_TRIANGLES+1];


Код:
inline double determ(int N1, int N2, int New)
{                  /* помогает определить, выпуклый ли кусок границы
                   * т.к. обход выполняется против ч/с, то если New
                   * лежит выше прямой по вектору N1->N2, определитель
                   * положителен, т.е. необходимо достраивать треугольник
                   */
   double det;
   det = (Node[New].x - Node[N1].x)*(Node[N2].y - Node[N1].y);
   det -= (Node[New].y - Node[N1].y)*(Node[N2].x - Node[N1].x);
   return det-1e-12; /* эту величину мы не учитываем при изгибе границы */
}

Код:
int FindNextBorder(int Start, int NumOfPoints)
{
   int i;
   for (i = Start; i < NumOfPoints; i++)
      if (Node[i].border)
         return i;
   return FindNextBorder(0, NumOfPoints); /* циклический поиск */
}

Код:
   UberTriangles = ~0;
   if (NumOfPoints > 3) {
      i = FindNextBorder(0  , NumOfPoints);
      j = FindNextBorder(i+1, NumOfPoints);
      k = FindNextBorder(j+1, NumOfPoints);
      do {
         if (i < j && j < k && i == FindNextBorder(0, NumOfPoints) &&
         UberTriangles == NumOfTriangles)
            break;
         if (i < j && j < k && i == FindNextBorder(0, NumOfPoints))
                   UberTriangles = NumOfTriangles;
#ifdef DEBUGBORDER
            printf("BORDERTESTING: %u %u %u\n", i, j, k);
#endif
         if (determ(i, j, k) > 0) {
            Node[j].border = 0;
#ifdef DEBUGBORDER
            printf("BORDERTRIANGLE: %u %u %u\n", i, j, k);
#endif
            Element[NumOfTriangles].Node[0] = i;
            Element[NumOfTriangles].Node[1] = j;
            Element[NumOfTriangles].Node[2] = k;
            ++NumOfTriangles;
            i = k;
            j = FindNextBorder(i+1, NumOfPoints);
            k = FindNextBorder(j+1, NumOfPoints);
         } else {
            i = j;
            j = k;
            k = FindNextBorder(j+1, NumOfPoints);
         }
      } while (0 != 1);
   }

 
 
 [ Сообщений: 3 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group