Эта статья имеет рейтинг C-класса по шкале оценки контента Википедии . Она представляет интерес для следующих WikiProjects : | |||||||||||||||||||||||||||||||||||||||||||||||||||
|
В этой статье мне не хватает двух вещей:
Я сам не знаю алгоритма, поэтому оставлю это кому-нибудь другому. Jeronimo 14:36 25 июля 2002 г. (PDT)
Поскольку алгоритм Брезенхэма в первую очередь применим к растровым устройствам, первоначальное его использование на плоттерах Calcomp (которые изначально могут рисовать прямые линии движениями пера) неясно. Рендеринг "пунктирных" линий, вероятно, является способом использования алгоритма на плоттерах, но я не уверен. Может ли кто-нибудь дать ответ? - Bevo 13:07, 25 июля 2004 (UTC)
Я думаю, что после умножения уравнений на deltax переменная deltaerr становится ненужной, так как она просто равна deltay. Замена deltaerr на deltay упростила бы код и приблизила бы его к другим реализациям, например, к той, что в FSHill: Computer Graphics Using OpenGL. Но в любом случае спасибо за эту статью, это пока лучшее и самое простое объяснение алгоритма, которое я видел.
X увеличивается вправо, как обычно, но Y увеличивается вниз, а не вверх. Я понимаю, что это зависит только от того, находится ли начало координат (0, 0) в верхнем левом или нижнем левом углу, но похоже, что этот выбор вызывает путаницу, отсюда и неверное "Эта первая версия обрабатывает только линии, которые восходят вправо", разве не должно быть нисхождение? Я бы предположил, что +X == вправо, +Y == вверх будет более привычно для неспециалистов, которые пришли из декартовых координат в математике в школе, без необходимости мысленно переворачивать по оси X. -- Ральф Кордерой 11:36, 3 декабря 2006 (UTC)
На каком языке программирования написан код в этой статье? — Brim 07:59, 9 февраля 2005 (UTC)
в статье об алгоритме рисования линий утверждается, что это позволяет избежать арифметики с плавающей точкой, однако код здесь явно этого не делает. Пожалуйста, поясните. Plugwash 21:44, 20 марта 2006 (UTC)
Хм... Я вижу, что это может сбивать с толку. Первая версия приведена только в педагогических целях, поскольку она лучше иллюстрирует алгоритм. Надеюсь, вы не против, что я немного сдвинул ваше пояснение, так как считаю, что введение должно, вероятно, просто дать общий обзор. Хенрик 13:57, 21 марта 2006 (UTC)
Если это имело значение, я преобразовал окончательный оптимизированный псевдокод в процедуру C++. Я считаю, что сделал верную построчную реализацию. Итог: это не сработало. Некоторые октанты плоскости работали нормально. Другие создавали только линии под углом 45 градусов. Вернулся и проверил и перепроверил свою реализацию. Она делала все, что говорил псевдокод, и в том же порядке (насколько я мог судить).
Зашел на другой сайт и преобразовал их версию псевдокода в реализацию C++. Работает отлично. Возможно, стоит еще раз проверить псевдокод этой Wiki, чтобы убедиться, что он действительно правильный.
Я на самом деле не тестировал код, но я почти уверен, что основная ошибка исходит от ABS и SWAP; попробуйте использовать функции вместо макросов или хотя бы поставьте скобки, например
-ElNinyo, 28 апреля 2008 г. — Предыдущий неподписанный комментарий добавлен 87.126.153.152 (обсуждение) 11:43, 28 апреля 2008 г. (UTC)
Я думаю, вам следует прочитать сообщение об ошибке SWAP, отправленное в gcc по адресу [2] — Предыдущий неподписанный комментарий добавлен пользователем 193.147.222.244 ( обсуждение ) 18:00, 10 февраля 2009 (UTC)
// ПРИМЕЧАНИЕ: ДАННАЯ РЕАЛИЗАЦИЯ НЕВЕРНА!#define ABS(x) (x < 0 ? -x : x)#define SWAP(x, y) (x ^= y ^= x ^= y)void LineDrawer_Bresenham::Draw(int x1, int y1, int x2, int y2, int color){bool крутой = ABS(y2 - y1) > ABS(x2 - x1);если(крутой){ПЕРЕСТАНОВКА(x1, y1);ПЕРЕСТАНОВКА(x2, y2);}если(x1 > x2){ПЕРЕСТАНОВКА(x1, x2);ПЕРЕСТАНОВКА(y1, y2);}int dx = x2 - x1;int dy = ABS(y2 - y1);ошибка int = 0;int ystep;целое у = у1;если (y1 < y2){ystep = 1;}еще{ystep = -1;}для (int x = x1; x < x2; x++) {если(крутой){буфер[y + x * SCRWIDTH] = цвет;}еще{ буфер[x + y * SCRWIDTH] = цвет;}ошибка += dy;если(2 * ошибка >= dx){y += ystep;ошибка -= dx;}}}
-- анонимно
Реализация макроса "SWAP" в приведенном выше коде неверна, как объясняется в алгоритме обмена XOR и [3]. Некоторые хорошие компиляторы C скомпилируют эту реализацию во что-то, что не даст ожидаемых результатов.
Реализация макроса "ABS" в приведенном выше коде неверна, как объясняется в Wikibooks: C Programming/Preprocessor#.23define. Хороший компилятор C всегда скомпилирует эту реализацию во что-то, что возвращает "-3" при задании "1-2", а это не то, что нам нужно.
Существует много способов правильно реализовать "SWAP" и "ABS". Например, в C++,
#define SWAP(x, y) std::swap(x,y)#определить ABS(x) std::abs(x)
или, в C,
#определить ABS( x ) ( ((x) < 0) ? -(x) : (x) )#define SWAP(x, y) { int temp = x; x = y; y = temp; } /* предположим, что x и y — это int */
или, если вы настаиваете на том, чтобы быть «умным»,
#определить ABS( x ) ( ((x) < 0) ? -(x) : (x) )#define SWAP(x, y) { x ^= y; y ^= x; x ^= y; } /* предположим, что x и y не ссылаются на одну и ту же ячейку памяти */
Как только эти ошибки будут исправлены, перевод «оптимизированного» псевдокода, представленного в статье, на язык C в пропорции 1:1, по-моему, даст правильные результаты.
-- 68.0.124.33 ( обсуждение ) 19:06, 23 ноября 2010 (UTC)
Я чувствовал себя настолько свободным, что добавил эту главу как прямой перевод с немецкой версии, куда я также внес эту и некоторые другие части. Поскольку мой родной язык не английский, кто-то может захотеть пройтись по формулировкам этой новой главы и перевести их на настоящий английский... Кроме того, первоначальное описание алгоритма и иллюстрация сильно отличаются в немецкой версии, возможно, мы сможем объединить все это и извлечь лучшее из обоих. de:PeterFrankfurt, 4 февраля 2007 г. — Предыдущий неподписанный комментарий был добавлен 84.177.118.110 (обсуждение) 15:08, 4 февраля 2007 г. (UTC).
Я думаю, что в конце кода на языке C должно быть следующее, а не то, что там есть:
если (у>=х){ setPixel(x0 + x, y0 + y); setPixel(x0 - x, y0 + y); setPixel(x0 + x, y0 - y); setPixel(x0 - x, y0 - y); если (у>х){ setPixel(x0 + y, y0 + x); setPixel(x0 - y, y0 + x); setPixel(x0 + y, y0 - x); setPixel(x0 - y, y0 - x); } }
Это предотвращает двойную прорисовку пикселей. Я не уверен, что это вызывает какие-либо проблемы, поэтому я и добавил это здесь.
Большая часть этой статьи НЕ об алгоритме Брезенхэма, а о различных других алгоритмах DDA, которые являются его вариациями или обобщениями. Я бы рекомендовал переименовать эту статью в DDA или Цифровые дифференциальные анализаторы, и прояснить, какие алгоритмы на самом деле являются алгоритмами Брезенхэма (в основном только первая часть), а какие, например, обобщение средней точки, принадлежат более поздним ученым-компьютерщикам.
Например, «Другой подход» — это алгоритм DDA средней точки, разработанный Питтевеем: Питтевей, MLV, «Алгоритм рисования эллипсов или гипербол с помощью цифрового плоттера», Computer J., 10(3) ноября 1967 г., стр. 282-289.
Ван Эйкен (Ван Эйкен, младший, "Эффективный алгоритм рисования эллипса", CG&A, 4(9), сентябрь 1984 г., стр. 24-35) показал, что алгоритм средней точки дает тот же результат, что и алгоритм Брезенхэма. Swestrup 17:59, 28 февраля 2007 г. (UTC)
Понимание вычисления параметра решения, который используют алгоритмы средней точки окружности и эллипса, очень важно для полного понимания алгоритма и для полноты. - Видрат 16:23, 29 апреля 2007 (UTC)
Реализовав вариант круга на ассемблере AVR, используя пример BASIC в качестве отправной точки, я обнаружил две интересные вещи (обе подтверждены запуском кода примера в BBC Basic для Windows):
Во-первых, вычисление Y^2 и X^2 совершенно излишне; хорошо, это показывает, как вычисленные значения соотносятся с теоремой Пифагора, но это пустая трата процессорного времени, если люди понимают это как пример из реальной жизни.
Во-вторых, при портировании в среду без плавающей точки я вычислил Y-end, умножив r на root-2 * 65536, а затем отбросив два младших байта результата. Достаточно справедливо, но конечная точка октанта — это точка, в которой увеличение y и уменьшение x становятся равными. yend не нужно вычислять, а проверка цикла while-wend может быть y<=x. Это позволяет избежать любых вычислений с плавающей точкой вообще, более того, это позволяет избежать вычисления избыточного значения вообще.
Я не вижу никаких проблем, есть ли какие-либо комментарии? (Кроме моей неправильной орфографии, которая уже исправлена)
Я добавил кое-что, касающееся вычисления квадрата числа по сумме нечетных чисел N, считая от 1. См. square_number . Я нашел упоминание об этой технике на folklore.org. Сайт Macintosh stories. Там упоминалось, что эта идея лежит в основе реализации круговой процедуры. Я считаю, что за ней стоял Bill_Atkinson .
Я пытался реализовать это сам. Пришел с каким-то кодом. Затем попытался найти способ сохранить порог . Я пришел только к вычислению y так же, как и x. По сумме нечетных рядов. Должно быть, можно сделать это еще лучше, сказал я себе.
Просмотр того, что было на этой странице, дал мне больше понимания. Что это относится к Брезенхэму.
void raster_circle(целое число x0, целое число y0, целое число радиуса) { ошибка int = 1 - радиус; int nextodd_x = 0; int nextodd_y = -2 * радиус - 1; целое число х = 0; int y = радиус; нарисуйте начальный квадрат пикселей в то время как ( х < у ) {
Я понял, что в цикле y речь идет о получении нечетных чисел из этой серии с дальнего конца.
/* подготовить следующий нечетный с дальнего конца и уменьшить на него */ если ( ошибка >= 0 ) { у--; следующий_четный_y += 2; f += nextodd_y; } х++;
Я также понял, что в цикле x речь идет о получении просто следующего нечетного числа.
/* увеличить на следующий od от */ следующийнечетный_x += 2; f += nextodd_x; нарисуйте правильные восемь пикселей }}
Я завершаю это, давая свое псевдоотношение. Это может быть составлено для .
В статье предполагается перевернутая система координат, линия идет слегка вниз, и говорится: "(то есть линия имеет наклон больше -1 и меньше 0.)". Эти три утверждения не могут быть все верными.
Примите решение и исправьте это. Ура, Shinobu 15:56, 19 мая 2007 (UTC)
Я хотел бы отметить, что эти алгоритмы рисования линий, опубликованные PrisonerOfPain, и алгоритм линий Брезенхэма, обсуждаемый в статье, даже не будут работать для некоторых линий, идущих прямо вниз. Вот пример: линия начинается в [1,1] и заканчивается в [3, 25], линия идет прямо вниз (в растровой системе координат), как вы увидите, вы выполните цикл только 2 раза, рисуя только два пикселя. Должен быть еще один цикл для рисования всех пикселей оси Y, или вы можете захотеть вычислить отношение dx/dy и учесть его при цикле от x1 до x2. Я сейчас в середине экзамена, поэтому я расскажу о своем алгоритме рисования линий немного позже.
Фомас 02:03, 24 мая 2007 (UTC)
Статья теперь специально указывает, что первый пример псевдокода не обрабатывает должным образом эти случаи. "Обобщенные" и "оптимизированные" примеры псевдокода в статье в настоящее время используют флаг "steep", и, насколько я могу судить, были исправлены для обработки всех упомянутых вами случаев.
-- 68.0.124.33 ( обсуждение ) 19:06, 23 ноября 2010 (UTC)
Следующий алгоритм позволяет вам нарисовать любую прямую линию с любым наклоном. Обратите внимание, что его можно оптимизировать, рисуя пиксели с обоих концов к середине.
Функция drawLine(x1, y1, x2, y2) int dX = Abs(x2 - x1) int dY = Abs(y2 - y1) int x = x1 int y = y1 Если (x1 > x2) Тогда offsetX = -1 Иначе offsetX = 1 Если (y1 > y2) Тогда offsetY = -1 Иначе offsetY = 1 УстановитьПиксель(x,y) Если (dX > dY) Тогда ошибка int = dX / 2 Пока (x != x2) ошибка = ошибка - dY Если (ошибка < 0) y = y + смещениеY ошибка = ошибка + dX Конец Если x = x + смещениеX УстановитьПиксель(x,y) Wend Else int ошибка = dY / 2 Пока (y != y2) ошибка = ошибка - dX Если (ошибка < 0) x = x + смещениеX ошибка = ошибка + dY Конец Если y = y + смещениеY УстановитьПиксель(x,y) Венд Конец ЕСЛИ Конец Если Конец Функция
Фомас 00:00, 26 мая 2007 (UTC)
Похоже, это действительно работает, проверено путем преобразования в ассемблер x86. 83.21.28.61 (обсуждение) 11:16, 10 марта 2008 (UTC)
У меня тоже работает.. преобразовано в C. Спасибо! -- JeffryJohnston ( обсуждение ) 22:42, 4 мая 2008 (UTC)
Вышеприведенное НЕ работает! Это даже синтаксически некорректно, так как есть дополнительный END IF перед END FUNCTION. Также есть дополнительный раздел в Java ниже для случая, когда dX = dY, который отсутствует в вышеприведенном. Когда вы документируете алгоритмы, вам нужно убедиться, что документация верна, иначе она бессмысленна. Это лучшая причина использовать настоящий язык, а не псевдокод. Настоящие языки имеют реализации, так что написанное на них можно протестировать. Лучшие из них имеют формальные семантические определения и могут быть обоснованы математически. Псевдокоды, как правило, не имеют ни того, ни другого. —Предыдущий комментарий без знака , добавленный 86.138.15.151 (обсуждение) 22:31, 28 марта 2010 (UTC)
Это версия Java, для тех, кому интересно...
public void drawLine(int x1, int y1, int x2, int y2){ Point2D.Double[] пикселей = new Point2D.Double[Math.abs(x1 - x2) + Math.abs(y1 - y2)]; int dX = Math.abs(x2 - x1); int dY = Math.abs(y2 - y1); целое число х = х1; целое у = у1; int offsetY; int offsetX; счетчик целых чисел = 0; если (x1 > x2) смещениеX = -1;иначе если (x2 > x1) смещение X = 1;иначе смещениеX = 0; если (y1 > y2) смещение Y = -1;иначе если (y2 > y1) смещение Y = 1;иначе смещениеY = 0;пиксели[счетчик] = new Point2D.Double(x, y); если (dX > dY){ ошибка int = dX / 2; пока (х != х2){ счетчик ++; ошибка = ошибка - dY; если (ошибка < 0){ y = y + смещениеY; ошибка = ошибка + dX; } x = x + смещениеX; пиксели[счетчик] = new Point2D.Double(x, y); } } иначе если (dY > dX){ ошибка int = dY / 2; пока (y != y2){ счетчик ++; ошибка = ошибка - dX; если (ошибка < 0){ x = x + смещениеX; ошибка = ошибка + dY; } y = y + смещениеY; пиксели[счетчик] = new Point2D.Double(x, y); } } иначе если (dX == dY){ пока(х != х2){ х++; у++; пиксели[счетчик] = new Point2D.Double(x, y); } }}
Обратите внимание, что пределы массива ни в коем случае не являются точными; однако они достаточно велики, чтобы вместить строку. 192.84.113.70 ( обсуждение ) 17:34, 14 июля 2008 (UTC)Я,Я сам и я
Это обсуждение имеет особое значение? Я бы предпочел удалить... semanticprecision 15:53, 6 июля 2007 (UTC)
Эта статья теперь в беспорядке - у нас есть два альтернативных описания одного и того же алгоритма, лучшим подходом было бы вместо этого изменить исходный контент, чтобы включить новую информацию. Так что теперь у нас есть то, что по сути является ответвлением контента на той же странице. Я испытываю искушение переместить второе описание в песочницу, чтобы мы могли переместить полезные части обратно в статью по частям. Если никто не возражает, я, скорее всего, сделаю это через день или два. henrik • talk 11:28, 9 августа 2007 (UTC)
Версия алгоритма на языке C неверна. Она не может рисовать линии, где dy > dx. Это происходит из-за того простого факта, что она не включает переменную "steep", которая используется в коде выше. 91.89.169.47 (обсуждение) 23:51, 10 января 2008 (UTC)
Алгоритм круга средней точки использовался для указания на раздел «Вариант круга» в этой статье. Раздел был удален, но теперь я перенес его в новую статью. Не уверен, является ли это наиболее используемым названием для этого алгоритма, поэтому, пожалуйста, внесите соответствующие изменения, если вы знаете лучше. Lakeworks ( обсуждение ) 20:56, 12 января 2008 (UTC)
Для получения дополнительной информации по этой теме щелкните ссылку ниже http://signalspot.com/2008/01/14/a-novel-and-accurate-method-for-circular-object-identification-combined-approach-of-hough-transform-eigen-values-and/#more-264 —Предыдущий неподписанный комментарий добавлен 117.198.96.60 (обсуждение) 19:58, 13 января 2008 (UTC)
Я просто немного пересматривал модуль Graphics, который я делаю, и наткнулся на это, и насколько я знаю из лекций и т. д., это НЕ алгоритм Брезенхэма, это DDA. Алгоритм Брезенхэма отличается очень тонко, он включает больше предварительных вычислений и не разделяется при вычислении параметра решения, поэтому быстрее и лучше. Плюс разные вычисления для параметра решения в зависимости от значения <0 или >0. Очень неправильно называть статью чем-то, что она не описывает. —Предыдущий неподписанный комментарий добавлен Leshiy uk (обсуждение • вклад ) 21:38, 11 мая 2008 (UTC)
93.184.73.10 ( обсуждение ) 01:15, 24 мая 2014 (UTC)
Могу ли я использовать исходный код реализации C, указанный на странице моего лицензионного программного обеспечения MIT/X11? 149.156.160.140 (обсуждение) 08:04, 22 января 2009 (UTC)
Реализация C99/C++ не рисует полную горизонтальную линию. При вводе (0,0), (2,0) она рисует только пиксели (0,0) и (1,0), а (2,0) остается пустым.
Должна ли эта строка:
для (int x = x0; x != x1; x += xstep) {
быть изменен на этот?
для (int x = x0; x <= x1; x += xstep) {
-- 155.210.155.136 (обсуждение) 08:35, 17 июля 2009 (UTC)
Я удалил код реализации из статьи. Он нам не нужен; псевдокода достаточно. Как видно из обсуждений выше, код реализации подвержен ошибкам, и что еще хуже, это оригинальное исследование . Соответствующее обсуждение есть в [4]. Консенсус был в том, что нам на самом деле не нужен код реализации, псевдокода достаточно. Offliner ( talk ) 16:01, 9 августа 2009 (UTC)
Я думаю, что следующий алгоритм неверен. Я не совсем уверен, поэтому лучше оставлю его в покое.
function line(x0, x1, y0, y1) int deltax := x1 - x0 int deltay := y1 - y0 real error := 0 real deltaerr := deltay / deltax // Предположим, что deltax != 0 (линия не вертикальная), // обратите внимание, что это деление необходимо выполнить таким образом, чтобы сохранить дробную часть int y := y0 для x от x0 до x1 график(x,y) ошибка := ошибка + deltaerr если abs(ошибка) ≥ 0,5 тогда у := у + 1 ошибка := ошибка - 1.0
Меня беспокоит эта строка.
если abs(ошибка) ≥ 0,5 тогда
«abs» здесь совершенно неверен, потому что если deltaerr равен точно 0,5, условие всегда будет выполняться, уменьшая ошибку на 0,5 с каждым оборотом.
И да, это мое оригинальное исследование :) Miko3k ( обсуждение ) 23:16, 12 августа 2009 (UTC)
Я думаю, что следующий код Octave отображает псевдокод, приведенный здесь
функция [indx indy]=bresenham ( x,y ) % векторы x, y в координатах экрана x = круглый ( x ); y = круглый ( y ); % находится ли линия выше диагонали крутой = abs ( y ( 2 ) - y ( 1 )) > abs ( x ( 2 ) - x ( 1 )); если крутой % отразить вдоль диагонали y_new = x ; x = y ; y = y_new ; очистить y_new ; конец обратный = x ( 1 ) > x ( 2 ); если обратный % обратный наклон x = x ([ 2 1 ]); y = y ([ 2 1 ]); конец deltax = x ( 2 ) - x ( 1 ); deltay = abs ( y ( 2 ) - y ( 1 )); если deltax ~= 0 deltaerr = deltay / deltax ; иначе % вернуть вертикальный список индексов disp ( 'вертикальная линия' ) end если y ( 1 ) < y ( 2 ) % положительный наклон ystep = 1 ; иначе ystep = - 1 ; конец % инициализация indy = нули ( deltax + 1 , 1 ); indx = indy ; j = 0 ; err = пол ( дельтаксис / 2 ); для i = 0 : deltax , если крутой indx ( i + 1 )= j + y ( 1 ); indy ( i + 1 )= i + x ( 1 ); иначе indx ( i + 1 )= i + x ( 1 ); indy ( i + 1 )= j + y ( 1 ); конец err = err - deltay ; если err < 0 j = j + ystep ; err = err + deltax ; конец конец
Вот тестовый скрипт
% Скриптовая фигура ( 1 , 'Позиция' ,[ 0 200 0 200 ]); экранx = 20 ; экранy = 20 ;x = linspace ( 0 , 1 , 100 ) * 10 + 3 ; y = 2 * x - 3 ; y2 = - 1,5 * x + 22 ; y3 = .6342 * x + 3 ; [ indx , indy ] = брезенхам ( x ([ 1 конец ]), y ([ 1 конец ])); [ indx2 , indy2 ] = брезенхам ( x ([ 1 конец ]), y2 ([ 1 конец ])); [ indx3 , indy3 ] = брезенхам ( x ([ 1 конец ]) + 5 , y3 ([ 1 конец ])); h = plot ( indx , indy , 'bo' , ... indx2 , indy2 , 'ro' , ... indx3 , indy3 , 'go' ); set ( h , 'markersize' , 12 );удержание графика ( x , y , '-b' , x , y2 , ' -r' , x + 5 , y3 , '-g' ) удержание выключено set ( gca , 'xtick' ,( 1 : screenx ) - 0.5 , 'ytick' ,( 1 : screeny ) - 0.5 , 'yticklabel' ,[], 'xticklabel' ,[]); сеткаось([1 экранx 1 экранy]) ось равна
Результат показан на рисунке справа.
Я думаю, вы можете видеть, что решение было принято неверно для двух строк. Это, вероятно, не алгоритм Брезенхэма. Kakila 17:22(CEST) Воскресенье, 6 июня 2010 г. — Предыдущий недатированный комментарий добавлен 15:31, 6 июня 2010 г. (UTC).
err = floor(дельтаксис / 2);
err = round(дельтаксис / 2);
В разделе «Оптимизация» основной статьи я просто не могу понять, какого черта все дробные числа умножаются на «дельтакс». Разрешено ли нам выполнять такое умножение везде, где это нужно? И почему ошибка установлена в «дельтакс/2», она также может быть дробным числом, если выражена таким образом. — Предыдущий комментарий без знака добавлен Jaybhanderi ( talk • contribs ) 17:24, 9 июня 2010 (UTC)
ошибка int := deltax / 2
ошибка int := round( deltax / 2 )
ошибка int := floor( deltax / 2 )
Я не понимаю, как умножение на deltax приводит к делению с плавающей точкой внутри основного цикла. Единственное деление, которое я смог придумать, это то, что в неравенстве будет написано:
ошибка > дельтакс/2
Но deltax/2 останется постоянным на протяжении всего цикла, так что его можно будет легко вычислить до входа в цикл. Я что-то упустил? — Предыдущий комментарий без знака , добавленный 87.161.171.40 (обсуждение) 21:48, 9 февраля 2013 (UTC)
Другая реализация, которую я видел, была ОЧЕНЬ медленной, поэтому вот та, которую я написал, по сути, просто преобразовав псевдокод под заголовком «Оптимизация»:
public static final void lineAlgorithm(int x0, int y0, int x1, int y1) { // Bresenham's line algorithmboolean steep = Math.abs(y1 - y0) > Math.abs(x1 - x0);if (steep) {int tmp = x0;x0 = y0;y0 = tmp;tmp = x1;x1 = y1;y1 = tmp;}if (x0 > x1) {int tmp = x0;x0 = x1;x1 = tmp;tmp = y0;y0 = y1;y1 = tmp;}int deltax = x1 - x0;int deltay = Math.abs(y1 - y0);int error = deltax / 2;int ystep = -1;int y = y0;if (y0 < y1)ystep = 1;for (int x = x0; x <= x1; x++) {error -= deltay;if (error < 0) {y += ystep;error += deltax;} } }
И это только мне кажется или версия алгоритма «Упрощение» намного медленнее изначально оптимизированной? 24.193.99.41 (обсуждение) 19:33, 8 августа 2011 (UTC)
-- может быть, потому что «упрощенный» алгоритм имеет 3 оператора «if» во внутреннем цикле, а «оптимизированный» алгоритм имеет только 2? .. на самом деле, вычеркните это: я не учел цикл «for», который технически также является «if»
Часть статьи «Вывод» не очень гармонирует с предыдущими частями. Во введении к алгоритму предполагается, что «центры пикселей имеют целочисленные координаты». Однако в части вывода графики, похоже, предполагают, что это верхний левый угол пикселя имеет целочисленные координаты. Мой разум сейчас представляет собой месиво из хэш-салата после прохождения алгоритмов, но мне кажется, что это должно иметь какие-то последствия. Очень сбивает с толку то, что способ инициализации переменной накопления ошибок настолько отличается.
Кроме того, «упрощение» первого алгоритма до такого, который не выполняет никаких обменов, впечатляет, и я был бы очень признателен за некоторые педагогические шаги для его вывода. Я думаю, что в этом также может быть некоторая общая педагогическая ценность. Кроме того, как это соотносится с другими с точки зрения производительности? Я также не уверен, что упрощение — правильное слово. — Предыдущий неподписанный комментарий, добавленный Arketyp (обсуждение • вклад ) 13:52, 14 марта 2012 (UTC)
Это недоступно для прочтения любому читателю, который действительно хочет понять, о чем идет речь.
В разделе «Оптимизация» указано: «Это приводит к разделению внутри основного цикла, однако...». Что? О каком «разделении» вы говорите? Где вы там видите «разделение»? Нет абсолютно никакого разумного объяснения, почему мы перешли от подсчета ошибок от нуля и выше к подсчету от дельтакса и ниже. Почему, в самом деле?
Раздел «Вывод» начинается с переосмысления канонического уравнения прямой в 2D. И он делает это с нуля. Почему??? Почему бы просто не использовать Ax+By+C=0 как общеизвестный базовый факт?
Следующий раздел «Алгоритм» неполон. Он никуда не ведет. Следующий раздел «Алгоритм с целочисленной арифметикой» совершенно бессвязен. Он представляет две формулы для второй точки, но не дает объяснения того, что делают там эти уравнения. Он говорит о «разнице D», но не объясняет, что это за «разница D» для второй точки. Что такое D для второй точки? Что делают там эти две формулы?
50.242.89.251 (обсуждение) 20:28, 26 апреля 2014 (UTC)
Следующий блок повторяется до и в конце цикла:
если D > 0 у = у+1 Д = Д - (2*дх)
Но на самом деле его последнее выполнение бесполезно, поэтому мы могли бы вместо этого поместить его только в начало цикла, тем самым упростив код:
plotLine(x0,y0, x1,y1) дх=х1-х0 dy=y1-y0 D = 2*dy - dx участок(x0,y0) у=у0 для x от x0+1 до x1 если D > 0 у = у+1 Д = Д - (2*дх) график(x,y) Д = Д + (2*ди)
72.229.111.192 (обсуждение) 20:30, 24 мая 2017 (UTC)
Что касается пункта 1: он все еще неверен. Здесь есть несколько основных заблуждений. У пикселя нет центра, и у него определенно нет углов. За словами «центр пикселя» даже есть ссылка на основную статью о пикселях. Видимо, человек, который это сделал, не читал статью о пикселях. Честно говоря, об этом не говорится прямо. Если вы хотите просветить себя (и, возможно, улучшить эту статью), я рекомендую прочитать статью «Пиксель — это не маленький квадрат» Элви Рэя Смита от 1995 года. Короче говоря, пиксель — это точка выборки . У нее есть положение, но нет протяженности. 2001:16B8:4870:FD00:DD8E:E505:61A7:D939 (обсуждение) 14:41, 20 октября 2019 (UTC)
-- См. также: https://en.wikipedia.org/wiki/%3F:#Lua функция bline ( x0 , y0 , x1 , y1 ) локальный dx , sx = math.abs ( x1 - x0 ) , x0 < x1 и 1 или -1 локальный dy , sy = math.abs ( y1 - y0 ) , y0 < y1 и 1 или -1 локальная err , e2 = ( dx > dy и dx или - dy ) / 2 while true do setPixel ( x0 , y0 ); if x0 == x1 and y0 == y1 then break end e2 = err if e2 > - dx then err -= dy ; x0 += sx end if e2 < dy then err += dx ; y0 += sy end end end