Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Построение выпуклой оболочки в режиме реального времени / Doc / Построение выпуклой оболочки в реальном времени.doc
Скачиваний:
25
Добавлен:
01.05.2014
Размер:
783.87 Кб
Скачать

Список используемой литературы

[1] Ф. Препарата, М. Шеймос «Вычислительная геометрия. Введение», Москва, Мир, 1989

Приложение 1

Диаграмма классов

(классы, реализующие рандомизированное дерево)

Диаграмма классов

(классы, реализующие алгоритм построения ВО и интерфейс пользователя)

Приложение 2

Текст программы

Файл RandomizeNode.cpp

namespace RandomTree

{

template<class T> class RandomizeSearchTree;

/** Шаблон - узел рандомизированного дерева */

template<class T>

class RandomizeNode

{

typedef RandomizeNode<T> t_Node;

private:

RandomizeNode *p_parent; //указатель на родителя

RandomizeNode *p_lchild; //указатель на левое поддерево

RandomizeNode *p_rchild; // правое

RandomizeNode *p_next; //указатель на левое поддерево

RandomizeNode *p_prev; // правое

T *val; //значение узла

double m_dPriority; //приоритет узла

void rotateRight(void); //правый поворот узла

void rotateLeft(void); //левый поворот узла

public:

RandomizeNode(T *v, double k);

RandomizeNode(T *v);

RandomizeNode();

~RandomizeNode();

RandomizeNode *lchild(void);

RandomizeNode *rchild(void);

T *getVal();

void setVal(T* ttt)

{ val=ttt;}

RandomizeNode *next(void);

RandomizeNode *prev(void);

RandomizeNode *parent(void); //получить указатель на РОДИТЕЛЯ

RandomizeNode *minimum(void); //получить мин. элемент

void bubbleUp(RandomizeNode<T>** koren); //поднять узел вверх

void bubbleDown(RandomizeNode<T>** koren); //опустить узел вниз

double priority(void); //получить ПРИОРИТЕТ

RandomizeNode<T> *insertInList(RandomizeNode<T> *b);

void insertInSortList(RandomizeNode<T> *b);

RandomizeNode<T> *removeNodeOfList(void);

void removeNodeOfSortList(RandomizeNode<T> *b);

void replaceNodeInList(RandomizeNode<T> *b);

friend class RandomizeSearchTree<T>;

};

//конструктор

template<class T>

RandomizeNode<T>::RandomizeNode(T *v, double priority)

{

m_dPriority = priority;

val = new T(*v);

p_lchild = p_rchild = p_parent = NULL;

p_next = this;

p_prev = this;

}

template<class T>

RandomizeNode<T>::RandomizeNode(T *v)

{

RAND_MAX;

m_dPriority = (rand()%32767)/(32767.0);

val = new T(*v);

p_lchild = p_rchild = p_parent = NULL;

p_next = this;

p_prev = this;

}

template<class T>

RandomizeNode<T>::RandomizeNode()

{

m_dPriority = 0.0;

val = NULL;

p_lchild = p_rchild = p_parent = NULL;

p_next = NULL;

p_prev = NULL;

}

template<class T> RandomizeNode<T>::~RandomizeNode()

{

p_lchild = p_rchild = p_parent = NULL;

}

template<class T> T *RandomizeNode<T>::getVal(void)

{

return val;

}

//правый поворот узла

template<class T> void RandomizeNode<T>::rotateRight(void)

{

RandomizeNode<T> *y, *x, *p;

y = this;

x = y->lchild();

p = y->parent();

y->p_lchild = x->rchild();

if (y->lchild() != NULL)

y->lchild()->p_parent = y;

if (p != NULL)

{

if (p->rchild() == y)

p->p_rchild = x;

else

p->p_lchild = x;

}

x->p_parent = p;

x->p_rchild = y;

y->p_parent = x;

}

//левый поворот узла

template<class T> void RandomizeNode<T>::rotateLeft(void)

{

RandomizeNode<T> *x, *y, *p;

x = this;

y = x -> rchild();

p = x -> parent();

x->p_rchild = y->lchild();

if (x->rchild() != NULL)

x->rchild()->p_parent = x;

if (p != NULL)

{

if (p->lchild() == x)

p->p_lchild = y;

else

if (p->p_rchild == x)

p->p_rchild = y;

}

y->p_parent = p;

y->p_lchild = x;

x->p_parent = y;

}

//поднять узел

template<class T> void RandomizeNode<T>::bubbleUp(RandomizeNode<T>** koren)

{

RandomizeNode<T> *p, *cur;

cur = this;

p = parent();

if (p != NULL)

{

if (priority() > p->priority())

{

if (p->lchild() == this)

{

if (cur == *koren)

*koren = p->lchild();

p->rotateRight();

}

else

{

if (cur == *koren)

*koren = p->rchild();

p->rotateLeft();

}

bubbleUp(koren);

}

}

else

if (p == NULL)

*koren = cur;

}

template<class T> void RandomizeNode<T>::bubbleDown(RandomizeNode<T>** koren)

{

if ((lchild() == NULL) && (rchild() != NULL))

{

if (*koren == this)

*koren = rchild();

this->rotateLeft();

}

else

if ((rchild() == NULL) && (lchild() != NULL))

{

if (*koren == this)

*koren = lchild();

this->rotateRight();

}

else

if ((rchild() != NULL) && (lchild() != NULL))

{

if (lchild()->priority() < rchild()->priority())

{

if (*koren == this)

*koren = rchild();

this->rotateLeft();

}

else

{

if (*koren == this)

*koren = lchild();

this->rotateRight();

}

}

if ((lchild() != NULL) || (rchild() != NULL))

{

bubbleDown(koren);

}

}

/********************* Функции GET УЗЛА *********************/

template<class T> RandomizeNode<T> *RandomizeNode<T>::rchild(void)

{

return p_rchild;

}

template<class T> RandomizeNode<T> *RandomizeNode<T>::lchild(void)

{

return p_lchild;

}

template<class T> RandomizeNode<T> *RandomizeNode<T>::next(void)

{

return p_next;

}

template<class T> RandomizeNode<T> *RandomizeNode<T>::prev(void)

{

return p_prev;

}

template<class T> RandomizeNode<T> *RandomizeNode<T>::parent(void)

{

return p_parent;

}

template<class T> double RandomizeNode<T>::priority(void)

{

return m_dPriority;

}

template<class T> RandomizeNode<T> *RandomizeNode<T>::minimum(void)

{

RandomizeNode<T> *m=this;

if (m)

{

while (m->lchild())

{

m=m->lchild();

}

}

return m;

}

template<class T> RandomizeNode<T> *RandomizeNode<T>::insertInList(RandomizeNode<T> *b)

{

RandomizeNode<T> *c = p_next;

b->p_next = c;

b->p_prev = this;

p_next = b;

c->p_prev = b;

return b;

}

template<class T> void RandomizeNode<T>::insertInSortList(RandomizeNode<T> *b)

{

RandomizeNode<T> *c = minimum();

if (c->getVal() > b->getVal())

{

b->p_next = c;

b->p_prev = c->p_prev;

c->p_prev = b;

}

else

{

while (b->getVal() > c->getVal())

{

if ( c->getVal() != minimum()->getVal())

break;

c = c->p_next;

}

b->p_next = c;

b->p_prev = c->p_prev;

c->p_prev = b;

}

}

template<class T> RandomizeNode<T> *RandomizeNode<T>::removeNodeOfList(void)

{

p_prev->p_next = p_next;

p_next->p_prev = p_prev;

p_next = p_prev = this;

return this;

}

template<class T> void RandomizeNode<T>::removeNodeOfSortList(RandomizeNode<T> *b)

{

RandomizeNode<T> *c = minimum();

while (c->getVal() != b->getVal())

c = c->p_next;

c->removeNodeOfList();

}

template<class T> void RandomizeNode<T>::replaceNodeInList(RandomizeNode<T> *b)

{

RandomizeNode<T> *c = minimum();

RandomizeNode<T> *min = minimum();

do

{

c = c->p_next;

if ((*min->getVal()) > (*c->getVal()))

min = c;

} while (c != minimum());

c = min;

while ((*c->getVal()) < (*b->getVal()))

c = c->p_next;

RandomizeNode<T> *tmp = b;

b->p_prev->p_next = b->p_next;

b->p_prev = c->p_prev;

b->p_next = c;

c->p_prev->p_next = b;

c->p_prev = b;

}

}

