<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://camokathomelab.servebeer.com/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=85.172.12.58</id>
	<title>wiki12 - Вклад [ru]</title>
	<link rel="self" type="application/atom+xml" href="https://camokathomelab.servebeer.com/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=85.172.12.58"/>
	<link rel="alternate" type="text/html" href="https://camokathomelab.servebeer.com/mediawiki/index.php/%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/85.172.12.58"/>
	<updated>2026-07-21T20:57:17Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>https://camokathomelab.servebeer.com/mediawiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B5%D0%B7%D0%B5%D0%BD%D1%85%D1%8D%D0%BC%D0%B0&amp;diff=50283</id>
		<title>Алгоритм Брезенхэма</title>
		<link rel="alternate" type="text/html" href="https://camokathomelab.servebeer.com/mediawiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B5%D0%B7%D0%B5%D0%BD%D1%85%D1%8D%D0%BC%D0%B0&amp;diff=50283"/>
		<updated>2025-10-31T09:20:05Z</updated>

		<summary type="html">&lt;p&gt;85.172.12.58: /* Литература */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Файл:LineBresenham.gif|thumb|336px|Демонстрация работы алгоритма]]&lt;br /&gt;
&#039;&#039;&#039;Алгоритм Брезенхе́ма&#039;&#039;&#039; ({{lang-en|Bresenham&#039;s line algorithm}}) — [[алгоритм]], определяющий, какие точки [[Алгоритмы построения отрезка|двумерного растра нужно закрасить, чтобы получить близкое приближение прямой линии между двумя заданными точками]]. Алгоритм широко используется, в частности, для рисования линий на экране компьютера. Существует обобщение алгоритма Брезенхэма для построения кривых 2-го порядка.{{Нет АИ|25|9|2023}} Это один из старейших алгоритмов в [[машинная графика|машинной графике]] — он был разработан [[Брезенхэм, Джек Элтон|Джеком Элтоном Брезенхэмом]] в компании [[IBM]] в 1962 году.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм ==&lt;br /&gt;
Отрезок проводится между двумя точками — &amp;lt;math&amp;gt;(x_0, y_0)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(x_1, y_1)&amp;lt;/math&amp;gt;, где в этих парах указаны столбец и строка соответственно, номера которых растут вправо и вниз. Сначала мы будем предполагать, что наша линия идёт вправо и вниз, причём горизонтальное расстояние &amp;lt;math&amp;gt;x_1 - x_0&amp;lt;/math&amp;gt; превосходит вертикальное &amp;lt;math&amp;gt;y_1 - y_0&amp;lt;/math&amp;gt;, то есть наклон линии от горизонтали — менее 45°. Наша цель состоит в том, чтобы для каждого столбца &#039;&#039;x&#039;&#039; между &amp;lt;math&amp;gt;x_0&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;x_1&amp;lt;/math&amp;gt; определить, какая строка &#039;&#039;y&#039;&#039; ближе всего к линии, и нарисовать точку &amp;lt;math&amp;gt;(x, y)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Общая формула линии между двумя точками:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;y - y_0 = \frac{y_1-y_0}{x_1-x_0}(x-x_0).&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Поскольку мы знаем колонку &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, то строка &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; получается округлением к целому следующего значения:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;y = \frac{y_1-y_0}{x_1-x_0}(x-x_0) + y_0.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Однако, вычислять точное значение этого выражения нет необходимости. Достаточно заметить, что &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; уменьшается от &amp;lt;math&amp;gt;y_0&amp;lt;/math&amp;gt; и за каждый шаг мы добавляем к &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; единицу и добавляем к &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; значение наклона (в нашем случае значение наклона будет отрицательным числом):&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;s = \frac{y_1-y_0}{x_1-x_0},&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
которое можно вычислить заранее. Более того, на каждом шаге мы делаем одно из двух: либо сохраняем тот же &#039;&#039;y&#039;&#039;, либо уменьшаем его на 1.&lt;br /&gt;
&lt;br /&gt;
Что из этих двух выбрать, можно решить, отслеживая &#039;&#039;значение ошибки&#039;&#039;, которое означает вертикальное расстояние между текущим значением &#039;&#039;y&#039;&#039; и точным значением &#039;&#039;y&#039;&#039; для текущего &#039;&#039;x&#039;&#039;. Всякий раз, когда мы увеличиваем &#039;&#039;x&#039;&#039;, мы увеличиваем значение ошибки на величину наклона &#039;&#039;s&#039;&#039;, приведённую выше. Если ошибка превысила 1.0, линия стала ближе к следующему &#039;&#039;y&#039;&#039;, поэтому мы увеличиваем &#039;&#039;y&#039;&#039; на 1.0, одновременно уменьшая значение ошибки на 1.0. В реализации алгоритма, приведённой ниже, &amp;lt;code&amp;gt;plot(x,y)&amp;lt;/code&amp;gt; рисует точку, а &amp;lt;code&amp;gt;abs&amp;lt;/code&amp;gt; возвращает [[Абсолютная величина|абсолютную величину]] числа:&lt;br /&gt;
  &#039;&#039;&#039;function&#039;&#039;&#039; line(&#039;&#039;int&#039;&#039; x0, &#039;&#039;int&#039;&#039; x1, &#039;&#039;int&#039;&#039; y0, &#039;&#039;int&#039;&#039; y1)&lt;br /&gt;
      &#039;&#039;int&#039;&#039; deltax := abs(x1 - x0)&lt;br /&gt;
      &#039;&#039;int&#039;&#039; deltay := abs(y1 - y0)&lt;br /&gt;
      &#039;&#039;real&#039;&#039; error := 0&lt;br /&gt;
      &#039;&#039;real&#039;&#039; deltaerr := (deltay + 1) / (deltax + 1)&lt;br /&gt;
      &#039;&#039;int&#039;&#039; y := y0&lt;br /&gt;
      &#039;&#039;int&#039;&#039; diry := y1 - y0&lt;br /&gt;
      &#039;&#039;&#039;if&#039;&#039;&#039; diry &amp;gt; 0 &lt;br /&gt;
          diry := 1&lt;br /&gt;
      &#039;&#039;&#039;if&#039;&#039;&#039; diry &amp;lt; 0 &lt;br /&gt;
          diry := -1&lt;br /&gt;
      &#039;&#039;&#039;for&#039;&#039;&#039; x &#039;&#039;&#039;from&#039;&#039;&#039; x0 &#039;&#039;&#039;to&#039;&#039;&#039; x1&lt;br /&gt;
          plot(x,y)&lt;br /&gt;
          error := error + deltaerr&lt;br /&gt;
          &#039;&#039;&#039;if&#039;&#039;&#039; error &amp;gt;= 1.0&lt;br /&gt;
              y := y + diry&lt;br /&gt;
              error := error - 1.0&lt;br /&gt;
