Bitmap/Bresenham's line algorithm: Difference between revisions
Content deleted Content added
(34 intermediate revisions by 17 users not shown) | |||
Line 1:
[[Category:Graphics algorithms]]
[[Category:Geometry]]
{{task|Raster graphics operations}}
;Task:
Line 6 ⟶ 7:
<br>draw a line given two points with [[wp:Bresenham's line algorithm|Bresenham's line algorithm]].
<br><br>
=={{header|11l}}==
{{trans|Python}}
<syntaxhighlight lang="11l">T Colour = BVec3
V black = Colour(0, 0, 0)
V white = Colour(255, 255, 255)
T Bitmap
Int width, height
Colour background
[[Colour]] map
F (width = 40, height = 40, background = white)
assert(width > 0 & height > 0)
.width = width
.height = height
.background = background
.map = (0 .< height).map(h -> (0 .< @width).map(w -> @@background))
F fillrect(x, y, width, height, colour = black)
assert(x >= 0 & y >= 0 & width > 0 & height > 0)
L(h) 0 .< height
L(w) 0 .< width
.map[y + h][x + w] = colour
F chardisplay()
V txt = .map.map(row -> row.map(bit -> (I bit == @@.background {‘ ’} E ‘@’)).join(‘’))
txt = txt.map(row -> ‘|’row‘|’)
txt.insert(0, ‘+’(‘-’ * .width)‘+’)
txt.append(‘+’(‘-’ * .width)‘+’)
print(reversed(txt).join("\n"))
F set(x, y, colour = black)
.map[y][x] = colour
F get(x, y)
R .map[y][x]
F line(x0, y0, x1, y1)
‘Bresenham's line algorithm’
V dx = abs(x1 - x0)
V dy = abs(y1 - y0)
V (x, y) = (x0, y0)
V sx = I x0 > x1 {-1} E 1
V sy = I y0 > y1 {-1} E 1
I dx > dy
V err = dx / 2.0
L x != x1
.set(x, y)
err -= dy
I err < 0
y += sy
err += dx
x += sx
E
V err = dy / 2.0
L y != y1
.set(x, y)
err -= dx
I err < 0
x += sx
err += dy
y += sy
.set(x, y)
V bitmap = Bitmap(17, 17)
L(x0, y0, x1, y1) ((1, 8, 8, 16), (8, 16, 16, 8), (16, 8, 8, 1), (8, 1, 1, 8))
bitmap.line(x0, y0, x1, y1)
bitmap.chardisplay()</syntaxhighlight>
{{out}}
<pre>
+-----------------+
| @ |
| @ @ |
| @ @ |
| @ @ |
| @ @ |
| @ @ |
| @ @ |
| @ @ |
| @ @|
| @ @ |
| @ @ |
| @ @@ |
| @ @ |
| @ @ |
| @ @ |
| @ |
| |
+-----------------+
</pre>
=={{header|360 Assembly}}==
{{trans|Rexx}}
<
BRESENH CSECT
USING BRESENH,R13 base register
Line 196 ⟶ 290:
PG DC CL80' ' buffer
REGEQU
END BRESENH </
{{out}}
<pre>
Line 220 ⟶ 314:
...|....................
</pre>
=={{header|Action!}}==
Part of the task is available in [http://www.rosettacode.org/wiki/Category:Action!_Bitmap_tools#RGBLINE.ACT RGBLINE.ACT].
{{libheader|Action! Bitmap tools}}
<syntaxhighlight lang="action!">INCLUDE "H6:RGBLINE.ACT" ;from task Bresenham's line algorithm
RGB black,yellow,violet,blue
PROC DrawImage(RgbImage POINTER img BYTE x,y)
RGB POINTER ptr
BYTE i,j
ptr=img.data
FOR j=0 TO img.h-1
DO
FOR i=0 TO img.w-1
DO
IF RgbEqual(ptr,yellow) THEN
Color=1
ELSEIF RgbEqual(ptr,violet) THEN
Color=2
ELSEIF RgbEqual(ptr,blue) THEN
Color=3
ELSE
Color=0
FI
Plot(x+i,y+j)
ptr==+RGBSIZE
OD
OD
RETURN
PROC Main()
RgbImage img
BYTE CH=$02FC,width=[81],height=[51],st=[5]
BYTE ARRAY ptr(12393)
BYTE c,i,n
INT x,y,nx,ny
RGB POINTER col
Graphics(7+16)
SetColor(0,13,12) ;yellow
SetColor(1,4,8) ;violet
SetColor(2,8,6) ;blue
SetColor(4,0,0) ;black
RgbBlack(black)
RgbYellow(yellow)
RgbViolet(violet)
RgbBlue(blue)
InitRgbImage(img,width,height,ptr)
FillRgbImage(img,black)
nx=width/st ny=height/st
FOR n=0 TO 2*nx+2*ny-1
DO
IF n MOD 3=0 THEN col=yellow
ELSEIF n MOD 3=1 THEN col=violet
ELSE col=blue FI
IF n<nx THEN
x=n*st y=0
ELSEIF n<nx+ny THEN
x=width-1 y=(n-nx)*st
ELSEIF n<2*nx+ny THEN
x=width-1-(n-nx-ny)*st y=height-1
ELSE
x=0 y=height-1-(n-2*nx-ny)*st
FI
RgbLine(img,width/2,height/2,x,y,col)
OD
DrawImage(img,(160-width)/2,(96-height)/2)
DO UNTIL CH#$FF OD
CH=$FF
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Bresenham's_line_algorithm.png Screenshot from Atari 8-bit computer]
=={{header|Ada}}==
<
DX : constant Float := abs Float (Stop.X - Start.X);
DY : constant Float := abs Float (Stop.Y - Start.Y);
Line 261 ⟶ 433:
end if;
Picture (X, Y) := Color; -- Ensure dots to be drawn
end Line;</
The test program's
<
begin
Fill (X, White);
Line 270 ⟶ 442:
Line (X, (16, 8), ( 8, 1), Black);
Line (X, ( 8, 1), ( 1, 8), Black);
Print (X);</
sample output
<pre>
Line 290 ⟶ 462:
H
</pre>
=={{header|ALGOL 68}}==
{{trans|Ada}}
Line 296 ⟶ 467:
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-2.6 algol68g-2.6].}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}}
'''File: prelude/Bitmap/Bresenhams_line_algorithm.a68'''<
line OF class image := (REF IMAGE picture, POINT start, stop, PIXEL color)VOID:
Line 337 ⟶ 508:
END # line #;
SKIP</
# -*- coding: utf-8 -*- #
Line 352 ⟶ 523:
(line OF class image)(x, ( 8, 1), ( 1, 8), black OF class image);
(print OF class image)(x)
)</
<pre>
ffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffffffff
Line 371 ⟶ 542:
ffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffffffff
</pre>
=={{header|Applesoft BASIC}}==
<syntaxhighlight lang="gwbasic"> 10 HGR :FULLSCREEN = PEEK (49234)
20 HCOLOR= 3
30 FOR N = 3 TO 279 STEP 4
40 X1 = 276:Y1 = 189:X2 = N:Y2 = 1: GOSUB 100"PLOT LINE"
50 NEXT N
60 FOR N = 3 TO 191 STEP 3
70 X1 = 276:Y1 = 190:X2 = 2:Y2 = N: GOSUB 100"PLOT LINE"
80 NEXT N
90 END
100 DX = ABS (X2 - X1)
110 SX = SGN (X2 - X1)
120 DY = - ABS (Y2 - Y1)
130 SY = SGN (Y2 - Y1)
140 ERR = DX + DY
150 FOR WHILE = 0 TO 1 STEP 0
160 HPLOT X1,Y1
170 IF X1 = X2 AND Y1 = Y2 THEN RETURN
180 E2 = 2 * ERR
190 IF E2 > = DY AND X1 = X2 THEN RETURN
200 IF E2 > = DY THEN ERR = ERR + DY:X1 = X1 + SX
210 IF E2 < = DX AND Y1 = Y2 THEN RETURN
220 IF E2 < = DX THEN ERR = ERR + DX:Y1 = Y1 + SY
230 NEXT WHILE</syntaxhighlight>
=={{header|Assembly}}==
16 bit Intel 8086\80486 Assembly for dos, see [http://en.wikipedia.org/wiki/X86_assembly_language x86 assembly language].
Line 571 ⟶ 765:
END start
</pre>
=={{header|ATS}}==
See [[Bresenham_tasks_in_ATS]].
=={{header|AutoHotkey}}==
<
White := Color(255,255,255)
Bitmap := Bitmap(100,100,Blue) ;create a 100*100 blue bitmap
Line 592 ⟶ 788:
Temp1 := ErrorValue << 1, ((Temp1 > DeltaY) ? (ErrorValue += DeltaY, PosX1 += StepX) : ""), ((Temp1 < DeltaX) ? (ErrorValue += DeltaX, PosY1 += StepY) : "") ;move forward
}
}</
=={{header|AutoIt}}==
<
Func drawBresenhamLine($iX0, $iY0, $iX1, $iY1)
Line 618 ⟶ 814:
EndIf
WEnd
EndFunc ;==>drawBresenhamLine</
=={{header|bash}}==
<
function line {
Line 683 ⟶ 878:
line $((COLS/2)) $LINS $((COLS/4*3)) $((LINS/2))
line $((COLS/4*3)) $((LINS/2)) $((COLS/2)) 1
echo -e "\e[${LINS}H"</
=={{header|BASIC}}==
<
1510 REM Inputs are X1, Y1, X2, Y2: Destroys value of X1, Y1
1520 DX = ABS(X2 - X1):SX = -1:IF X1 < X2 THEN SX = 1
Line 697 ⟶ 891:
1590 IF E2 > -DX THEN ER = ER - DY:X1 = X1 + SX
1600 IF E2 < DY THEN ER = ER + DX:Y1 = Y1 + SY
1610 GOTO 1560</
=={{header|Batch File}}==
<
setlocal enabledelayedexpansion
Line 827 ⟶ 1,020:
)
)
goto :eof</
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<
Height% = 200
Line 864 ⟶ 1,056:
GCOL 1
LINE x%*2,y%*2,x%*2,y%*2
ENDPROC</
[[File:bresenham_bbc.gif]]
=={{header|C}}==
Instead of swaps in the initialisation use error calculation for both directions x and y simultaneously:
<
int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1;
Line 883 ⟶ 1,074:
if (e2 < dy) { err += dx; y0 += sy; }
}
}</
=={{header|C sharp|C#}}==
Port of the C version.
<
using System.Drawing;
using System.Drawing.Imaging;
Line 913 ⟶ 1,103:
return bitmap;
}
}</
=={{header|C++}}==
<
void Line( float x1, float y1, float x2, float y2, const Color& color )
{
Line 961 ⟶ 1,150:
}
}
</syntaxhighlight>
=={{header|Clojure}}==
<
(defn draw-line
Line 990 ⟶ 1,178:
(recur (inc x) (+ y y-step) (+ error (- delta-x delta-y)))
(recur (inc x) y (- error delta-y)))))))))))
</syntaxhighlight>
=={{header|CoffeeScript}}==
<
drawBresenhamLine = (x0, y0, x1, y1) ->
dx = Math.abs(x1 - x0)
Line 1,013 ⟶ 1,200:
y0 += sy
null
</syntaxhighlight>
=={{header|Commodore BASIC}}==
<syntaxhighlight lang="basic">
10 rem bresenham line algorihm
20 rem translated from purebasic
Line 1,055 ⟶ 1,241:
2050 if sl<(sw*sh) then poke sc+sl,pc
2060 return
</syntaxhighlight>
[https://www.worldofchris.com/assets/c64-bresenham-line.png C64 Example screenshot]
=={{header|Common Lisp}}==
<
(declare (type rgb-pixel-buffer buffer))
(declare (type integer x1 y1 x2 y2))
Line 1,087 ⟶ 1,272:
(incf y y-step)
(incf error delta-x))))
buffer))</
=={{header|D}}==
This code uses the Image defined in [[Bitmap]] Task.
<
import std.algorithm, std.math, bitmap;
Line 1,143 ⟶ 1,327:
img.textualShow();
}
}</
To run the demo code compile with <code>-version=bitmap_bresenhams_line_algorithm_main</code>.
{{out}}
Line 1,168 ⟶ 1,352:
###.###########.#########
#########################</pre>
=={{header|Delphi}}==
<
procedure drawLine (bitmap : TBitmap; xStart, yStart, xEnd, yEnd : integer; color : TAlphaColor);
// Bresenham's Line Algorithm. Byte, March 1988, pp. 249-253.
Line 1,244 ⟶ 1,427:
end;
end;
</syntaxhighlight>
=={{header|E}}==
{{trans|C}}
<
def t := left
left := right
Line 1,279 ⟶ 1,461:
}
}
}</
<
drawLine(i, 1, 1, 3, 18, makeColor.fromFloat(0,1,1))
i.writePPM(<import:java.io.makeFileOutputStream>(<file:~/Desktop/Bresenham.ppm>))</
=={{header|EasyLang}}==
[https://easylang.online/show/#cod=XZHNboMwEITvPMUeG0W4NrSHSnHehQRHQkoJMiRl3z6zePkrAsv7MTNe2118XKnrw0AjMRkyGRH9Pl4B9Sd9gWEUFsN1IGuK72nITNaJs47V371pobbElkZH7OaUeiRP1aWnD+AcioPQXmjuZNrcxHaCS6r531SkAJ4DWAJYA3gbwBLASwDvAkKMokVO3byoUAv6OiNbLUkDtkhM2m4XqkE16Xxkhwqe7dDchXjZctXW0odf+wgFKiRriUVBzuhkVKIL535tBA8Cjx6noMTs7KedVNxH6XtFnNy8dRtc1HJHhbXk5LUyXbmC6St/7N4AQOV/R7lxOJu9AQ== Run it]
{{trans|C}}
<syntaxhighlight>
proc pset x y . .
move x / 4 y / 4
rect 0.25 0.25
.
proc drawline x0 y0 x1 y1 . .
dx = abs (x1 - x0)
sx = -1
if x0 < x1
sx = 1
.
dy = abs (y1 - y0)
sy = -1
if y0 < y1
sy = 1
.
err = -dy div 2
if dx > dy
err = dx div 2
.
repeat
pset x0 y0
until x0 = x1 and y0 = y1
e2 = err
if e2 > -dx
err -= dy
x0 += sx
.
if e2 < dy
err += dx
y0 += sy
.
.
.
drawline 200 10 100 200
drawline 100 200 200 390
drawline 200 390 300 200
drawline 300 200 200 10
</syntaxhighlight>
=={{header|Elm}}==
<
Line 1,344 ⟶ 1,571:
bresenhamLineLoop statics error_ (Position x y) positions_
</syntaxhighlight>
=={{header|Erlang}}==
<
build_path({Sx, Sy}, {Tx, Ty}) ->
if
Line 1,393 ⟶ 1,620:
F2 = F0 + Dx,
through_y({Nx, Ny}, {Tx, Ty}, {StepX, StepY}, {Dx, Dy}, F2, [{Nx, Ny}|P]).
</syntaxhighlight>
OR
<
line({X0, Y0}, {X1, Y1}) ->
SX = step(X0, X1),
Line 1,426 ⟶ 1,653:
next_y(Y, _SY, _DX, E, _DE) ->
{Y, E}.
</syntaxhighlight>
=={{header|ERRE}}==
<syntaxhighlight lang="erre">
PROGRAM BRESENHAM
Line 1,460 ⟶ 1,686:
SCREEN(0)
END PROGRAM
</syntaxhighlight>
=={{header|Euphoria}}==
{{trans|C}}
<
include std/graphics.e
include std/math.e
Line 1,580 ⟶ 1,805:
--
--,respectively in the last if check.
--*/</
Output:
<pre>
Line 1,602 ⟶ 1,827:
Press Any Key to continue...
</pre>
=={{header|F Sharp|F#}}==
<
let steep = abs(y1 - y0) > abs(x1 - x0)
let x0, y0, x1, y1 =
Line 1,619 ⟶ 1,843:
else
loop (e-dy) (x+1) y
loop (dx/2) x0 y0</
The following program tests the above bresenham function by drawing 100 lines into an image and visualizing the result using
{{libheader|Windows Presentation Foundation}}:
<
open System.Windows.Media.Imaging
Line 1,638 ⟶ 1,862:
BitmapSource.Create(n, n, 1.0, 1.0, format, null, pixel, n)
Window(Content=image, Title="Bresenham's line algorithm")
|> (Application()).Run |> ignore</
=={{header|Factor}}==
A very ugly imperative implementation similar to the wikipedia pseudocode..
<
math.ranges math.vectors rosettacode.raster.display
rosettacode.raster.storage sequences ui.gadgets ;
Line 1,678 ⟶ 1,901:
: draw-line ( {R,G,B} pt1 pt2 image -- )
[ line-points ] dip
[ set-pixel ] curry with each ;</
=={{header|FBSL}}==
1. In FBSL, successive calls to one and the same subprocedure may be concatenated to a series of argument sets as in Sub Rhombus() below.
Line 1,686 ⟶ 1,908:
'''Using pure FBSL's built-in graphics functions:'''
<
#DEFINE WM_CLOSE 16
Line 1,720 ⟶ 1,942:
WEND
END SUB
END SUB</
'''Output:''' [[File:FBSLBresenham.PNG]]
=={{header|Forth}}==
<
defer ystep \ 1+ or 1-
Line 1,771 ⟶ 1,992:
** *
**
ok</
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
{{trans|C}}
<
use RCImageBasic
Line 1,845 ⟶ 2,065:
end subroutine draw_line
end module RCImagePrimitive</
Usage example:
<
use RCImageBasic
use RCImageIO
Line 1,875 ⟶ 2,095:
call free_img(animage)
end program BasicImageTests</
=={{header|FreeBASIC}}==
<
' compile with: fbc -s console
' OR compile with: fbc -s gui
Line 1,916 ⟶ 2,135:
Loop Until InKey <> "" ' loop until a key is pressed
End</
=={{header|Go}}==
<
// Line draws line by Bresenham's algorithm.
Line 1,964 ⟶ 2,182:
func (b *Bitmap) LineRgb(x0, y0, x1, y1 int, c Rgb) {
b.Line(x0, y0, x1, y1, c.Pixel())
}</
A demonstration program:
<
// Files required to build supporting package raster are found in:
Line 1,988 ⟶ 2,206:
fmt.Println(err)
}
}</
=={{header|Haskell}}==
<
import Bitmap
Line 2,023 ⟶ 2,240:
deltax = x2 - x1
deltay = abs $ y2 - y1
ystep = if y1 < y2 then 1 else -1</
=={{header|J}}==
'''Solution:'''
Using definitions from [[Basic bitmap storage#J|Basic bitmap storage]].
<
NB.*getBresenhamLine v Returns points for a line given start and end points
Line 2,044 ⟶ 2,260:
NB.*drawLines v Draws lines (x) on image (y)
NB. x is: 2-item list (start and end points) ; (color)
drawLines=: (1&{:: ;~ [: ; [: <@getBresenhamLine"2 (0&{::))@[ setPixels ]</
'''Example Usage:'''
<
myimg=: ((1 1 ,: 5 11) ; 255 0 0 ) drawLines myimg NB. draw red line from xy point 1 1 to 11 5
Line 2,055 ⟶ 2,271:
viewRGB myimg=: (Diamond;255 0 0) drawLines myimg NB. draw 4 red lines to form a diamond
viewRGB myimg=: (Square;0 0 255) drawLines myimg NB. draw 4 blue lines to form a square
viewRGB (Diamond;255 0 0) drawLines (Square;0 0 255) drawLines myimg</
=={{header|Java}}==
<
import java.awt.Dimension;
import java.awt.Graphics;
Line 2,172 ⟶ 2,387:
}
}
}</
=={{header|JavaScript}}==
Instead of swaps in the initialisation use error calculation for both directions x and y simultaneously:
<
var dx = Math.abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
Line 2,189 ⟶ 2,403:
if (e2 < dy) { err += dx; y0 += sy; }
}
}</
=={{header|Julia}}==
{{works with|Julia|0.6}}
<
δx = abs(x1 - x0)
δy = abs(y1 - y0)
Line 2,219 ⟶ 2,432:
drawline!(img, 1, 1, 5, 5, Gray(0.0));
println("\nModified image:")
display(img); println()</
{{out}}
Line 2,239 ⟶ 2,452:
Gray{Float64}(255.0) Gray{Float64}(255.0) Gray{Float64}(255.0) Gray{Float64}(255.0) Gray{Float64}(0.0) </pre>
=={{header|
<syntaxhighlight lang="ksh">function line {
typeset x0=$1 y0=$2 x1=$3 y1=$4
if ((x0 > x1))
then
((dx = x0 - x1)); ((sx = -1))
Line 2,251 ⟶ 2,463:
fi
if ((
then
((dy = y0 - y1)); ((sy = -1))
Line 2,258 ⟶ 2,470:
fi
if ((
then
((err = dx))
Line 2,266 ⟶ 2,478:
((err /= 2)); ((e2 = 0))
while
do
echo $x0 $y0
((
((e2 = err))
((
((
done
}</
Output from the statement:
line 0 0 3 4
(which could be piped to another program)
<
1 1
1 2
2 3
3 4</
=={{header|Lua}}==
{{trans|C}}
{{works with|Lua 5.1 (or above, tested on: 5.1.5, 5.2.3, 5.3.5)}}
<syntaxhighlight lang="lua">
-----------------------------------------------
-- Bitmap replacement
Line 2,375 ⟶ 2,585:
bitmap:line(60,10,30,20)
bitmap:line(30,20,0,10)
bitmap:render({[0x000000]='.', [0xFFFFFFFF]='X'})</
{{out}}<pre>.............................XXX.............................
..........................XXX...XXX..........................
Line 2,398 ⟶ 2,608:
.............................XXX.............................
</pre>
=={{header|Maple}}==
<
local deltax, deltay, x, y, ystep, steep, err, img2, x02, y02, x12, y12;
x02, x12, y02, y12 := y0, y1, x0, x1;
Line 2,436 ⟶ 2,645:
end do;
return img2;
end proc:</
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">Rasterize[Style[Graphics[Line[{{0, 0}, {20, 10}}]], Antialiasing -> False]]</syntaxhighlight>
=={{header|MATLAB}}==
Note: Store this function in a file named "bresenhamLine.m" in the @Bitmap folder for the Bitmap class defined [[Bitmap#MATLAB|here]].
[[File:Bresenham.png|thumb|MATLAB sample usage output.]]
<syntaxhighlight lang="matlab">
%screen = Bitmap object
%startPoint = [x0,y0]
Line 2,508 ⟶ 2,713:
assignin('caller',inputname(1),screen); %saves the changes to the object
end
</syntaxhighlight>
Sample Usage:
<syntaxhighlight lang="matlab">
>> img = Bitmap(800,600);
>> img.bresenhamLine([400 550],[200 400],[255 255 255]);
Line 2,520 ⟶ 2,725:
>> img.bresenhamLine([400 550],[400 150],[255 255 255]);
>> disp(img)
</syntaxhighlight>
=={{header|MAXScript}}==
<
(
if steep then
Line 2,575 ⟶ 2,779:
myBitmap = bitmap 512 512 color:(color 0 0 0)
myBitmap = drawLine myBitmap [0, 511] [511, 0] #((color 255 255 255))
display myBitmap</
=={{header|Metal}}==
For drawing lines between points in an Apple Metal compute shader.
<
void drawLine(texture2d<float, access::write> targetTexture, uint2 start, uint2 end)
Line 2,619 ⟶ 2,822:
}
}
}</
=={{header|MiniScript}}==
This GUI implementation is for use with [http://miniscript.org/MiniMicro Mini Micro].
<syntaxhighlight lang="miniscript">
drawLine = function(img, x0, y0, x1, y1, colr)
sign = function(a, b)
if a < b then return 1
return -1
end function
dx = abs(x1 - x0)
sx = sign(x0, x1)
dy = abs(y1 - y0)
sy = sign(y0, y1)
if dx > dy then
err = dx
else
err = -dy
end if
err = floor(err / 2)
while true
img.setPixel x0, y0, colr
if x0 == x1 and y0 == y1 then break
e2 = err
if e2 > -dx then
err -= dy
x0 += sx
end if
if e2 < dy then
err += dx
y0 += sy
end if
end while
end function
img= Image.create(320, 320)
drawLine img, 0, 0, 250, 300, color.red
gfx.clear
gfx.drawImage img, 0, 0
</syntaxhighlight>
=={{header|Nim}}==
<
proc
let
dx = abs(q.x - p.x)
Line 2,638 ⟶ 2,884:
while true:
img[p.x, p.y] =
if p == q:
break
Line 2,647 ⟶ 2,893:
if e2 < dy:
err += dx
p.y += sy
when isMainModule:
var img = newImage(16, 16)
img.fill(White)
img.drawLine((0, 7), (7, 15), Black)
img.drawLine((7, 15), (15, 7), Black)
img.drawLine((15, 7), (7, 0), Black)
img.drawLine((7, 0), (0, 7), Black)
img.print()</syntaxhighlight>
{{out}}
<pre>.......H........
......H.H.......
.....H...H......
....H.....H.....
...H.......HH...
..H..........H..
.H............H.
H..............H
.H............H.
..H..........H..
...H........H...
...H.......H....
....H.....H.....
.....H...H......
......H.H.......
.......H........</pre>
=={{header|OCaml}}==
<
let steep = abs(y1 - y0) > abs(x1 - x0) in
Line 2,690 ⟶ 2,962:
in
loop x0 y0 error
;;</
=={{header|Pascal}}==
[[Bresenham's_line_algorithm#Delphi | Delphi]]
=={{header|Perl}}==
{{libheader|Imlib2}}
<
use strict;
use Image::Imlib2;
Line 2,762 ⟶ 3,032:
$img->save("test1.png");
exit 0;</
Images <tt>test0.png</tt> and <tt>test1.png</tt> look different since Imlib2 draw lines with antialiasing.
=={{header|Phix}}==
Modified copy of [[Bitmap/Bresenham%27s_line_algorithm#Euphoria|Euphoria]], with a bigger bitmap and a simpler pattern.
Requires new_image() from [[Bitmap#Phix|Bitmap]], write_ppm() from [[Bitmap/Write_a_PPM_file#Phix|Write_a_PPM_file]]. <br>
<syntaxhighlight lang="phix">-- demo\rosetta\Bresenham_line.exw (runnable version)
global function bresLine(sequence image, integer x0, y0, x1, y1, colour)
integer dimx
deltaY = abs(y1-y0),
stepX = iff(x0<x1,1,-1),
stepY = iff(y0<y1,1,-1),
lineError = iff(deltaX>deltaY,deltaX,-deltaY),
prevle
lineError = round(lineError/2, 1)
while true do
if x0>=1 and x0<=dimx
and y0>=1 and y0<=dimy then
image[x0][y0] = colour
end if
if x0=x1 and y0=y1 then exit end if
Line 2,796 ⟶ 3,068:
end if
end while
return
end function
--include ppm.e -- red, green, blue, white, new_image(), write_ppm(), bresLine() (as distributed, instead of the above)
sequence screenData = new_image(400,300,black)
screenData = bresLine(screenData,100,1,50,300,red)
screenData = bresLine(screenData,1,180,400,240,green)
screenData = bresLine(screenData,200,1,400,150,white)
screenData = bresLine(screenData,195,1,205,300,blue)
write_ppm("bresenham.ppm",screenData)</syntaxhighlight>
=={{header|PicoLisp}}==
<
(let SX
(cond
Line 2,845 ⟶ 3,118:
(prinl "P1")
(prinl 120 " " 90)
(mapc prinl Img) ) )</
=={{header|PL/I}}==
===version 1===
{{incorrect|PL/I|The sample output does not start at -1/-3!?! Pls show the complete program producing this output.}}
<syntaxhighlight lang="pl/i">
/* Draw a line from (x0, y0) to (x1, y1). 13 May 2010 */
/* Based on Rosetta code proforma. */
Line 2,887 ⟶ 3,159:
end draw_line;
</syntaxhighlight>
Output from the statement:-
call draw_line(-1, -3, 6, 10);
for a -10:10 x -10:10 grid:
<syntaxhighlight lang="text">
..........|..........
..........|..........
Line 2,914 ⟶ 3,186:
..........|..........
..........|..........
</syntaxhighlight>
===version 2===
<
brbn:Proc Options(main);
/*********************************************************************
Line 2,967 ⟶ 3,239:
image(x0,y0)='X';
end;
end;</
'''output'''
<pre>11 ..|.......
Line 2,986 ⟶ 3,258:
-4 ..|.......
2101234567</pre>
=={{header|Prolog}}==
<syntaxhighlight lang="prolog">
:- use_module(bitmap).
:- use_module(bitmapIO).
Line 3,027 ⟶ 3,298:
draw_line(NB,B,[0,0,0],2,2,10,90),
write_ppm_p6('line.ppm',NB).
</syntaxhighlight>
=={{header|PureBasic}}==
<
If Abs(y1 - y0) > Abs(x1 - x0);
steep =#True
Line 3,088 ⟶ 3,358:
Until Event = #PB_Event_CloseWindow
EndIf
EndIf</
=={{header|Python}}==
{{works with|Python|3.1}}
Line 3,095 ⟶ 3,364:
Extending the example given [[Basic_bitmap_storage/Python#Alternative_version|here]] and using the algorithm from the Ada solution:
<
"Bresenham's line algorithm"
dx = abs(x1 - x0)
Line 3,152 ⟶ 3,421:
| |
+-----------------+
'''</
===Not relying on floats===
Extending the example given [[Basic_bitmap_storage/Python#Alternative_version|here]].
<
from fractions import Fraction
Line 3,174 ⟶ 3,443:
# see test code above
</syntaxhighlight>
=={{header|Racket}}==
Port of the Python version.
<
#lang racket
(require racket/draw)
Line 3,212 ⟶ 3,480:
(apply draw-line (cons dc points)))
bm
</syntaxhighlight>
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2018.03}}
Bitmap class from [[Bitmap#Raku|Bitmap]] task.
<syntaxhighlight lang="raku"
class Bitmap {
has UInt ($.width, $.height);
Line 3,269 ⟶ 3,536:
}
}
}</
=={{header|RapidQ}}==
Use this routine together with the code from [[Basic_bitmap_storage#RapidQ|Basic bitmap storage]] to create a full application.
<
x_dist = abs(x2-x1)
y_dist = abs(y2-y1)
Line 3,309 ⟶ 3,575:
END IF
END SUB</
Example usage:
<
draw_line 200, 10, 100, 200, &H00ff00
draw_line 100, 200, 200, 400, &H00ff00
draw_line 200, 400, 300, 200, &H00ff00
draw_line 300, 200, 200, 10, &H00ff00
END SUB</
=={{header|REXX}}==
=== version 1 ===
This REXX version has automatic scaling (for displaying the plot), includes a
border, accepts lines segments from the
<br>command line, displays a (background) plot field, uses an infinite field, and
it also handles multiple line segments.
<
parse arg data /*obtain optional arguments from the CL*/
if data='' then data= "(1,8) (8,16) (16,8) (8,1) (1,8)" /* ◄──── a rhombus.*/
Line 3,365 ⟶ 3,630:
if err2 > -dy then do; err= err - dy; x= x + sx; end
if err2 < dx then do; err= err + dx; y= y + sy; end
end /*forever*/</
{{out|output|text= when using the default input:}}
<pre>
Line 3,391 ⟶ 3,656:
=== version 2 ===
<
* 21.05.2014 Walter Pachl
* Implementing the pseudo code of
Line 3,434 ⟶ 3,699:
end
end
Return</
'''output'''
<pre>11 ..|.......
Line 3,453 ⟶ 3,718:
-4 ..|.......
2101234567</pre>
=={{header|Ring}}==
<
load "guilib.ring"
load "stdlib.ring"
Line 3,512 ⟶ 3,776:
}
label1 { setpicture(p1) show() }
</syntaxhighlight>
Output :
[https://lh3.googleusercontent.com/-6uJvON0dAuo/V2LO2zz4zQI/AAAAAAAAALE/IjEGFuhta6oUSeG2QfuxcPBWMmCyNCjdwCLcB/s1600/CalmoSoftBresenham.jpg Bitmap/Bresenham's algorithm]
=={{header|Ruby}}==
<
class Pixmap
Line 3,564 ⟶ 3,827:
bitmap.draw_line(Pixel[10, 10], Pixel[a,490], RGBColour::YELLOW)
end
bitmap.draw_line(Pixel[10, 10], Pixel[490,490], RGBColour::YELLOW)</
=={{header|Rust}}==
<syntaxhighlight lang="rust">
struct Point {
x: i32,
Line 3,574 ⟶ 3,836:
fn main() {
let
points.append(&mut get_coordinates(1, 20, 20, 28));
points.append(&mut get_coordinates(20, 28, 69, 0));
draw_line(points, 70, 30);
}
fn get_coordinates(x1: i32, y1: i32, x2: i32, y2: i32) -> Vec<Point> {
let mut coordinates: Vec<Point> = vec![];
let dx:i32 = i32::abs(x2 - x1);
let dy:i32 = i32::abs(y2 - y1);
let sx:i32 = { if x1 < x2 { 1 } else { -1 } };
let sy:i32 = { if
let mut error:i32 = (if dx > dy { dx } else { -dy }) / 2 ;
let mut current_x:i32 = x1;
let mut current_y:i32 = y1;
loop {
coordinates.push(Point { x : current_x, y: current_y });
if
let error2:i32 = error;
if error2 > -dx {
error -= dy;
current_x += sx;
}
error += dx;
current_y += sy;
}
}
Line 3,620 ⟶ 3,876:
let is_point_in_line = line.iter().any(| point| point.x == row && point.y == col);
match is_point_in_line {
true => print!("
_ =>
};
}
Line 3,633 ⟶ 3,883:
}
}
</syntaxhighlight>
'''Output:'''
<pre>
.....................................................................@
......................................................................
</pre>
=={{header|Scala}}==
Uses the [[Basic_bitmap_storage#Scala|Scala Basic Bitmap Storage]] class.
<
def bresenham(bm:RgbBitmap, x0:Int, y0:Int, x1:Int, y1:Int, c:Color)={
val dx=math.abs(x1-x0)
Line 3,693 ⟶ 3,942:
bm.setPixel(x, y, c)
}
}</
=={{header|Sidef}}==
{{trans|Perl}}
<
var steep = (abs(y1 - y0) > abs(x1 - x0))
Line 3,749 ⟶ 3,997:
img.draw_line(80, 10, 10, 80)
img.save("test1.png")</
=={{header|SparForte}}==
As a structured script.
<syntaxhighlight lang="ada">#!/usr/local/bin/spar
pragma annotate( summary, "DrawLine" )
@( description, "Draw a line given 2 points with the Bresenham's algorithm." )
@( see_also, "http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm" )
@( author, "Ken O. Burtch" );
pragma license( unrestricted );
pragma restriction( no_external_commands );
procedure drawline is
-- Spar 1.x has only single-dimensional arrays but we can simulate a
-- two dimensional array that has been folded into a 1D array
width : constant positive := 20;
height : constant positive := 20;
type image_array is array(1..400) of character;
Picture : image_array;
-- Line
-- Draw a line between two coordinates using the given character
procedure Line ( Start_X : positive; Start_Y : positive; Stop_X : positive; Stop_Y : positive; Color : character) is
-- at this point, formal parameters are defined but the actual values aren't defined!
-- but creating a dummy Line in a test script works?
DX : constant float := abs( float( Stop_X ) - float( Start_X ) );
DY : constant float := abs( float( Stop_Y ) - float( Start_Y ) );
Err : float;
X : positive := Start_X;
Y : positive := Start_Y;
Step_X : integer := 1;
Step_Y : integer := 1;
begin
if Start_X > Stop_X then
Step_X := -1;
end if;
if Start_Y > Stop_Y then
Step_Y := -1;
end if;
if DX > DY then
Err := DX / 2.0;
while X /= Stop_X loop
Picture (X + width*(Y-1)) := Color;
Err := @ - DY;
if Err < 0.0 then
Y := positive( integer(@) + Step_Y);
Err := @ + DX;
end if;
X := positive( integer(@) + Step_X );
end loop;
else
Err := DY / 2.0;
while Y /= Stop_Y loop
Picture (X + height*(Y-1)) := Color;
Err := @ - DX;
if Err < 0.0 then
X := positive( integer(@) + Step_X );
Err := @ + DY;
end if;
Y := positive( integer(@) + Step_Y );
end loop;
end if;
Picture (X + width*(Y-1)) := Color;
end Line;
-- new_picture
-- Erase the picture by filling it with spaces.
procedure new_picture is
begin
for i in arrays.first( Picture )..arrays.last( Picture ) loop
Picture(i) := ' ';
end loop;
end new_picture;
-- render
-- Draw the contents of the picture area.
procedure render is
begin
for i in arrays.first( Picture )..arrays.last( Picture ) loop
put( Picture(i) );
if i mod width = 0 then
new_line;
end if;
end loop;
end render;
begin
new_picture;
Line( 1, 8, 8, 16, 'X' );
Line( 8,16,16, 8, 'X' );
Line(16, 8, 8, 1, 'X' );
Line( 8, 1, 1, 8, 'X' );
render;
end drawline;</syntaxhighlight>
=={{header|Tcl}}==
{{libheader|Tk}}
ref [[Basic bitmap storage#Tcl]]
<
package require Tk
Line 3,792 ⟶ 4,141:
fill $img black
drawLine $img yellow {20 20} {180 80}
drawLine $img yellow {180 20} {20 80}</
=={{header|TI-89 BASIC}}==
Line 3,800 ⟶ 4,148:
{{trans|E}}
<
Prgm
Local steep, x, y, dx, dy, ystep, error, tmp
Line 3,833 ⟶ 4,181:
EndIf
EndFor
EndPrgm</
=={{header|VBScript}}==
{{trans|Rexx}}
<
Dim map(48,40), list(10), ox, oy
data=Array(1,8, 8,16, 16,8, 8,1, 1,8)
Line 3,889 ⟶ 4,236:
If err2< dx Then err=err+dx: y=y+sy
Loop
End Sub 'draw_line </
{{out}}
<pre>
Line 3,913 ⟶ 4,260:
...|....................
</pre>
=={{header|Vedit macro language}}==
<
// #1=x1, #2=y1; #3=x2, #4=y2
Line 3,954 ⟶ 4,300:
}
Num_Pop(31,35)
return</
=={{header|Wart}}==
<
def (line x0 y0 x1 y1)
let steep ((> abs) y1-y0 x1-x0)
Line 3,978 ⟶ 4,323:
when (error < 0)
y += ystep
error += deltax</
=={{header|Wren}}==
{{libheader|DOME}}
Requires version 1.3.0 of DOME or later.
<syntaxhighlight lang="wren">import "graphics" for Canvas, ImageData, Color
import "dome" for Window
class Game {
static bmpCreate(name, w, h) { ImageData.create(name, w, h) }
static bmpFill(name, col) {
var image = ImageData[name]
for (x in 0...image.width) {
for (y in 0...image.height) image.pset(x, y, col)
}
}
static bmpPset(name, x, y, col) { ImageData[name].pset(x, y, col) }
static bmpPget(name, x, y) { ImageData[name].pget(x, y) }
static bmpLine(name, x0, y0, x1, y1, col) {
var dx = (x1 - x0).abs
var dy = (y1 - y0).abs
var sx = (x0 < x1) ? 1 : -1
var sy = (y0 < y1) ? 1 : -1
var err = ((dx > dy ? dx : - dy) / 2).floor
while (true) {
bmpPset(name, x0, y0, col)
if (x0 == x1 && y0 == y1) break
var e2 = err
if (e2 > -dx) {
err = err - dy
x0 = x0 + sx
}
if (e2 < dy) {
err = err + dx
y0 = y0 + sy
}
}
}
static init() {
Window.title = "Bresenham's line algorithm"
var size = 200
Window.resize(size, size)
Canvas.resize(size, size)
var name = "bresenham"
var bmp = bmpCreate(name, size, size)
bmpFill(name, Color.white)
bmpLine(name, 50, 100, 100, 190, Color.black)
bmpLine(name, 100, 190, 150, 100, Color.black)
bmpLine(name, 150, 100, 100, 10, Color.black)
bmpLine(name, 100, 10, 50, 100, Color.black)
bmp.draw(0, 0)
}
static update() {}
static draw(alpha) {}
}</syntaxhighlight>
=={{header|XPL0}}==
Bresenham line draw is built-in.
<
[SetVid($112); \set 640x480 graphics in 24-bit color
Move(10, 20); \set start of line segment
Line 3,988 ⟶ 4,393:
if ChIn(1) then []; \wait for keystroke while viewing graphic screen
SetVid(3); \restore normal text mode
]</
=={{header|zkl}}==
[[File:Line.zkl.jpg|200px|thumb]]
Algorithm from Wikipedia plus other functions so I can reference this code in other examples.
<
ppm.line(50,100, 100,190, 0);
ppm.line(100,190, 150,100, 0);
Line 3,999 ⟶ 4,403:
ppm.line(100,10, 50,100, 0);
ppm.writeJPGFile("line.jpg");</
<
fcn init(width,height,rgb=0){
sz:=width*height;
Line 4,089 ⟶ 4,493:
}
}
}</
{{omit from|AWK}}
{{omit from|PARI/GP}}
|