Файл RandomizeSearchTree.cpp

#if !defined(__randomizesearchtree__)

#define __randomizesearchtree__

#endif

#include "stdafx.h"

#include "RandomizeNode.cpp"

#include <list>

namespace RandomTree

{

using namespace std;

/** Система классов исключений */

class treeException

{

public:

virtual char* get_comment()

{

return "Ошибка в дереве";

}

};

class out_of_bounds:public treeException

{ protected:

char comment[100];

public:

out_of_bounds()

{ memset(comment,0,100);}

out_of_bounds(char *c)

{ memset(comment,0,100);

memcpy(comment,c,strlen(c)>(100-1)?(100-1):strlen(c));

}

virtual char* get_comment()

{

return comment;

}

};

class no_defined_iter:public treeException

{ protected:

char comment[100];

public:

no_defined_iter()

{ memset(comment,0,100);}

no_defined_iter(char *c)

{ memset(comment,0,100);

memcpy(comment,c,strlen(c)>(100-1)?(100-1):strlen(c));

}

virtual char* get_comment()

{

return comment;

}

};

class out_of_memory:public treeException

{ protected:

char comment[100];

public:

out_of_memory()

{ memset(comment,0,100);}

out_of_memory(char *c)

{ memset(comment,0,100);

memcpy(comment,c,strlen(c)>(100-1)?(100-1):strlen(c));

}

virtual char* get_comment()

{

return comment;

}

};

/************** РАНДОМИЗИРОВАННОЕ ДЕРЕВО **************/

template <class T> class RandomizeSearchTree

{

private:

int cmp (T *a, T *b);

void removeRandomizeNode(RandomizeNode<T>*); //удалить узел дерева

RandomizeNode<T> *win; //текущий элемнент списка

RandomizeNode<T> *root; //корень дерева

RandomizeNode<T> *max; //МАКСимальный элемент дерева

RandomizeNode<T> *min; //МИНимальный элемент дерева

typedef const RandomizeSearchTree<T> t_constTree;

typedef RandomizeSearchTree<T> t_noconstTree;

private:

/*Шаблон итератора по дереву

_Tree - контейнер

_Node - тип возвращаемый опреатором * и -> (узел дерева)

*/

template<class _Tree,class _Node>

class tree_iterator

{

typedef tree_iterator<_Tree,_Node> t_iterator;

typedef tree_iterator<t_noconstTree,_Node> t_noconst_iterator;

typedef tree_iterator<t_constTree,_Node> t_const_iterator;

_Tree *p_cont_tree; //указатель на контейнер

_Node *cur; //текущий узел

public:

//конструктор по умолчанию

tree_iterator():p_cont_tree(NULL)

{

}

//конструктор

tree_iterator(_Tree &t, _Node &el)

{

p_cont_tree = &t;

cur = &el;

}

//опрератор преобразования типа в iter_type_const

operator t_const_iterator()

{

return t_const_iterator(*p_cont_tree,cur);

}

// оператор =

void operator = (t_iterator& temp)

{

p_cont_tree = temp.p_cont_tree;

cur = temp.cur;

}

//оператор *

_Node* operator* ()

{

return cur;

}

// оператор ->

_Node* operator-> ()

{

return &*cur;

}

private:

// получить левое поддерево

_Node* getLeftChild()

{

return cur->lchild();

}

// получить правое поддерево

_Node* getRightChild()

{

return cur->rchild();

}

// получить родителя

_Node* getParent()

{

return cur->parent();

}

// получить левое поддерево

_Node* getNext()

{

return cur->next();

}

// получить правое поддерево

_Node* getPrev()

{

return cur->prev();

}

public:

// переход на левое поддерево

t_iterator& toLeft()

{

if (p_cont_tree == NULL) throw no_defined_iter("Не определен итератор для дерева!");

if (getLeftChild() == NULL) throw out_of_bounds("Попытка перейти к несуществующему узлу!");

cur = getLeftChild();

return *this;

}

// переход на правое поддерево

t_iterator& toRight()

{

if (p_cont_tree == NULL) throw no_defined_iter("Не определен итератор для дерева!");

if (getRightChild() == NULL) throw out_of_bounds("Попытка перейти к несуществующему узлу!");

cur = getRightChild();

return *this;

}

// переход к родителю

t_iterator& toParent()

{

if (p_cont_tree == NULL) throw no_defined_iter("Не определен итератор для дерева!");

if (getParent() == NULL) throw out_of_bounds("Попытка перейти к несуществующему узлу!");

cur = getParent();

return *this;

}

// оператор ++

// переход на узел, следующий за текущим

t_iterator& operator++()

{

if (p_cont_tree == NULL) throw no_defined_iter("Не определен итератор для дерева!");

try

{

cur = getNext();

}

catch (...)

{

throw out_of_bounds("Попытка перейти к несуществующему узлу!");

}

return *this;

}

// оператор --

// переход на узел, предыдущий текущему

t_iterator& operator--()

{

if (p_cont_tree == NULL) throw no_defined_iter("Не определен итератор для дерева!");

try

{

cur = getPrev();

}

catch (...)

{

throw out_of_bounds("Попытка перейти к несуществующему узлу!");

}

return *this;

}

bool equals (const t_iterator &t1)

{

return (cur==t1.cur &&

p_cont_tree==t1.p_cont_tree);

}

// оператор ==

friend bool operator == (const t_iterator &t1,const t_iterator& t2)

{

return (t1.cur==t2.cur &&

t1.p_cont_tree==t2.p_cont_tree);

}

// оператор !=

friend bool operator != (const t_iterator &t1,const t_iterator& t2)

{

return !(t1.cur==t2.cur &&

t1.p_cont_tree==t2.p_cont_tree);

}

};

public:

typedef RandomizeNode<T> t_node;

typedef RandomizeSearchTree<T> t_rst;

//Итератор по дереву

typedef tree_iterator<t_noconstTree,t_node> iterator;

//Константный итератор по дереву

typedef tree_iterator<t_constTree,t_node> const_iterator;

RandomizeSearchTree();

virtual ~RandomizeSearchTree(void);

// ФУНКЦИИ

RandomizeNode<T> *find_elem(T *);

void modify();

//вставить новый узел с приоритетом в дерево

void insert(T *, double k, bool needModify = true);

//вставить узел со случайным приоритетом в дерево

void insert(T *val);

//вставить элемент в упорядоченный список

void insertInList(RandomizeNode<T> *val);

//удалить элемент из списока

void removeFromList(RandomizeNode<T> *val);

void replaceNodeInList(RandomizeNode<T> *val);

//удалить

virtual void remove(void);

//удалить узел

T *remove(T *);

//удалить все поддеревья дерева

void deleteChildren(RandomizeNode<T> *p_rn);

//удалить всё дерево

void clear();

T *next(void);

T *prev(void);

T *roundnext(void);

T *roundprev(void);

T *val(void);

int isFirst(void);

int isLast(void);

int isHead(void);

int isEmpty(void);

T *findMin(void);

RandomizeNode<T> *getWin(); //текущий элемнент списка

RandomizeNode<T> *getRoot(); //корень дерева

RandomizeNode<T> *getMax(); //МАКСимальный элемент дерева

RandomizeNode<T> *getMin(); //МИНимальный элемент дерева

void setWin(RandomizeNode<T> *); //текущий элемнент списка

void setRoot(RandomizeNode<T> *); //корень дерева

void setMax(RandomizeNode<T> *); //МАКСимальный элемент дерева

void setMin(RandomizeNode<T> *); //МИНимальный элемент дерева

iterator begin()

{

return iterator(*this, *root->minimum());

}

//Возвращает константный итератор, указывающий на начало списка

const_iterator begin() const

{

return const_iterator(*this, *root->minimum());

}

//Возвращает итератор, указывающий на конец списка

iterator end()

{

return iterator(*this, *root->minimum()->prev());

}

//Возвращает константный итератор, указывающий на конец списка

const_iterator end() const

{

return const_iterator(*this, *root->minimum()->prev());

}

//Возвращает итератор, указывающий на нужный элемент

iterator find(T* t)

{

return iterator(*this,*find_elem(t));

}

//Возвращает константный итератор, указывающий на нужный элемент

const_iterator find(const T* t) const

{

return const_iterator(*this,*find_elem(t));

}

//Возвращает количество узлов

int size()

{

int count = 0;

iterator tmp, tek;

if (root != NULL)

{

tmp = begin();

do

{

count++;

++tmp;

} while ((*tmp)->getVal() != (*(begin()))->getVal());

}

return count;

}

int depthOfTree(RandomizeNode<T> *uz, int count, int tmp_count)

{

if (uz != NULL)

{

tmp_count++;

if (uz->lchild() !=NULL)

count = depthOfTree(uz->lchild(), count, tmp_count);

if (uz->rchild() !=NULL)

count = depthOfTree(uz->rchild(), count, tmp_count);

}

if (tmp_count > count)

count = tmp_count;

tmp_count--;

return count;

}

//Возвращает глубину дерева

int depthOfTree(RandomizeNode<T> *tt)

{ if (!tt) return -1;

return depthOfTree(tt, 0, 0);

}

};

//Конструктор

template<class T>

RandomizeSearchTree<T>::RandomizeSearchTree(/*int seed = -1*/)

{

win = NULL;

root = NULL;

min = NULL;

max = NULL;

}

// Деструктор

template<class T>

RandomizeSearchTree<T>::~RandomizeSearchTree(void)

{

clear();

win = NULL;

min = NULL;

max = NULL;

}

//удалить все поддеревья дерева

template<class T>

void RandomizeSearchTree<T>::deleteChildren(RandomizeNode<T> *p_rn)

{

if (p_rn == NULL)

return;

if (p_rn->getVal())

delete p_rn->getVal();

if (p_rn->lchild())

{

deleteChildren(p_rn->lchild());

delete p_rn->lchild();

}

if (p_rn->p_rchild)

{

deleteChildren(p_rn->rchild());

delete p_rn->rchild();

}

}

//удалить все дерево

template<class T>

void RandomizeSearchTree<T>::clear()

{

if (root)

{

deleteChildren(root);

delete root;

root = NULL;

}

}

template<class T>

int RandomizeSearchTree<T>::cmp (T *a, T *b)

{

return (*a) < (*b) ? -1 : (*a) > (*b) ? 1 : 0;

}

// изменить структуру дерева, чтобы существовал левый сын у корня

template<class T> void RandomizeSearchTree<T>::modify()

{

RandomizeNode<T> *ch = root->rchild();

double pri=root->m_dPriority;

if (root->rchild() != NULL && root->lchild() == NULL)

{

root->m_dPriority = ch->m_dPriority;

ch->m_dPriority = pri;

ch->bubbleUp(&root);

}

}

//Вставить новый узел со случайным приоритетом в дерево

template<class T> void RandomizeSearchTree<T>::insert(T *val)

{

insert(val, -1.0);

}

//Вставить новый узел с приоритетом в дерево

template<class T> void RandomizeSearchTree<T>::insert(T *val, double priority, bool needModify)

{

RandomizeNode<T> *p;

p = getRoot();

if ( p == NULL) //вставка первого элемента в дерево

{

if (priority == -1.0)

win = new RandomizeNode<T>(val);

else

win = new RandomizeNode<T>(val, priority);

root = win;

min = max = root;

root->insertInList(win);

}

else //вставка i-ого элемента в дерево

{

int result = 1;

bool flag = true;

if (priority == -1.0)

win = new RandomizeNode<T>(val);

else

win = new RandomizeNode<T>(val, priority);

while (flag)

{

result = cmp(val, p->val);

if (result<0)

{

if (p->lchild() == NULL)

flag = false;

else

p = p->lchild();

}

else

if (result>0)

{

if (p->rchild() == NULL)

flag = false;

else

p = p->rchild();

}

else

return;

}

win -> p_parent = p;

if (result < 0) //вставить в ЛЕВОЕ поддерево

{

p->p_lchild = win;

p->prev()->insertInList(win);

}

else

if (result > 0) //вставить в ПРАВОЕ поддерево

{

p->p_rchild = win;

p->insertInList(win);

}

win->bubbleUp(&root);

result = cmp(val, min->val);

if ( result < 0 )

min = win;

result = cmp(val, max->val);

if ( result > 0 )

max = win;

if (needModify)

modify(); //если левое поддерево пусто, то сделать его непустым

}

}

//Удалить

template<class T> void RandomizeSearchTree<T>::remove(void)

{

if ( win != root )

removeRandomizeNode(win);

}

//удалить узел дерева

template<class T> void RandomizeSearchTree<T>::removeRandomizeNode(RandomizeNode<T> *n)

{

if (n !=NULL)

{

if ((n->lchild() == NULL) && (n->rchild() == NULL))

{

RandomizeNode<T> *p = n->parent();

if (p->lchild() == n)

p->p_lchild = NULL;

else

p->p_rchild = NULL;

n->removeNodeOfList();

if (win == n)

win = n->prev();

if (n == min)

min = n->next();

if (n == max)

max = n->prev();

if (n->val)

{

delete n->val;

n->val = NULL;

}

if (root == n)

root = min = max = win = NULL;

delete n->val;

delete n;

return;

}

n->m_dPriority = -1;

n->bubbleDown(&root);

RandomizeNode<T> *p = n->parent();

if (p->lchild() == n)

p->p_lchild = NULL;

else

p->p_rchild = NULL;

if (win == n)

win = n->prev();

if (n == min)

min = n->next();

if (n == max)

max = n->prev();

if (n->val)

{

delete n->val;

n->val = NULL;

}

n->removeNodeOfList();

if (n)

{

delete n;

n = NULL;

}

}

}

//найти значение узла в дереве

template<class T> RandomizeNode<T>/*T*/ *RandomizeSearchTree<T>::find_elem(T *val)

{

int result;

RandomizeNode<T> *n = root;

while (n)

{

result = cmp(val, n->getVal());

if ( result < 0 )

n = n->lchild();

else

if ( result > 0 )

n = n->rchild();

else

if (result == 0)

{

return n;

}

}

return NULL; //такого значения узла в дереве нет

}

//удалить узел, если известно его значение

template<class T> T *RandomizeSearchTree<T>::remove(T *val)

{

RandomizeNode<T> *p_deleted = NULL;

p_deleted = find_elem (val);

if (p_deleted != NULL)

removeRandomizeNode(p_deleted);

return NULL;

}

/********************* Функции GET ДЕРЕВА *********************/

//получить следующий

template<class T> T *RandomizeSearchTree<T>::next(void)

{

win = win -> next();

return win->val;

}

//получить предыдущий

template<class T> T *RandomizeSearchTree<T>::prev(void)

{

win = win -> prev();

return win->val;

}

template<class T> T *RandomizeSearchTree<T>::roundnext(void)

{

if(win == max)

return min->val;

else

return win -> next()->val;

}

template<class T> T *RandomizeSearchTree<T>::roundprev(void)

{

if(win == min)

return max->val;

else

return win -> prev()->val;

}

//получить значение

template<class T> T *RandomizeSearchTree<T>::val(void)

{

return win->val;

}

template<class T> int RandomizeSearchTree<T>::isFirst(void)

{

return (win == root->next()) && (root!=root->next());

}

template<class T> int RandomizeSearchTree<T>::isLast(void)

{

return (win == root->prev()) && (root!=root->next());

}

template<class T> int RandomizeSearchTree<T>::isHead(void)

{

return (win == root);

}

template<class T> int RandomizeSearchTree<T>::isEmpty(void)

{

return (root == root->next() );

}

template<class T> T *RandomizeSearchTree<T>::findMin(void)

{

win = root->next();

return win->val;

}

template<class T> RandomizeNode<T> *RandomizeSearchTree<T>::getWin() //текущий элемнент списка

{

return win;

}

template<class T> RandomizeNode<T> *RandomizeSearchTree<T>::getRoot() //корень дерева

{

return root;

}

template<class T> RandomizeNode<T> *RandomizeSearchTree<T>::getMax() //МАКСимальный элемент дерева

{

return max;

}

template<class T> RandomizeNode<T> *RandomizeSearchTree<T>::getMin() //МИНимальный элемент дерева

{

return min;

}

template<class T> void RandomizeSearchTree<T>::setWin(RandomizeNode<T> *w) //текущий элемнент списка

{

win = w;

}

template<class T> void RandomizeSearchTree<T>::setRoot(RandomizeNode<T> *r) //корень дерева

{

root = r;

}

template<class T> void RandomizeSearchTree<T>::setMax(RandomizeNode<T> *m) //МАКСимальный элемент дерева

{

max = m;

}

template<class T> void RandomizeSearchTree<T>::setMin(RandomizeNode<T> *m) //МИНимальный элемент дерева

{

min = m;

}

template<class T> void RandomizeSearchTree<T>::insertInList(RandomizeNode<T> *val)

{

win->insertInSortList(val);

}

template<class T> void RandomizeSearchTree<T>::removeFromList(RandomizeNode<T> *val)

{

win->removeNodeOfSortList(val);

}

template<class T> void RandomizeSearchTree<T>::replaceNodeInList(RandomizeNode<T> *val)

{

win->replaceNodeInList(val);

}

}