&lt;br /&gt;
Проблема такого подхода в том, что с вещественными величинами, такими как &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;deltaerr&amp;lt;/code&amp;gt;, компьютеры работают относительно медленно. Кроме того, при вычислениях с плавающей точкой из-за ограничений, связанных с представлением вещественных чисел, невозможно получить точные значения при делении. Это приводит к тому, что в процессе вычислений происходит накопление ошибки и может привести к нежелательным результатам. По этим причинам лучше работать только с целыми числами. Это можно сделать, если умножить все используемые вещественные величины на (&amp;lt;code&amp;gt;deltax + 1)&amp;lt;/code&amp;gt;. Получаем следующий код:&lt;br /&gt;
&lt;br /&gt;
  &#039;&#039;&#039;function&#039;&#039;&#039; line(&#039;&#039;int&#039;&#039; x0, &#039;&#039;int&#039;&#039; x1, &#039;&#039;int&#039;&#039; y0, &#039;&#039;int&#039;&#039; y1)&lt;br /&gt;
      &#039;&#039;int&#039;&#039; deltax := abs(x1 - x0)&lt;br /&gt;
      &#039;&#039;int&#039;&#039; deltay := abs(y1 - y0)&lt;br /&gt;
      &#039;&#039;int&#039;&#039; error := 0&lt;br /&gt;
      &#039;&#039;int&#039;&#039; deltaerr := (deltay + 1)&lt;br /&gt;
      &#039;&#039;int&#039;&#039; y := y0&lt;br /&gt;
      &#039;&#039;int&#039;&#039; diry := y1 - y0&lt;br /&gt;
      &#039;&#039;&#039;if&#039;&#039;&#039; diry &amp;gt; 0 &lt;br /&gt;
          diry := 1&lt;br /&gt;
      &#039;&#039;&#039;if&#039;&#039;&#039; diry &amp;lt; 0 &lt;br /&gt;
          diry := -1&lt;br /&gt;
      &#039;&#039;&#039;for&#039;&#039;&#039; x &#039;&#039;&#039;from&#039;&#039;&#039; x0 &#039;&#039;&#039;to&#039;&#039;&#039; x1&lt;br /&gt;
          plot(x,y)&lt;br /&gt;
          error := error + deltaerr&lt;br /&gt;
          &#039;&#039;&#039;if&#039;&#039;&#039; error &amp;gt;= (deltax + 1)&lt;br /&gt;
              y := y + diry&lt;br /&gt;
              error := error - (deltax + 1)&lt;br /&gt;
