Список используемой литературы
[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 = ⪙
}
//опрератор преобразования типа в 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;
}