Файл CHRealTimeView.cpp

/** Опорная ли точка */

bool IsAbutment(CPoint v1,CPoint v,CPoint v2,CPoint p)

{

if (v.x != p.x)

{

double K = (double)(((double)v.y - (double)p.y)/((double)v.x - (double)p.x));

double B = (double)((double)p.y - K*(double)p.x);

if (((p.y == v.y) && (p.y == v2.y)) && (((p.x > v.x) && (p.x > v2.x)) ||((p.x < v.x) && (p.x < v2.x))))

if (abs(p.x - v.x) > abs(p.x - v2.x))

return false;

else

if (((p.x == v.x) && (p.x == v2.x)) && (((p.y > v.y) && (p.y > v2.y)) ||((p.y < v.y) && (p.y < v2.y))))

if (abs(p.y - v.y) > abs(p.y - v2.y))

return false;

else

if (((p.y == v.y) && (p.y == v1.y)) && (((p.x > v.x) && (p.x > v1.x)) ||((p.x < v.x) && (p.x < v1.x))))

if (abs(p.x - v.x) > abs(p.x - v1.x))

return false;

else

if (((p.x == v.x) && (p.x == v1.x)) && (((p.y > v.y) && (p.y > v1.y)) ||((p.y < v.y) && (p.y < v1.y))))

if (abs(p.y - v.y) > abs(p.y - v1.y))

return false;

return (v1.y >= (K*v1.x + B)) && (v2.y >= (K*v2.x + B)) || (v1.y <= (K*v1.x + B)) && (v2.y <= (K*v2.x + B));

}

else

{

if (((p.y == v.y) && (p.y == v2.y)) && (((p.x > v.x) && (p.x > v2.x)) ||((p.x < v.x) && (p.x < v2.x))))

if (abs(p.x - v.x) > abs(p.x - v2.x))

return false;

else

if (((p.x == v.x) && (p.x == v2.x)) && (((p.y > v.y) && (p.y > v2.y)) ||((p.y < v.y) && (p.y < v2.y))))

if (abs(p.y - v.y) > abs(p.y - v2.y))

return false;

else

if (((p.y == v.y) && (p.y == v1.y)) && (((p.x > v.x) && (p.x > v1.x)) ||((p.x < v.x) && (p.x < v1.x))))

if (abs(p.x - v.x) > abs(p.x - v1.x))

return false;

else

if (((p.x == v.x) && (p.x == v1.x)) && (((p.y > v.y) && (p.y > v1.y)) ||((p.y < v.y) && (p.y < v1.y))))

if (abs(p.y - v.y) > abs(p.y - v1.y))

return false;

return (v1.x >= v.x && v2.x >= v.x) || (v1.x <= v.x && v2.x <= v.x);

}

}