&lt;br /&gt;
Необходимость прибавлять единицу к deltax и deltay вызвана тем, что функция должна строить линию от точки (x0, y0) до точки (x1, y1) включительно! Теперь мы можем быстро рисовать линии, направленные вправо-вниз с величиной наклона меньше 1. Осталось распространить алгоритм на рисование во всех направлениях. Это достигается за счёт зеркальных отражений, то есть заменой знака (шаг в 1 заменяется на −1), обменом переменных &#039;&#039;x&#039;&#039; и &#039;&#039;y&#039;&#039;, обменом координат начала отрезка с координатами конца.&lt;br /&gt;
&lt;br /&gt;
== Рисование окружностей ==&lt;br /&gt;
Также существует алгоритм Брезенхема для рисования окружностей. По методу построения он похож на рисование линии. В этом алгоритме строится дуга окружности для первого квадранта, а координаты точек окружности для остальных квадрантов получаются симметрично. На каждом шаге алгоритма рассматриваются три пикселя, и из них выбирается наиболее подходящий путём сравнения расстояний от центра до выбранного пикселя с радиусом окружности.&lt;br /&gt;
&lt;br /&gt;
[[Файл:CircleBresenham.gif|справа|Разложение окружности в растр|обрамить]]&lt;br /&gt;
    // этот алгоритм рисует смежные пиксели,&lt;br /&gt;
    // R - радиус, X1, Y1 - координаты центра&lt;br /&gt;
    &#039;&#039;&#039;int&#039;&#039;&#039; x := 0&lt;br /&gt;
    &#039;&#039;&#039;int&#039;&#039;&#039; y := R&lt;br /&gt;
    &#039;&#039;&#039;int&#039;&#039;&#039; delta := 1 - 2 * R&lt;br /&gt;
    &#039;&#039;&#039;int&#039;&#039;&#039; error := 0&lt;br /&gt;
    &#039;&#039;&#039;while&#039;&#039;&#039; (y &amp;gt;= x)&lt;br /&gt;
        drawpixel(X1 + x, Y1 + y)&lt;br /&gt;
        drawpixel(X1 + x, Y1 - y)&lt;br /&gt;
        drawpixel(X1 - x, Y1 + y)&lt;br /&gt;
        drawpixel(X1 - x, Y1 - y)&lt;br /&gt;
        drawpixel(X1 + y, Y1 + x)&lt;br /&gt;
        drawpixel(X1 + y, Y1 - x)&lt;br /&gt;
        drawpixel(X1 - y, Y1 + x)&lt;br /&gt;
        drawpixel(X1 - y, Y1 - x)&lt;br /&gt;
        error := 2 * (delta + y) - 1&lt;br /&gt;
        &#039;&#039;&#039;if&#039;&#039;&#039; ((delta &amp;lt; 0) &amp;amp;&amp;amp; (error &amp;lt;= 0))&lt;br /&gt;
            delta += 2 * ++x + 1&lt;br /&gt;
            &#039;&#039;&#039;continue&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;if&#039;&#039;&#039; ((delta &amp;gt; 0) &amp;amp;&amp;amp; (error &amp;gt; 0))&lt;br /&gt;
            delta -= 2 * --y + 1&lt;br /&gt;
            &#039;&#039;&#039;continue&#039;&#039;&#039;&lt;br /&gt;
        delta += 2 * (++x - --y)&lt;br /&gt;
