Just another update

This commit is contained in:
Ingy döt Net 2015-02-20 00:35:01 -05:00
parent a25938f123
commit 00a190b0a6
6591 changed files with 94363 additions and 23227 deletions

View file

@ -1 +1 @@
Using the data storage type defined [[Basic_bitmap_storage|on this page]] for raster graphics images, draw a line given 2 points with the [[wp:Bresenham's_line_algorithm|Bresenham's algorithm]].
Using the data storage type defined [[Basic_bitmap_storage|on this page]] for raster graphics images, draw a line given 2 points with the [[wp:Bresenham's line algorithm|Bresenham's line algorithm]].

View file

@ -0,0 +1,128 @@
@echo off
setlocal enabledelayedexpansion
set width=87
set height=51
mode %width%,%height%
set "grid="
set /a resolution=height*width
for /l %%i in (1,1,%resolution%) do (
set "grid=!grid! "
)
call :line 1 1 5 5
call :line 9 30 60 7
call :line 9 30 60 50
call :line 52 50 32 1
echo:%grid%
pause>nul
exit
:line
set x1=%1
set y1=%2
set x2=%3
set y2=%4
set /a dx=x2-x1
set /a dy=y2-y1
::Clipping done to avoid overflow
if %dx% neq 0 set /a o=y1 - ( x1 * dy / dx )
if %x1% leq %x2% (
if %x1% geq %width% goto :eof
if %x2% lss 0 goto :eof
if %x1% lss 0 (
if %dx% neq 0 set y1=%o%
set x1=0
)
if %x2% geq %width% (
set /a x2= width - 1
if %dx% neq 0 set /a "y2= x2 * dy / dx + o"
)
) else (
if %x2% geq %width% goto :eof
if %x1% lss 0 goto :eof
if %x2% lss 0 (
if %dx% neq 0 set y2=%o%
set x2=0
)
if %x1% geq %width% (
set /a x1=width - 1
if %dx% neq 0 set /a "y1= x1 * dy / dx + o"
)
)
if %y1% leq %y2% (
if %y1% geq %height% goto :eof
if %y2% lss 0 goto :eof
if %y1% lss 0 (
set y1=0
if %dx% neq 0 set /a x1= - o * dx /dy
)
if %y2% geq %height% (
set /a y2=height-1
if %dx% neq 0 set /a "x2= (y2 - o) * dx /dy"
)
) else (
if %y2% geq %height% goto :eof
if %y1% lss 0 goto :eof
if %y2% lss 0 (
set y2=0
if %dx% neq 0 set /a "x2= - o * dx /dy"
)
if %y1% geq %height% (
set /a y1=height-1
if %dx% neq 0 set /a "x1= (y1 - o) * dx /dy"
)
)
:: Start of Bresenham's algorithm
set stepy=1
set stepx=1
set /a dx=x2-x1
set /a dy=y2-y1
if %dy% lss 0 set /a "dy=-dy","stepy=-1"
if %dx% lss 0 set /a "dx=-dx","stepx=-1"
set /a "dy <<= 1"
set /a "dx <<= 1"
if %dx% gtr %dy% (
set /a "fraction=dy-(dx>>1)"
set /a "cursor=y1*width + x1"
for /l %%x in (%x1%,%stepx%,%x2%) do (
set /a cursorP=cursor+1
for /f "tokens=1-2" %%g in ("!cursor! !cursorP!") do set "grid=!grid:~0,%%g!Û!grid:~%%h!"
if !fraction! geq 0 (
set /a y1+=stepy
set /a cursor+=stepy*width
set /a fraction-=dx
)
set /a fraction+=dy
set /a cursor+=stepx
)
) else (
set /a "fraction=dx-(dy>>1)"
set /a "cursor=y1*width + x1"
for /l %%y in (%y1%,%stepy%,%y2%) do (
set /a cursorP=cursor+1
for /f "tokens=1-2" %%g in ("!cursor! !cursorP!") do set "grid=!grid:~0,%%g!Û!grid:~%%h!"
if !fraction! geq 0 (
set /a x1+=stepx
set /a cursor+=stepx
set /a fraction-=dy
)
set /a fraction+=dx
set /a cursor+=width*stepy
)
)
goto :eof

View file

@ -26,19 +26,19 @@ void Line( const float x1, const float y1, const float x2, const float y2, const
for(int x=(int)x1; x<maxX; x++)
{
if(steep)
{
SetPixel(y,x, color);
}
{
SetPixel(y,x, color);
}
else
{
SetPixel(x,y, color);
}
{
SetPixel(x,y, color);
}
error -= dy;
if(error < 0)
{
y += ystep;
error += dx;
}
error -= dy;
if(error < 0)
{
y += ystep;
error += dx;
}
}
}