/** Выпуклая ли точка */

bool IsConvex(CPoint v1,CPoint v,CPoint v2,CPoint p)

{

int t1=v1.x*v.y+v1.y*v2.x+v.x*v2.y-v.y*v2.x-v.x*v1.y-v1.x*v2.y;

int t2=v1.x*p.y+v1.y*v.x+p.x*v.y-p.y*v.x-p.x*v1.y-v1.x*v.y;

if (((p.y == v.y) && (p.y == v2.y)) && (((p.x > v.x) && (p.x > v2.x)) ||((p.x < v.x) && (p.x < v2.x))))

if (abs(p.x - v.x) > abs(p.x - v2.x))

return false;

else

if (((p.x == v.x) && (p.x == v2.x)) && (((p.y > v.y) && (p.y > v2.y)) ||((p.y < v.y) && (p.y < v2.y))))

if (abs(p.y - v.y) > abs(p.y - v2.y))

return false;

else

if (((p.y == v.y) && (p.y == v1.y)) && (((p.x > v.x) && (p.x > v1.x)) ||((p.x < v.x) && (p.x < v1.x))))

if (abs(p.x - v.x) > abs(p.x - v1.x))

return false;

else

if (((p.x == v.x) && (p.x == v1.x)) && (((p.y > v.y) && (p.y > v1.y)) ||((p.y < v.y) && (p.y < v1.y))))

if (abs(p.y - v.y) > abs(p.y - v1.y))

return false;

return (t1>0 && t2>=0) || (t1<0 && t2<=0);

}

