Модераторы: PILOT, ManiaK, Mazzi
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Брезенхейм, Рисуем линию 
:(
    Опции темы
Alex
Дата 26.12.2004, 01:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

Репутация: нет
Всего: 162



Low-Level Optimizations
Low-level optimizations are somewhat dubious, because they depend on understanding various machine details. Because machines vary, the accuracy of these low-level assumptions can sometimes be questioned. 

Typically, a set of general rules can be determined that are more-or-less consistent across machines. Here are some examples: 
Addition and Subtraction are generally faster than Multiplication
-Multiplication is generally faster than Division
-Using tables to evaluate discrete functions is faster than computing them 
-Integer caluculations are faster than floating-point calculations. 
-Avoid unnecessary computation by testing for various special cases. 
-The intrinsic tests available to most machines are greater than, less than, greater than or equal, and less than or equal to zero (not an arbitrary value). 


None of these rules are etched in stone. Some of these rules are becoming less and less valid as time passes. We'll address these issues in more detail later. 

For our line drawing algorithm we'll investigate applying several of these optimizations. The incremental calculation effectively removed multiplications in favor of additions. Our next optimization will use three of the mentioned methods. It will remove floating-point calculations in favor of integer operations, and it will remove the single divide opertaion (it makes a difference on short lines), and it will normalize the tests to tests for zero. 

Notice that the slope is always rational (a ratio of two integers).

m = (y1 - y0) / (x1 - x0)

Also note that the incremental part of the algorthim never generates a new y value that is more than one unit away from the old one, because the slope is always less than one (this assured by our improved algorithm).

y[i+1] = y[i] + m

Thus, if we maintained the only the only fractional part of y we could still draw a line by noting when this fraction exceeded one. If we initialize fraction with 0.5, then we will also handle the rounding correctly as in our DDA routine. 

Код

fraction += m
if (fraction[i+1] >= 1) { y = y +1; fraction -= 1; } 


Note that the y variable is now an integer. Next we discuss how to retain the fraction as an integer. After we draw the first pixel (which happens outside our main loop) the correct fraction value is:

fraction = 1/2 + dy / dx

If we scale the fraction by 2*dx the following expression results:

scaledFraction = dx + 2*dy,

and the incremental update becomes:

scaledFraction += 2*dy,

and our test must be modified to reflect the new scaling

Код

if (scaledFraction >= 2*dx) { ... }.


This test can be made a test against a value of zero if the inital value of scaledFraction has 2*dx subtracted from it. Giving outside the loop:

OffsetScaledFraction = dx + 2*dy - 2*dx = 2*dy - dx,

and the inner loop becomes

Код

OffsetScaledFraction += 2*dy
if (OffsetScaledFraction >= 0) { y = y +1; fraction -= 2*dx; }
 

The net result is that we might as well double the values of dy and dx (this can be accomplished with either an add or a shift). The result ing method is known as Bresenham's line drawing algorithm. The code is shown below. 
Код

public void lineBresenham(int x0, int y0, int x1, int y1, Color color)
    {
        int pix = color.getRGB();
        int dy = y1 - y0;
        int dx = x1 - x0;
        int stepx, stepy;

        if (dy < 0) { dy = -dy;  stepy = -1; } else { stepy = 1; }
        if (dx < 0) { dx = -dx;  stepx = -1; } else { stepx = 1; }
        dy <<= 1;                                                  // dy is now 2*dy
        dx <<= 1;                                                  // dx is now 2*dx

        raster.setPixel(pix, x0, y0);
        if (dx > dy) {
            int fraction = dy - (dx >> 1);                         // same as 2*dy - dx
            while (x0 != x1) {
                if (fraction >= 0) {
                    y0 += stepy;
                    fraction -= dx;                                // same as fraction -= 2*dx
                }
                x0 += stepx;
                fraction += dy;                                    // same as fraction -= 2*dy
                raster.setPixel(pix, x0, y0);
            }
        } else {
            int fraction = dx - (dy >> 1);
            while (y0 != y1) {
                if (fraction >= 0) {
                    x0 += stepx;
                    fraction -= dy;
                }
                y0 += stepy;
                fraction += dx;
                raster.setPixel(pix, x0, y0);
            }
        }
    }
[IMG]http://forum.vingrad.ru/index.php?act=module&module=vingradfaq&target=download_file&articleid=2037&attachid=1[/IMG]


--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Микроконтроллеры (MCU) и микропроцессоры (MPU)"
PILOT ManiaK
UniBomb Mazzi

На данный раздел помимо Правил форума распространяются текже следующие правила:


  • Прежде чем создать тему воспользуйтесь поиском или посмотрите в faq. Возможно на форуме уже есть ответ на ваш или близкий к вашему вопрос.
  • В заголовке темы в квадратных скобках обозначьте используемое семейство микроконтроллера: [avr],[pic],[arm].
  • При создании темы с вопросом указывайте участок кода с ошибкой, версию компилятора, схемы подключения, fuse биты и прочие данные, которые помогут найти правильный ответ. Для форматирования текста программ используйте кнопку код.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Для флуда, просьб выполнить задание, поиска партнёров или исполнителей существуют свои разделы.
  • Если вы заметили несовместимое с правилами сообщение, то можете уведомить об этом модератора раздела нажав кнопку Репорт у соответствующего сообщения.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, PILOT, ManiaK, UniBomb, Mazzi.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Микроконтроллеры (MCU) и микропроцессоры (MPU) | Следующая тема »


 




[ Время генерации скрипта: 0.0418 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.