Отрисовка углового сектора текстуры
Автор: Flamer
Приветствую, уважаемые!
Понадобилось реализовать круглый прогресс-бар, чтобы заполнялся он, значит, по кругу :) Исходные посылы были таковы, что этот самый прогресс-бар может быть еще и анимированным, следовательно, при отрисовке сектора надо бы учесть и смену кадров анимации.
Посидев несколько часов в этих ваших интернетах, почесав репу и исходники 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; //---------------------------------------------------------------------------
2 января 2011
Комментарии [6]