/** Выпуклый ли угол */

bool IsConvexAngle(CPoint m,CPoint M,CPoint p)

{

return (m.x-p.x)*(M.y-p.y)-(m.y-p.y)*(M.x-p.x)<0;

}

// создать выпуклую оболочку

void CCHRealTimeView::Create_Convex_hull(CPoint point)

{

Deleted.clear();

DeleteTree(tree);

tree = MakeTree(NULL,RST.getRoot());

MakeNext(tree,tree,tree);

MakePrev(tree);

l = NULL;

r = NULL;

for(vector<StepStruct *>::iterator i = stepstruct.begin(); i != stepstruct.end(); i++) if((*i)) delete (*i);

stepstruct.clear();

situation.clear();

if(Search(RST.getRoot(),tree,point))

{

StepStruct *ss=new StepStruct(ltree,rtree,situation[situation.size()-1],4);

stepstruct.push_back(ss);

TPoint *tp;

RandomizeNode<TPoint> *temp;

if(r->getVal()->getID() > l->getVal()->getID())

{

temp=l->next();

while(temp!=r)

{

RST.setWin(temp);

temp=temp->next();

Deleted.push_back(RST.getWin()->getVal()->getID());

RST.remove(RST.getWin()->getVal());

}

int dif=l->getVal()->getID() - r->getVal()->getID()+2; //+2

temp=r;

// перенумеровка вершин выпуклой оболочки

dif = 2;

do

{

temp->getVal()->setID(dif);

temp=temp->next();

dif++;

} while(temp!=r);

tp=new TPoint(1,point.x,point.y);

TPoint r_temp(*r->getVal());

TPoint l_temp(*l->getVal());

RandomizeSearchTree<TPoint> TempTree;

t_TreeIter it = RST.begin();

try

{

for (int i = 0; i < RST.size(); i++)

{

TPoint *qqq = (*it)->getVal();

double www = (*it)->priority();

TempTree.insert((*it)->getVal(),(*it)->priority(), false);

++it;

}

}

catch(treeException& ex)

{

AutoSave(true);

AfxMessageBox(ex.get_comment());

return;

}

RST.clear();

try

{

it = TempTree.begin();

for (int i = 0; i < TempTree.size(); i++)

{

RST.insert((*it)->getVal(),(*it)->priority(), false);

++it;

}

}

catch(treeException& ex)

{

AutoSave(true);

AfxMessageBox(ex.get_comment());

return;

}

it = RST.find(&r_temp);

r = (*it);

it = RST.find(&l_temp);

l = (*it);

RST.insert(tp);

}

else {

temp = l->next();

while(temp!=r) {

RST.setWin(temp);

temp=temp->next();

Deleted.push_back(RST.getWin()->getVal()->getID());

RST.remove(RST.getWin()->getVal());

}

int dif=2 - r->getVal()->getID();

temp=r;

dif = 2;

do

{

temp->getVal()->setID(dif);

temp=temp->next();

dif++;

} while(temp!=r);

tp=new TPoint(1,point.x,point.y);

TPoint r_temp(*r->getVal());

TPoint l_temp(*l->getVal());

RandomizeSearchTree<TPoint> TempTree;

t_TreeIter it = RST.begin();

try

{

for (int i = 0; i < RST.size(); i++)

{

TempTree.insert((*it)->getVal(),(*it)->priority(), false);

++it;

}

RST.clear();

it = TempTree.begin();

for (i = 0; i < TempTree.size(); i++)

{

RST.insert((*it)->getVal(),(*it)->priority(), false);

++it;

}

}

catch(treeException& ex)

{

AutoSave(true);

AfxMessageBox(ex.get_comment());

return;

}

it = RST.find(&r_temp);

r = (*it);

it = RST.find(&l_temp);

l = (*it);

RST.insert(tp);

}

}

CurrNode=RST.getRoot();

// вывод в файл всех вершин дерева с использованием манипулятора

ofstream fout;

fout.open("print_man.txt");

fout<<(RST);

fout.close();

if(!Animation) {

DrawPoints();

DrawTree();

} else

NextStep();

}

/** Левый поиск */

RandomizeNode<TPoint> * CCHRealTimeView::Left_Search(RandomizeNode<TPoint> *root, TTree *troot, CPoint p)

