Haaf's Game EngineСтатьи

Отрисовка углового сектора текстуры

Автор:

Приветствую, уважаемые!

Понадобилось реализовать круглый прогресс-бар, чтобы заполнялся он, значит, по кругу :) Исходные посылы были таковы, что этот самый прогресс-бар может быть еще и анимированным, следовательно, при отрисовке сектора надо бы учесть и смену кадров анимации.

Посидев несколько часов в этих ваших интернетах, почесав репу и исходники HGE, собрав по кучкам все добро в одну большую кучу, родил творение :) Сразу оговорка: код можно сколько угодно критиковать, мне пофиг, потому что код сырой совсем, да и задачей статьи ставил лишь показать, как можно сделать подобную вещь.

При написании исходника за основу были взяты следующие постулаты:

1. Система координат - как показано здесь;
2. Расчет сектора идет строго по часовой стрелке;
3. Значения углов передаются в радианах.

Предпосылки задачи таковы:

1. Пусть у нас есть прямоугольник на текстуре с координатами X,Y и размерами W,H;
2. Нам известны значения двух векторов, в радианах;
3.  Нам известна точка с координатами X',Y' такими, что X < X' < X+W && Y < Y' < Y+H, т.е. это точка заведомо находится внутри используемого в данным момент прямоугольника текстуры.
4. По этим входным данным надо получить прямоугольник с отсутствующим сектором, т.е.:
  4.1. все части текстуры, лежащие (по часовой стрелке) правее первого вектора и до второго вектора - рисуются, остальные - отбрасываются.


Алгоритм получения такого сектора текстуры заключается в следующем:

1. Получаем проекцию векторов на стороны прямоугольника, т.е. выясняем стороны и точки на этих сторонах, с которыми вектора пересекаются;
2. По полученному набору точек строим набор треугольников, которые в дальнейшем и будут использоваться для отрисовки;
3. PROFIT!

Нижеприведенный код выдран из рабочего проекта, прямо из класса, чуть-чуть переписан для понимания, и все. То есть он не обязан компилиться, даже более того - он почти наверняка не скомпилится, т.к. вероятность ошибок при выдирании чуть более, чем нулевая. Однако на толковые вопросы ответить всегда готов.

Итак, для начала - используемые типы данных:

//---------------------------------------------------------------------------
enum CROSS_TYPE // виды пересечений
{
    ctParallel,    // отрезки лежат на параллельных прямых
    ctSameLine,    // отрезки лежат на одной прямой
    ctOnBounds,    // прямые пересекаются в конечных точках отрезков
    ctInBounds,    // прямые пересекаются в   пределах отрезков
    ctOutBounds    // прямые пересекаются вне пределов отрезков
};
//---------------------------------------------------------------------------
struct CROSS_RESULT // результат проверки пересечения
{
    CROSS_TYPE  type;  // тип пересечения
    hgeVector      pt;    // точка пересечения
};
//---------------------------------------------------------------------------
// функция проверки пересечения, стандартный алгоритм
CROSS_RESULT Crossing(   hgeVector p11, hgeVector p12,   // координаты первого отрезка
    hgeVector p21, hgeVector p22 );  // координаты второго отрезка

//---------------------------------------------------------------------------
enum which_side // c какой стороной прямоугольника пересечение
{
  wsLeft = 0,
  wsTop = 1,
  wsRight = 2,
  wsBottom = 3
};
//---------------------------------------------------------------------------
typedef struct // полная информация о точке пересечения
{
  which_side side;
  hgeVector pt;
} side_point;
//---------------------------------------------------------------------------
Страницы: 1 2 3 4 Следующая »

2 января 2011

Комментарии [6]