&lt;br /&gt;
    // этот алгоритм не рисует смежные пиксели&lt;br /&gt;
    &#039;&#039;&#039;var&#039;&#039;&#039; x = 0;&lt;br /&gt;
    &#039;&#039;&#039;var&#039;&#039;&#039; y = R;&lt;br /&gt;
    &#039;&#039;&#039;var&#039;&#039;&#039; delta = 3 - 2 * y;&lt;br /&gt;
    &#039;&#039;&#039;while&#039;&#039;&#039; (x &amp;lt;= y) {&lt;br /&gt;
        drawpixel(X1 + x, Y1 + y);&lt;br /&gt;
        drawpixel(X1 + x, Y1 - y);&lt;br /&gt;
        drawpixel(X1 - x, Y1 + y);&lt;br /&gt;
        drawpixel(X1 - x, Y1 - y);&lt;br /&gt;
        drawpixel(X1 + y, Y1 + x);&lt;br /&gt;
        drawpixel(X1 + y, Y1 - x);&lt;br /&gt;
        drawpixel(X1 - y, Y1 + x);&lt;br /&gt;
        drawpixel(X1 - y, Y1 - x);&lt;br /&gt;
        delta += delta &amp;lt; 0 ? 4 * x + 6 : 4 * (x - y--) + 10;&lt;br /&gt;
        ++x;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* {{книга&lt;br /&gt;
 | автор = Роджерс Д.&lt;br /&gt;
 | заглавие = Алгоритмические основы машинной графики&lt;br /&gt;
 | ссылка = https://archive.org/details/libgen_00155582&lt;br /&gt;
 | год = 1989&lt;br /&gt;
 | издательство = Мир&lt;br /&gt;
 | место = М.&lt;br /&gt;
 | страницы = [https://archive.org/details/libgen_00155582/page/n446 54]-63&lt;br /&gt;
 |isbn = 5-03-000476-9&lt;br /&gt;
}}&lt;br /&gt;
* {{книга&lt;br /&gt;
 | автор = Шмидт Г.&lt;br /&gt;
 | заглавие = &amp;quot;Си&amp;quot; для профессиональных программистов&lt;br /&gt;
 | год = 1989&lt;br /&gt;
 | место = М.&lt;br /&gt;
 | ref = Шмидт&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
{{wikibooks|Алгоритмы_компьютерной_графики}}&lt;br /&gt;
* [[Алгоритмы построения отрезка]]&lt;br /&gt;
* [[Алгоритм Ву]]&lt;br /&gt;
* [[Алгоритм DDA-линии]]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Геометрические алгоритмы]]&lt;/div&gt;</summary>
		<author><name>85.172.12.58</name></author>
	</entry>
</feed>