{

RandomizeNode<TPoint> *l;

RandomizeNode<TPoint> *RN;

TTree *treeTree;

RST.setWin(root);

CPoint v1(RST.roundprev()->getX(),RST.roundprev()->getY());

CPoint v(RST.getWin()->getVal()->getX(),RST.getWin()->getVal()->getY());

CPoint v2(RST.roundnext()->getX(),RST.roundnext()->getY());

bool abut = false;

bool conv = false;

t_TreeIter it = RST.find(root->getVal());

if ((v.x == v1.x) && (v.x == v2.x) && (p.x != v.x))

{

try

{

while (((*it)->getVal()->getX() == v.x) && ((*it)->next()->getVal() != root->getVal()))

++it;

}

catch(treeException& ex)

{

AutoSave(true);

AfxMessageBox(ex.get_comment());

return NULL;

}

if ((((*it)->getVal()->getX() > v.x) && (p.x > v.x)) ||(((*it)->getVal()->getX() < v.x) && (p.x < v.x)))

{

conv = 0;

abut = 0;

}

else

if ((((*it)->getVal()->getX() > v.x) && (p.x < v.x)) ||(((*it)->getVal()->getX() < v.x) && (p.x > v.x)))

{

conv = 1;

abut = 0;

}

else

if (p.y < v.y)

conv = 1;

}

else

if ((v.y == v1.y) && (v.y == v2.y) && (p.y != v.y))

{

t_TreeIter it = RST.find(root->getVal());

try

{

while (((*it)->getVal()->getY() == v.y) && ((*it)->next()->getVal() != root->getVal()))

++it;

}

catch(treeException& ex)

{

AutoSave(true);

AfxMessageBox(ex.get_comment());

return NULL;

}

if ((((*it)->getVal()->getY() > v.y) && (p.y > v.y)) ||(((*it)->getVal()->getY() < v.y) && (p.x < v.x)))

{

conv = 0;

abut = 0;

}

else

if ((((*it)->getVal()->getY() > v.y) && (p.y < v.y)) ||(((*it)->getVal()->getY() < v.y) && (p.y > v.y)))

{

conv = 1;

abut = 0;

}

else

if (p.x < v.x)

conv = 1;

}

if(IsAbutment(v1,v,v2,p) || abut) {

l=root;

ltree=troot;

StepStruct *ss=new StepStruct(troot,ltree,situation[situation.size()-1],3);

stepstruct.push_back(ss);

}

else {

if(IsConvex(v1,v,v2,p) || conv) {

RN=root->lchild();

treeTree=troot->lchild;

StepStruct *ss=new StepStruct(troot,treeTree,situation[situation.size()-1],3);

stepstruct.push_back(ss);

}

else {

RN=root->rchild();// добавил

treeTree=troot->rchild;

StepStruct *ss=new StepStruct(troot,treeTree,situation[situation.size()-1],3);

stepstruct.push_back(ss);

}

if(treeTree){

l=Left_Search(RN,treeTree,p);

}else{

l=root;

ltree=troot;

StepStruct *ss=new StepStruct(troot,ltree,situation[situation.size()-1],3);

stepstruct.push_back(ss);

};

}

return l;

}

/** Правый поиск */

RandomizeNode<TPoint> * CCHRealTimeView::Right_Search(RandomizeNode<TPoint> *root,TTree *troot, CPoint p)

{

RandomizeNode<TPoint> *r;

RandomizeNode<TPoint> *RN;

TTree *treeTree;

RST.setWin(root);

CPoint v1(RST.roundprev()->getX(),RST.roundprev()->getY());

CPoint v(RST.getWin()->getVal()->getX(),RST.getWin()->getVal()->getY());

CPoint v2(RST.roundnext()->getX(),RST.roundnext()->getY());

bool abut = false;

bool conv = false;

if ((v.x == v1.x) && (v.x == v2.x) && (p.x != v.x))

{

t_TreeIter it = RST.find(root->getVal());

try

{

while (((*it)->getVal()->getX() == v.x) && ((*it)->next()->getVal() != root->getVal()))

++it;

}

catch(treeException& ex)

{

AutoSave(true);

AfxMessageBox(ex.get_comment());

return NULL;

}

if ((((*it)->getVal()->getX() > v.x) && (p.x > v.x)) ||(((*it)->getVal()->getX() < v.x) && (p.x < v.x)))

{

conv = 0;

abut = 0;

}

else

if ((((*it)->getVal()->getX() > v.x) && (p.x < v.x)) ||(((*it)->getVal()->getX() < v.x) && (p.x > v.x)))

{

conv = 1;

abut = 0;

}

else

if (p.y < v.y)

conv = 1;

}

else

if ((v.y == v1.y) && (v.y == v2.y) && (p.y != v.y))

{

t_TreeIter it = RST.find(root->getVal());

try

{

while (((*it)->getVal()->getY() == v.y) && ((*it)->next()->getVal() != root->getVal()))

++it;

}

catch(treeException& ex)

{

AutoSave(true);

AfxMessageBox(ex.get_comment());

return NULL;

}

if ((((*it)->getVal()->getY() > v.y) && (p.y > v.y)) ||(((*it)->getVal()->getY() < v.y) && (p.x < v.x)))

{

conv = 0;

abut = 0;

}

else

if ((((*it)->getVal()->getY() > v.y) && (p.y < v.y)) ||(((*it)->getVal()->getY() < v.y) && (p.y > v.y)))

{

conv = 1;

abut = 0;

}

else

if (p.x < v.x)

conv = 1;

}

if(IsAbutment(v1,v,v2,p) || abut) {

r=root;

rtree=troot;

StepStruct *ss=new StepStruct(troot,rtree,situation[situation.size()-1],3);

stepstruct.push_back(ss);

}

else {

if(IsConvex(v1,v,v2,p) || conv) {

RN=root->rchild();

treeTree=troot->rchild;

StepStruct *ss=new StepStruct(troot,treeTree,situation[situation.size()-1],3);

stepstruct.push_back(ss);

}

else {

RN=root->lchild();

treeTree=troot->lchild;

StepStruct *ss=new StepStruct(troot,treeTree,situation[situation.size()-1],3);

stepstruct.push_back(ss);

}

if(treeTree){

r=Right_Search(RN,treeTree,p);

}else{

r=root;

rtree=troot;

StepStruct *ss=new StepStruct(troot,rtree,situation[situation.size()-1],3);

stepstruct.push_back(ss);

};

}

return r;

}

/** Поиск опорных точек */

bool CCHRealTimeView::Search(RandomizeNode<TPoint> *root,TTree *troot, CPoint p)