View file

@ -1,20 +1,20 @@
(defn draw-line
"Draw a line from x1,y1 to x2,y2 using Bresenham's, to a java BufferedImage in the colour of pixel."
[buffer x1 y1 x2 y2 pixel]
(let [dist-x (abs (- x1 x2))
dist-y (abs (- y1 y2))
(let [dist-x (Math/abs (- x1 x2))
dist-y (Math/abs (- y1 y2))
steep (> dist-y dist-x)]
(let [[x1 y1 x2 y2] (if steep [y1 x1 y2 x2] [x1 y1 x2 y2])]
(let [[x1 y1 x2 y2] (if (> x1 x2) [x2 y2 x1 y1] [x1 y1 x2 y2])]
(let [delta-x (- x2 x1)
delta-y (abs (- y1 y2))
delta-y (Math/abs (- y1 y2))
y-step (if (< y1 y2) 1 -1)]
(let [plot (if steep
#(.setRGB buffer (int %1) (int %2) pixel)
#(.setRGB buffer (int %2) (int %1) pixel))]
(loop [x x1 y y1 error (floor delta-x 2) ]
(loop [x x1 y y1 error (Math/floor (/ delta-x 2)) ]
(plot x y)
(if (< x x2)
; Rather then rebind error, test that it is less than delta-y rather than zero

View file

@ -3,26 +3,26 @@
(declare (type integer x1 y1 x2 y2))
(declare (type rgb-pixel pixel))
(let* ((dist-x (abs (- x1 x2)))
(dist-y (abs (- y1 y2)))
(steep (> dist-y dist-x)))
(dist-y (abs (- y1 y2)))
(steep (> dist-y dist-x)))
(when steep
(psetf x1 y1 y1 x1
x2 y2 y2 x2))
x2 y2 y2 x2))
(when (> x1 x2)
(psetf x1 x2 x2 x1
y1 y2 y2 y1))
y1 y2 y2 y1))
(let* ((delta-x (- x2 x1))
(delta-y (abs (- y1 y2)))
(error (floor delta-x 2))
(y-step (if (< y1 y2) 1 -1))
(y y1))
(delta-y (abs (- y1 y2)))
(error (floor delta-x 2))
(y-step (if (< y1 y2) 1 -1))
(y y1))
(loop
:for x :upfrom x1 :to x2
:do (progn (if steep
(setf (rgb-pixel buffer x y) pixel)
(setf (rgb-pixel buffer y x) pixel))
(setf error (- error delta-y))
(when (< error 0)
(incf y y-step)
(incf error delta-x)))))
:for x :upfrom x1 :to x2
:do (if steep
(setf (rgb-pixel buffer x y) pixel)
(setf (rgb-pixel buffer y x) pixel))
(setf error (- error delta-y))
(when (< error 0)
(incf y y-step)
(incf error delta-x))))
buffer))

View file

@ -6,7 +6,7 @@ void drawLine(Color)(Image!Color img,
size_t x1, size_t y1,
in size_t x2, in size_t y2,
in Color color)
pure nothrow {
pure nothrow @nogc {
immutable int dx = x2 - x1;
immutable int ix = (dx > 0) - (dx < 0);
immutable size_t dx2 = abs(dx) * 2;

View file

@ -0,0 +1,72 @@
procedure drawLine (bitmap : TBitmap; xStart, yStart, xEnd, yEnd : integer; color : TAlphaColor);
// Bresenham's Line Algorithm. Byte, March 1988, pp. 249-253.
// Modified from http://www.efg2.com/Lab/Library/Delphi/Graphics/Bresenham.txt and tested.
var
a, b : integer; // displacements in x and y
d : integer; // decision variable
diag_inc : integer; // d's increment for diagonal steps
dx_diag : integer; // diagonal x step for next pixel
dx_nondiag : integer; // nondiagonal x step for next pixel
dy_diag : integer; // diagonal y step for next pixel
dy_nondiag : integer; // nondiagonal y step for next pixel
i : integer; // loop index
nondiag_inc: integer; // d's increment for nondiagonal steps
swap : integer; // temporary variable for swap
x,y : integer; // current x and y coordinates
begin
x := xStart; // line starting point}
y := yStart;
// Determine drawing direction and step to the next pixel.
a := xEnd - xStart; // difference in x dimension
b := yEnd - yStart; // difference in y dimension
// Determine whether end point lies to right or left of start point.
if a < 0 then // drawing towards smaller x values?
begin
a := -a; // make 'a' positive
dx_diag := -1
end
else
dx_diag := 1;
// Determine whether end point lies above or below start point.
if b < 0 then // drawing towards smaller x values?
begin
b := -b; // make 'a' positive
dy_diag := -1
end
else
dy_diag := 1;
// Identify octant containing end point.
if a < b then
begin
swap := a;
a := b;
b := swap;
dx_nondiag := 0;
dy_nondiag := dy_diag
end
else
begin
dx_nondiag := dx_diag;
dy_nondiag := 0
end;
d := b + b - a; // initial value for d is 2*b - a
nondiag_inc := b + b; // set initial d increment values
diag_inc := b + b - a - a;
for i := 0 to a do
begin /// draw the a+1 pixels
drawPixel (bitmap, x, y, color);
if d < 0 then // is midpoint above the line?
begin // step nondiagonally
x := x + dx_nondiag;
y := y + dy_nondiag;
d := d + nondiag_inc // update decision variable
end
else
begin // midpoint is above the line; step diagonally}
x := x + dx_diag;
y := y + dy_diag;
d := d + diag_inc
end;
end;
end;

View file

@ -0,0 +1,93 @@
import java.awt.*;
import javax.swing.*;
public class Bresenham extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame f = new Bresenham();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
f.add(new BresenhamPanel(), BorderLayout.CENTER);
f.setTitle("Bresenham");
f.setResizable(false);
f.pack();
f.setLocationRelativeTo(null);
}
});
}
}
class BresenhamPanel extends JPanel {
final int centerX, centerY;
public BresenhamPanel() {
int w = 600;
int h = 500;
centerX = w / 2;
centerY = h / 2;
setPreferredSize(new Dimension(w, h));
setBackground(Color.white);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
drawLine(g, 0, 0, 8, 19); // NNE
drawLine(g, 0, 0, 19, 8); // ENE
drawLine(g, 0, 0, 19, -8); // ESE
drawLine(g, 0, 0, 8, -19); // SSE
drawLine(g, 0, 0, -8, -19); // SSW
drawLine(g, 0, 0, -19, -8); // WSW
drawLine(g, 0, 0, -19, 8); // WNW
drawLine(g, 0, 0, -8, 19); // NNW
}
private void plot(Graphics g, int x, int y) {
g.setColor(Color.black);
g.drawOval(centerX + (x * 10), centerY + (-y * 10), 10, 10);
}
private void drawLine(Graphics g, int x1, int y1, int x2, int y2) {
// delta of exact value and rounded value of the dependant variable
int d = 0;
int dy = Math.abs(y2 - y1);
int dx = Math.abs(x2 - x1);
int dy2 = (dy << 1); // slope scaling factors to avoid floating
int dx2 = (dx << 1); // point
int ix = x1 < x2 ? 1 : -1; // increment direction
int iy = y1 < y2 ? 1 : -1;
if (dy <= dx) {
for (;;) {
plot(g, x1, y1);
if (x1 == x2)
break;
x1 += ix;
d += dy2;
if (d > dx) {
y1 += iy;
d -= dx2;
}
}
} else {
for (;;) {
plot(g, x1, y1);
if (y1 == y2)
break;
y1 += iy;
d += dx2;
if (d > dy) {
x1 += ix;
d -= dy2;
}
}
}
}
}

View file

@ -0,0 +1,51 @@
*process source xref or(!);
brbn:Proc Options(main);
/*********************************************************************
* 21.05.2014 Walter Pachl
* Implementing the pseudo code of
* http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
* under 'Simplification' (see also REXX version 2)
*********************************************************************/
grid.=
dcl image(-2:7,-4:11) char(1);
image='.';
image(*,0)='-';
image(0,*)='|';
image(0,0)='+';
call draw_line(-1,-3,6,10);
Dcl (i,j) Bin Fixed(31);
Do j=11 To -4 By -1;
Put Edit(j,' ')(Skip,f(2),a);
Do i=-2 To 7;
Put Edit(image(i,j))(a);
End;
End;
Put Edit(' 2101234567')(Skip,a);
draw_line: procedure (x0,y0,x1,y1);
dcl (x0,y0,x1,y1) fixed binary(31);
dcl (dx,dy,sx,sy,err,e2) fixed binary(31);
dx = abs(x1-x0);
dy = abs(y1-y0);
if x0 < x1 then sx = 1;
else sx = -1;
if y0 < y1 then sy = 1;
else sy = -1;
err = dx-dy;
Do Until(x0=x1&y0=y1);
image(x0,y0)='X';
e2=err*2;
if e2>-dy then do;
err=err-dy;
x0=x0+sx;
End;
if e2<dx then do;
err=err+dx;
y0=y0+sy;
End;
End;
image(x0,y0)='X';
end;
end;

View file

@ -0,0 +1,36 @@
use_module(library(pce)).
lindraw(X1,Y1,X2,Y2):-
new(Win,window("Line")),
new(Pix,pixmap(@nil,black,white,X2+30,Y2+30)),
send(Win,size,size(400,400)),
draw_line(Pix,X1,Y1,X2,Y2),
new(Bmp,bitmap(Pix)),
send(Win,display,Bmp,point(0,0)),
send(Win,open).
draw_recursive_line(_Pict,X,X,_DX,_DY,Y,Y,_D,_Sx,_Sy).%Don't iterate if X and X2 are the same number
draw_recursive_line(Pict,X,X2,DX,DY,Y,Y2,C,Sx,Sy):-
( C>0->%If the difference is greater than one, add Y one to Y.
Y1 is Y+Sy,
send(Pict,pixel(X,Y1,colour(black))),
C2 is C+(2*DY-2*DX);
Y1 is Y,
send(Pict,pixel(X,Y,colour(black))),
C2 is C+(2*DY)),
X0 is X+Sx,%The next iteration
draw_recursive_line(Pict,X0,X2,DX,DY,Y1,Y2,C2,Sx,Sy).
isneg(X,O):-
( X<0->
O is -1;
( X\==0->
O is 1;
O is 0)).
draw_line(Pict,X1,Y1,X2,Y2):-
DY is abs(Y2-Y1),
DX is abs(X2-X1),
isneg(DX,Sx),
isneg(DY,Sy),
D = 2*DY-DX,%The slope of the line
draw_recursive_line(Pict,X1,X2,DX,DY,Y1,Y2,D,Sx,Sy).

View file

@ -0,0 +1,43 @@
/*REXX program plots/draws line(s) using the Bresenham's line algorithm.*/
@.='·' /*fill the array with middle─dots*/
parse arg data /*allow data point specifications*/
if data='' then data= '(1,8) (8,16) (16,8) (8,1) (1,8)' /*rhombus*/
data=translate(data,,'()[]{}/,:;') /*elide chaff from data points. */
/* [↓] data pt pairs ──► !.array.*/
do points=1 while data\='' /*put data points into an array. */
parse var data x y data; !.points=x y /*extract line segments.*/
if points==1 then do; minX=x; maxX=x; minY=y; maxY=y; end /*1st case*/
minX=min(minX,x); maxX=max(maxX,x); minY=min(minY,y); maxY=max(maxY,y)
end /*points*/ /* [↑] data points pairs in !. */
border=2 /*border=extra space around plot.*/
minX=minX-border*2; maxX=maxX+border*2 /*min,max X for the plot display.*/
minY=minY-border ; maxY=maxY+border /* " " Y " " " " */
do x=minX to maxX; @.x.0=''; end /*draw dash from left──► right.*/
do y=minY to maxY; @.0.y=''; end /*draw pipe from lowest──►highest*/
@.0.0='' /*define the plot's axis point. */
do seg=2 to points-1; _=seg-1 /*obtain the X,Y line coördinates*/
call draw_line !._, !.seg /*draw (plot) a line segment. */
end /*seg*/ /* [↑] drawing the line segments*/
/* [↓] display the plot to term.*/
do y=maxY to minY by -1; _= /*display plot one line at a time*/
do x=minX to maxX /*traipse throught the X axis. */
_=_ || @.x.y /*construct a "line" of the plot.*/
end /*x*/ /*(a line is a "row" of points.) */
say _ /*display a "line" of the plot. */
end /*y*/ /* [↑] all done ploting the pts.*/
exit /*stick a fork in it, we're done.*/
/*────────────────────────────────DRAW_LINE subroutine──────────────────*/
draw_line: procedure expose @.; parse arg x y,xf yf; plotChar='Θ'
dx=abs(xf-x); if x<xf then sx=+1 /*obtain X range, determine slope*/
else sx=-1
dy=abs(yf-y); if y<yf then sy=+1 /*obtain Y range, determine slope*/
else sy=-1
err=dx-dy /*calc error between adjustments.*/
do forever; @.x.y=plotChar /*plot the points until complete.*/
if x=xf & y=yf then leave /*are plot points at the finish? */
err2=err+err /*this is faster than err*2. */
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*/
return

View file

@ -0,0 +1,44 @@
/* REXX ***************************************************************
* 21.05.2014 Walter Pachl
* Implementing the pseudo code of
* http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
* under 'Simplification'
**********************************************************************/
grid.='.'
Do i=-2 To 7; grid.i.0='-'; End
Do j=-4 To 11; grid.0.j='|'; End
grid.0.0='+'
Call line -1,-3,6,10
Do j=11 To -4 By -1
ol=format(j,2)' '
Do i=-2 To 7
ol=ol||grid.i.j
End
Say ol
End
Say ' 2101234567'
Exit
line: Procedure Expose grid.
Parse Arg x0, y0, x1, y1
dx = abs(x1-x0)
dy = abs(y1-y0)
if x0 < x1 then sx = 1
else sx = -1
if y0 < y1 then sy = 1
else sy = -1
err = dx-dy
Do Forever
grid.x0.y0='X'
if x0 = x1 & y0 = y1 Then Leave
e2 = 2*err
if e2 > -dy then do
err = err - dy
x0 = x0 + sx
end
if e2 < dx then do
err = err + dx
y0 = y0 + sy
end
end
Return

View file

@ -1,64 +0,0 @@
/*REXX program plots/draws a line using the Bresenham's line algorithm. */
EoE = 1000 /*EOE = End Of Earth, er, plot. */
image. = 'fa'x /*fill the array with middle-dots*/
plotC = 'fe'x /*character used for plotting pts*/
do j=-EoE to +EoE /*draw grid from lowest──>highest*/
image.j.0 = '' /*draw the horizontal axis. */
image.0.j = '' /* " " verical " */
end /*j*/
image.0.0='' /*"draw" the axis origin. */
parse arg xi yi xf yf . /*allow specifying line-end pts. */
if xi=='' | xi==',' then xi = -1 /*if not specified, use default. */
if yi=='' | yi==',' then yi = -3 /* " " " " " */
if xf=='' | xf==',' then xf = 6 /* " " " " " */
if yf=='' | yf==',' then yf = 10 /* " " " " " */
call draw_line xi, yi, xf, yf /*call subroutine and draw line. */
call findMaxXY
do y=maxY by -1 to minY; aRow=
do x=minX to maxX
aRow=aRow || image.x.y
end /*x*/
say aRow
end /*y*/
exit
/*────────────────────────────────DRAW_LINE subroutine──────────────────*/
draw_line: procedure expose image. plotC; error=0
parse arg xi 1 x0, yi 1 y0 1 y, xf 1 x1, yf 1 y1
steep= abs(y1-y0) > abs(x1-x0)
if steep then parse value x0 y0 x1 y1 with y0 x0 y1 x1
if x0>x1 then parse value x0 x1 y0 y1 with x1 x0 y1 y0
if y0<y1 then yInc = 1
else yInc = -1
deltaE=abs(y1-y0) / (x1-x0)
do x=x0 to x1
if steep then image.y.x=plotC
else image.x.y=plotC
error=error+deltaE
if error>=.5 then do; y=y+yInc; error=error-1; end
end
return
/*────────────────────────────────FINDMAXXY subroutine──────────────────*/
findMaxXY: extra=3 /*don't just show cropped plot. */
do minX=-EoE to +EoE /*find min X in the plot field. */
do y=-EoE to +EoE; if .isP(image.minX.y) then leave minX; end /*y*/
end /*minX*/
do maxX=+EoE to -EoE by -1 /*find max X in the plot field. */
do y=-EoE to +EoE; if .isP(image.maxX.y) then leave maxX; end /*y*/
end /*maxX*/
do minY=-EoE to +EoE /*find min Y in the plot field. */
do x=-EoE to +EoE; if .isP(image.x.minY) then leave minY; end /*x*/
end /*minY*/
do maxY=+EoE to -EoE by -1 /*find max Y in the plot field. */
do x=-EoE to +EoE; if .isP(image.X.maxy) then leave maxY; end /*x*/
end /*maxY*/
minX=minX-extra*2; minY=minY-extra /*like showbiz, show a little more*/
maxX=maxX+extra*2; maxY=maxY+extra /* " " " " " " */
return /*go ye forth and show ye plot. */
.isP: return pos(arg(1),plotC)\==0