Уроки, алгоритмы, программы, примеры

Вход на сайт

Материалы по разделам

Построения
на плоскости (2D)
Графика
в пространстве (3D)
Вычислительная
геометрия
Физическое
моделирование
Фрактальная
графика

Новые комментарии

Спасибо за реализацию, она действительно быстрая. Но не все линии отрисовывает в нужную сторону... Необходимо добавить проверку для случая X-линии if(y1 "<" y0) grad=-grad; и аналогично для Y-линии if(x1 "<" x0) grad=-grad; P.S. На...
Отличные уроки(учу GL по ним), только в renderScene нужно добавить очистку буфера цвета и буфера глубины. При изменении размеров треугольники размножаются)
как исправить это , сделал все по инструкции
Timer1 - выдает ошибку. Использовал IdleTimer1, работает! unit Unit1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls, OpenGLContext, GL, GLU; type { TForm1 } TForm1 =...
в коде присутствуют ошибки! // Считываем координаты procedure TForm1.getCoords(Sender: TObject); var j1:longint; begin n:= StrToInt(Edit2.Text); //число точек s1:=Edit1.Text; s2:=''; i := 1; j:=1; k:=0...

Счетчики и рейтинг

Яндекс.Метрика Рейтинг@Mail.ru
Скриншот к примеру
Среда программирования: 
Code::Blocks 10.05

Одним из важнейших алгоритмов растеризации является алгоритм растеризации треугольника (заполнения треугольника), т.к. в большинстве моделей построения трехмерных объектов последние состоят именно из треугольников. В некоторых статьях этот алгоритм называется алгоритм рисования треугольника. Схематично алгоритм можно описать следующим образом:
Треугольник разбивается на две части вертикальной линией, проходящей через среднюю точку. Каждый из двух полученных треугольников растеризуется по отдельности. В процессе растеризации обе стороны растеризуются параллельно, таким образом, чтобы координаты по оси Y текущих точек на обоих отрезках совпадали. При этом связность растеризуемых линий (сторон треугольника) не обеспечивается. При получении координат текущих точек горизонтальный отрезок между ними заполняется.

Код программы: 

#include <windows.h>
#include "math.h"
#include "fixed.h"
 
#define roundf(x) floor(x + 0.5f)
 
inline void swap(int &a, int &b)
{
      int t;
      t = a;
      a = b;
      b = t;
}
 
void triangle(HDC hdc, int x1, int y1, int x2, int y2, int x3, int y3)
{
      // Упорядочиваем точки p1(x1, y1),
      // p2(x2, y2), p3(x3, y3)
      if (y2 < y1) {
            swap(y1, y2);
            swap(x1, x2);
      } // точки p1, p2 упорядочены
      if (y3 < y1) {
            swap(y1, y3);
            swap(x1, x3);
      } // точки p1, p3 упорядочены
      // теперь p1 самая верхняя
      // осталось упорядочить p2 и p3
      if (y2 > y3) {
            swap(y2, y3);
            swap(x2, x3); 
      }
      // приращения по оси x для трёх сторон
      // треугольника
      fixed dx13 = 0, dx12 = 0, dx23 = 0;
      // вычисляем приращения
      // в случае, если ординаты двух точек
      // совпадают, приращения
      // полагаются равными нулю
      if (y3 != y1) {
            dx13 = int_to_fixed(x3 - x1);
            dx13 /= y3 - y1;
      }
      else
      {
            dx13 = 0;
      }
 
      if (y2 != y1) {
            dx12 = int_to_fixed(x2 - x1);
            dx12 /= (y2 - y1);
      }
      else
      {
            dx12 = 0;
      }
 
      if (y3 != y2) {
            dx23 = int_to_fixed(x3 - x2);
            dx23 /= (y3 - y2);
      }
      else
      {
            dx23 = 0;
      }
      // "рабочие точки"
      // изначально они находятся в верхней  точке 
      fixed wx1 = int_to_fixed(x1);
      fixed wx2 = wx1;
      // сохраняем приращение dx13 в другой переменной 
      int _dx13 = dx13;
 
      // упорядочиваем приращения таким образом, чтобы 
      // в процессе работы алгоритмы
      // точка wx1 была всегда левее wx2
      if (dx13 > dx12)
      {
            swap(dx13, dx12);
      }
      // растеризуем верхний полутреугольник
      for (int i = y1; i < y2; i++){
            // рисуем горизонтальную линию между рабочими
            // точками 
            for (int j = fixed_to_int(wx1); j <= fixed_to_int(wx2); j++){ 
                  SetPixel(hdc, j, i, 0);
            }
            wx1 += dx13;
            wx2 += dx12;
      }
      // вырожденный случай, когда верхнего полутреугольника нет 
      // надо разнести рабочие точки по оси x, т.к. изначально они совпадают 
      if (y1 == y2){
            wx1 = int_to_fixed(x1);
            wx2 = int_to_fixed(x2);
      }
      // упорядочиваем приращения
      // (используем сохраненное приращение)
      if (_dx13 < dx23)
      {
            swap(_dx13, dx23);
      }
      // растеризуем нижний полутреугольник
      for (int i = y2; i <= y3; i++){
            // рисуем горизонтальную линию между рабочими
            // точками 
            for (int j = fixed_to_int(wx1); j <= fixed_to_int(wx2); j++){
                  SetPixel(hdc, j, i, 0);
            }
            wx1 += _dx13;
            wx2 += dx23;
      }
}

Прикрепленный файлРазмер
Исходный код3.81 кб
Исполняемый файл4.54 кб