{

if(!root) {

StepStruct *ss=new StepStruct(troot,NULL,0,5);

stepstruct.push_back(ss);

return false;

}

if (Points.size() == 5)

{

int i = 1;

}

int sit=Situation(root->minimum(),root,p);

situation.push_back(sit);

StepStruct *ss=new StepStruct(troot,NULL,sit,1);

stepstruct.push_back(ss);

stree=troot;

switch(sit) {

case 1:

ss=new StepStruct(troot,troot->rchild,sit,2);

stepstruct.push_back(ss);

if (root->rchild()) //добавил

return Search(root->rchild(),troot->rchild,p);

else

if (l != NULL && r == l)

{

l = NULL;

ltree = NULL;

l = Left_Search(root,troot,p);

return true;

}

else

if (root->lchild())

return Search(root->lchild(),troot->lchild,p);

else

return Search(root->rchild(),troot->rchild,p);

break;

case 2:

if(root->rchild()) r=Right_Search(root->rchild(),troot->rchild,p);

else

{

r = root;

rtree = troot;

}

if(root == root->minimum() && root->lchild()) l=Left_Search(root->lchild(),troot->lchild,p);

else

if(root) l=Left_Search(root,troot,p);

else

{

l = root;

ltree = troot;

}

if (l == r && root->parent())

return Search(root->parent(),troot->parent,p);

return true;

break;

case 3:

ss=new StepStruct(troot,troot->lchild,sit,2);

stepstruct.push_back(ss);

if (root->lchild()) //добавил

return Search(root->lchild(),troot->lchild,p);

else

if (l != NULL && r == l)

{

l = NULL;

ltree = NULL;

l = Left_Search(root,troot,p);

return true;

}

else

if (root->rchild())

return Search(root->rchild(),troot->rchild,p);

else

return Search(root->lchild(),troot->lchild,p);

break;

case 4:{

if (RST.size() == 2)

{

r = Right_Search(root->lchild(),troot->lchild,p);

l = root;

ltree = troot;

return true;

}

if(root->lchild()) r=Right_Search(root->lchild(),troot->lchild,p);

else

{

r = root;

rtree = troot;

}

if(root == root->minimum() && root->rchild()) l=Left_Search(root->rchild(),troot->rchild,p);

else

if(root) l=Left_Search(root,troot,p);

else

{

l = root;

ltree = troot;

}

if (l == r && root->parent())

return Search(root->parent(),troot->parent,p);

return true;

break;}

case 5:

ss=new StepStruct(troot,troot->rchild,sit,2);

stepstruct.push_back(ss);

if (root->rchild()) //добавил

return Search(root->rchild(),troot->rchild,p);

else

if (l != NULL && r == l)

{

l = NULL;

l = Left_Search(root,troot,p);

return true;

}

else

if (root->lchild())

return Search(root->lchild(),troot->lchild,p);

else

return Search(root->rchild(),troot->rchild,p);

break;

case 6:

if(root->rchild()) l=Left_Search(root->rchild(),troot->rchild,p);

else

{

l = root;

ltree = troot;

}

if(root == root->minimum() && root->lchild()) r=Right_Search(root->lchild(),troot->lchild,p);

else

if(root)r=Right_Search(root,troot,p);

else

{

r = root;

rtree = troot;

}

if (l == r && root->parent())

return Search(root->parent(),troot->parent,p);

return true;

break;

case 7:

ss=new StepStruct(troot,troot->lchild,sit,2);

stepstruct.push_back(ss);

if (root->lchild()) //добавил

return Search(root->lchild(),troot->lchild,p);

else

if (l != NULL && r == l)

{

l = NULL;

l = Left_Search(root,troot,p);

return true;

}

else

if (root->rchild())

return Search(root->rchild(),troot->rchild,p);

else

if (RST.getRoot()->getVal()->getX() == RST.getRoot()->minimum()->getVal()->getX() && RST.getRoot()->minimum()->getVal()->getX() == p.x)

{

t_TreeIter it = RST.begin();

TTree *tmpTree = troot->minimum();

TTree *maxTree,*minTree;

int diffMin = 10000;

int diffMax = 0;

RandomizeNode<TPoint> *numMin, *numMax;

try

{

for (int i = 0; i < RST.size(); i++)

{

int tempDiff = abs((*it)->getVal()->getY() - p.y);

if (tempDiff < diffMin)

{

diffMin = tempDiff;

numMin = *it;

minTree = tmpTree;

}

if (tempDiff > diffMax)

{

diffMax = tempDiff;

numMax = *it;

maxTree = tmpTree;

}

++it;

tmpTree = tmpTree->next;

}

}

catch(treeException& ex)

{

AutoSave(true);

AfxMessageBox(ex.get_comment());

return NULL;

}

r = numMin;

rtree = minTree;

l = numMax;

ltree = maxTree;

return true;

}

else

if (RST.getRoot()->getVal()->getY() == RST.getRoot()->minimum()->getVal()->getY() && RST.getRoot()->minimum()->getVal()->getY() == p.y)

{

t_TreeIter it = RST.begin();

TTree *tmpTree = troot->minimum();

TTree *maxTree,*minTree;

int diffMin = 10000;

int diffMax = 0;

RandomizeNode<TPoint> *numMin,*numMax;

try

{

for (int i = 0; i < RST.size(); i++)

{

int tempDiff = abs((*it)->getVal()->getX() - p.x);

if (tempDiff < diffMin)

{

diffMin = tempDiff;

numMin = *it;

minTree = tmpTree;

}

if (tempDiff > diffMax)

{

diffMax = tempDiff;

numMax = *it;

maxTree = tmpTree;

}

++it;

tmpTree = tmpTree->next;

}

}

catch(treeException& ex)

{

AutoSave(true);

AfxMessageBox(ex.get_comment());

return NULL;

}

r = numMin;

rtree = minTree;

l = numMax;

ltree = maxTree;

return true;

}

else

return Search(root->lchild(),troot->lchild,p);

break;

case 8:

if (RST.size() == 2)

{

r = root;

rtree = troot;

l = Left_Search(root->lchild(),troot->lchild,p);

return true;

}

if(root->lchild()) l=Left_Search(root->lchild(),troot->lchild,p);

else

{

l = root;

ltree = troot;

}

if (RST.getRoot()->getVal()->getX() == RST.getRoot()->minimum()->getVal()->getX() && RST.getRoot()->minimum()->getVal()->getX() == p.x)

{

t_TreeIter it = RST.begin();

TTree *tmpTree = troot->minimum();

TTree *maxTree,*minTree;

int diffMin = 10000;

int diffMax = 0;

RandomizeNode<TPoint> *numMin, *numMax;

try

{

for (int i = 0; i < RST.size(); i++)

{

int tempDiff = abs((*it)->getVal()->getY() - p.y);

if (tempDiff < diffMin)

{

diffMin = tempDiff;

numMin = *it;

minTree = tmpTree;

}

if (tempDiff > diffMax)

{

diffMax = tempDiff;

numMax = *it;

maxTree = tmpTree;

}

++it;

tmpTree = tmpTree->next;

}

}

catch(treeException& ex)

{

AutoSave(true);

AfxMessageBox(ex.get_comment());

return NULL;

}

r = numMin;

rtree = minTree;

l = numMax;

ltree = maxTree;

return true;

}

else

if (RST.getRoot()->getVal()->getY() == RST.getRoot()->minimum()->getVal()->getY() && RST.getRoot()->minimum()->getVal()->getY() == p.y)

{

t_TreeIter it = RST.begin();

TTree *tmpTree = troot->minimum();

TTree *maxTree,*minTree;

int diffMin = 10000;

int diffMax = 0;

RandomizeNode<TPoint> *numMin,*numMax;

try

{

for (int i = 0; i < RST.size(); i++)

{

int tempDiff = abs((*it)->getVal()->getX() - p.x);

if (tempDiff < diffMin)

{

diffMin = tempDiff;

numMin = *it;

minTree = tmpTree;

}

if (tempDiff > diffMax)

{

diffMax = tempDiff;

numMax = *it;

maxTree = tmpTree;

}

++it;

tmpTree = tmpTree->next;

}

}

catch(treeException& ex)

{

AutoSave(true);

AfxMessageBox(ex.get_comment());

return NULL;

}

r = numMin;

rtree = minTree;

l = numMax;

ltree = maxTree;

return true;

}

if(root == root->minimum() && root->rchild()) r=Right_Search(root->rchild(),troot->rchild,p);

else

if(root)r=Right_Search(root,troot,p);

else

{

r = root;

rtree = troot;

}

if (l == r && root->parent())

return Search(root->parent(),troot->parent,p);

return true;

break;

}

}

/** Определение ситуации */

int CCHRealTimeView::Situation(RandomizeNode<TPoint> *m, RandomizeNode<TPoint> *M,CPoint p)

{

int sit;

bool a_convex;

bool m_convex;

bool M_convex;

bool m_abutment;

bool M_abutment;

CPoint pm,pM;

pm.x=m->getVal()->getX();

pm.y=m->getVal()->getY();

pM.x=M->getVal()->getX();

pM.y=M->getVal()->getY();

if (m == M)

{

CPoint M_old;

M_old.x=M->parent()->getVal()->getX();

M_old.y=M->parent()->getVal()->getY();

a_convex=IsConvexAngle(pm,M_old,p);

}

else

a_convex=IsConvexAngle(pm,pM,p);

CPoint v1,v2;

RST.setWin(m);

v1.x=RST.roundprev()->getX();

v1.y=RST.roundprev()->getY();

v2.x=RST.roundnext()->getX();

v2.y=RST.roundnext()->getY();

if ((pm.x == v1.x) && (pm.x == v2.x) && (p.x != pm.x) && (p.y < pm.y))

{

t_TreeIter it = RST.find(m->getVal());

try

{

while (((*it)->getVal()->getX() == pm.x) && ((*it)->next()->getVal() != m->getVal()))

++it;

}

catch(treeException& ex)

{

AutoSave(true);

AfxMessageBox(ex.get_comment());

return NULL;

}

if ((((*it)->getVal()->getX() > pm.x) && (p.x > pm.x)) ||(((*it)->getVal()->getX() < pm.x) && (p.x < pm.x)))

{

m_convex = 0;

m_abutment = 0;

}

else

if ((((*it)->getVal()->getX() > pm.x) && (p.x < pm.x)) ||(((*it)->getVal()->getX() < pm.x) && (p.x > pm.x)))

{

m_convex = 1;

m_abutment = 0;

}

else

if (p.y < pm.y)

{

m_convex=1;

m_abutment=IsAbutment(v1,pm,v2,p);

}

}

else

if ((pm.y == v1.y) && (pm.y == v2.y) && (p.y != pm.y))

{

t_TreeIter it = RST.find(m->getVal());

try

{

while (((*it)->getVal()->getY() == pm.y) && ((*it)->next()->getVal() != m->getVal()))

++it;

}

catch(treeException& ex)

{

AutoSave(true);

AfxMessageBox(ex.get_comment());

return NULL;

}

if ((((*it)->getVal()->getY() > pm.y) && (p.y > pm.y)) ||(((*it)->getVal()->getY() < pm.y) && (p.x < pm.x)))

{

m_convex = 0;

m_abutment = 0;

}

else

if ((((*it)->getVal()->getY() > pm.y) && (p.y < pm.y)) ||(((*it)->getVal()->getY() < pm.y) && (p.y > pm.y)))

{

m_convex = 1;

m_abutment = 0;

}

else

if (p.x < pm.x)

{

m_convex=1;

m_abutment=IsAbutment(v1,pm,v2,p);

}

}

else

{

m_convex=IsConvex(v1,pm,v2,p);

m_abutment=IsAbutment(v1,pm,v2,p);

}

RST.setWin(M);

v1.x=RST.roundprev()->getX();

v1.y=RST.roundprev()->getY();

v2.x=RST.roundnext()->getX();

v2.y=RST.roundnext()->getY();

if ((pM.x == v1.x) && (pM.x == v2.x) && (pM.x != p.x))

{

t_TreeIter it = RST.find(M->getVal());

try

{

while (((*it)->getVal()->getX() == pM.x) && ((*it)->next()->getVal() != M->getVal()))

++it;

}

catch(treeException& ex)

{

AutoSave(true);

AfxMessageBox(ex.get_comment());

return NULL;

}

if ((((*it)->getVal()->getX() > pM.x) && (p.x > pM.x)) ||(((*it)->getVal()->getX() < pM.x) && (p.x < pm.x)))

{

M_convex = 0;

M_abutment = 0;

}

else

if ((((*it)->getVal()->getX() > pM.x) && (p.x < pM.x)) ||(((*it)->getVal()->getX() < pM.x) && (p.x > pM.x)))

{

M_convex = 1;

M_abutment = 0;

}

else

if (p.y < pM.y)

{

M_convex=1;

M_abutment=IsAbutment(v1,pM,v2,p);

}

}

else

if ((pM.y == v1.y) && (pM.y == v2.y) && (pM.y != p.y))

{

t_TreeIter it = RST.find(M->getVal());

try

{

while (((*it)->getVal()->getY() == pM.y) && ((*it)->next()->getVal() != M->getVal()))

++it;

}

catch(treeException& ex)

{

AutoSave(true);

AfxMessageBox(ex.get_comment());

return NULL;

}

if ((((*it)->getVal()->getY() > pM.y) && (p.y > pM.y)) ||(((*it)->getVal()->getY() < pM.y) && (p.x < pM.x)))

{

M_convex = 0;

M_abutment = 0;

}

else

if ((((*it)->getVal()->getY() > pM.y) && (p.y < pM.y)) ||(((*it)->getVal()->getY() < pM.y) && (p.y > pM.y)))

{

M_convex = 1;

M_abutment = 0;

}

else

if (p.x < pM.x)

{

M_convex=1;

M_abutment=IsAbutment(v1,pM,v2,p);

}

}

else

{

M_convex=IsConvex(v1,pM,v2,p);

M_abutment=IsAbutment(v1,pM,v2,p);

}

if (a_convex) //alpha - выпуклый

{

if(!m_convex && !m_abutment){ //m - вогнутая

if(!M_convex && !M_abutment) { //M - вогнутая

sit=1;

}

else { //M - невогнутая

sit=2;

}

}

else { //m - невогнутая

if(M_convex && !M_abutment) { //M - выпуклая

sit=3;

}

else { //M - невыпуклая

sit=4;

}

}

}

else //alpha - вогнутый

{

if(m_convex && !m_abutment){ //m - выпуклая

if(M_convex && !M_abutment) { //M - выпуклая

sit=5;

}

else { //M - невыпуклая

sit=6;

}

}

else { //m - невыпуклая

if(!M_convex && !M_abutment) { //M - вогнутая

sit=7;

}

else { //M - невогнутая

sit=8;

}

}

}

return sit;

}

55

Соседние файлы в папке Doc