September 2017 Update
This commit is contained in:
parent
bba7bfd280
commit
ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions
|
|
@ -15,7 +15,7 @@
|
|||
LOCAL dx%, dy%, sx%, sy%, e
|
||||
dx% = ABS(x2% - x1%) : sx% = SGN(x2% - x1%)
|
||||
dy% = ABS(y2% - y1%) : sy% = SGN(y2% - y1%)
|
||||
IF dx% < dy% e = dx% / 2 ELSE e = dy% / 2
|
||||
IF dx% > dy% e = dx% / 2 ELSE e = dy% / 2
|
||||
REPEAT
|
||||
PROCsetpixel(x1%,y1%,r%,g%,b%)
|
||||
IF x1% = x2% IF y1% = y2% EXIT REPEAT
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
-- Brensenham Line Algorithm
|
||||
|
||||
type alias Position =
|
||||
{x: Int, y: Int}
|
||||
|
||||
type alias BresenhamStatics =
|
||||
{ finish : Position
|
||||
, sx : Int
|
||||
, sy : Int
|
||||
, dx : Float
|
||||
, dy : Float
|
||||
}
|
||||
|
||||
|
||||
line : Position -> Position -> List Position
|
||||
line p q =
|
||||
let
|
||||
dx = (toFloat << abs) (q.x - p.x)
|
||||
dy = (toFloat << abs) (q.y - p.y)
|
||||
|
||||
sx = if p.x < q.x then 1 else -1
|
||||
sy = if p.y < q.y then 1 else -1
|
||||
|
||||
error =
|
||||
(if dx > dy then dx else -dy) / 2
|
||||
|
||||
statics =
|
||||
BresenhamStatics q sx sy dx dy
|
||||
in
|
||||
bresenhamLineLoop statics error p []
|
||||
|
||||
|
||||
bresenhamLineLoop : BresenhamStatics -> Float -> Position -> List Position -> List Position
|
||||
bresenhamLineLoop statics error p positions =
|
||||
let
|
||||
positions_ = p :: positions
|
||||
{sx, sy, dx, dy, finish} = statics
|
||||
in
|
||||
if (p.x == finish.x) && (p.y == finish.y) then
|
||||
positions_
|
||||
else
|
||||
let
|
||||
(dErrX, x) =
|
||||
if error > -dx then (-dy, sx + p.x)
|
||||
else (0, p.x)
|
||||
|
||||
(dErrY, y) =
|
||||
if error < dy then (dx, sy + p.y)
|
||||
else (0, p.y)
|
||||
|
||||
error_ = error + dErrX + dErrY
|
||||
in
|
||||
bresenhamLineLoop statics error_ (Position x y) positions_
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
// version 1.1.2
|
||||
|
||||
import java.awt.*
|
||||
import javax.swing.*
|
||||
|
||||
class Bresenham(w: Int, h: Int) : JPanel() {
|
||||
private val centerX = w / 2
|
||||
private val centerY = h / 2
|
||||
|
||||
init {
|
||||
preferredSize = Dimension(w, h)
|
||||
background = Color.blue
|
||||
}
|
||||
|
||||
override fun paintComponent(g: Graphics) {
|
||||
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 fun plot(g: Graphics, x: Int, y: Int) {
|
||||
g.color = Color.white
|
||||
g.drawOval(centerX + x * 10, centerY -y * 10, 10, 10)
|
||||
}
|
||||
|
||||
private fun drawLine(g: Graphics, x1: Int, y1: Int, x2: Int, y2: Int) {
|
||||
var d = 0
|
||||
val dy = Math.abs(y2 - y1)
|
||||
val dx = Math.abs(x2 - x1)
|
||||
val dy2 = dy shl 1
|
||||
val dx2 = dx shl 1
|
||||
val ix = if (x1 < x2) 1 else -1
|
||||
val iy = if (y1 < y2) 1 else -1
|
||||
var xx = x1
|
||||
var yy = y1
|
||||
|
||||
if (dy <= dx) {
|
||||
while (true) {
|
||||
plot(g, xx, yy)
|
||||
if (xx == x2) break
|
||||
xx += ix
|
||||
d += dy2
|
||||
if (d > dx) {
|
||||
yy += iy
|
||||
d -= dx2
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (true) {
|
||||
plot(g, xx, yy)
|
||||
if (yy == y2) break
|
||||
yy += iy
|
||||
d += dx2
|
||||
if (d > dy) {
|
||||
xx += ix
|
||||
d -= dy2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
SwingUtilities.invokeLater {
|
||||
val f = JFrame()
|
||||
f.defaultCloseOperation = JFrame.EXIT_ON_CLOSE
|
||||
f.isVisible = true
|
||||
f.add(Bresenham(600, 500), BorderLayout.CENTER)
|
||||
f.title = "Bresenham"
|
||||
f.isResizable = false
|
||||
f.pack()
|
||||
f.setLocationRelativeTo(null)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
ppm:=PPM(200,200,0xFF|FF|FF);
|
||||
ppm.line(50,100, 100,190, 0);
|
||||
ppm.line(100,190, 150,100, 0);
|
||||
ppm.line(150,100, 100,10, 0);
|
||||
ppm.line(100,10, 50,100, 0);
|
||||
|
||||
ppm.writeJPGFile("line.jpg");
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
class PPM{ // (0,0) is logically bottom left
|
||||
fcn init(width,height,rgb=0){
|
||||
sz:=width*height;
|
||||
var [const]
|
||||
data=Data(sz*3).fill(rgb.toBigEndian(3).toData()), // initialize to 24bit Black (RGB=000)
|
||||
w=width, h=height;
|
||||
}
|
||||
fcn fill(rgb){ data.fill(rgb.toBigEndian(3).toData()) }
|
||||
fcn __sGet(x,y) { data.toBigEndian(3*y*w + 3*x,3); } //ppm[x,y]
|
||||
fcn __sSet(rgb,x,y){ data[3*y*w + x*3,3]=rgb.toBigEndian(3); rgb } //ppm[x,y]=rgb
|
||||
fcn write(out,raw=False){ // write bottom to top to move (0,0) from top left to bottom left
|
||||
out.write("P6\n#rosettacode PPM\n%d %d\n255\n".fmt(w,h));
|
||||
if(raw) out.write(data);
|
||||
else [h-1..0, -1].pump(out,'wrap(h){ data.seek(3*h*w); data.read(3*w) });
|
||||
}
|
||||
fcn writeJPGFile(fname){ // Linux, using imagemagick
|
||||
System.popen(0'|convert ppm:- jpg:"%s"|.fmt(fname),"w") :
|
||||
write(_,vm.pasteArgs(1));
|
||||
}
|
||||
fcn readJPGFile(fileName){ // Linux, using imagemagick
|
||||
p:=System.popen("convert \"%s\" ppm:-".fmt(fileName),"r");
|
||||
img:=PPM.readPPM(p);
|
||||
p.close();
|
||||
img
|
||||
}
|
||||
fcn readPPMFile(fileName){
|
||||
f:=File(fileName,"rb"); ppm:=readPPM(f); f.close();
|
||||
ppm
|
||||
}
|
||||
fcn readPPM(image){ // image is a PPM byte stream
|
||||
// header is "P6\n[#comment\n]<w> <h>\nmaxPixelValue\n
|
||||
image.readln(); // "P6"
|
||||
while("#"==(text:=image.readln().strip())[0]){}
|
||||
w,h:=text.split().apply("toInt");
|
||||
image.readln(); // max pixel value
|
||||
ppm,sz,buffer:=PPM(w,h), 3*w, Data(sz);
|
||||
ppm.data.clear(); // gonna write file image data
|
||||
// image is stored upside down in my data structure
|
||||
do(h){ ppm.data.insert(0, image.read(sz,buffer)) }
|
||||
ppm
|
||||
}
|
||||
fcn circle(x0,y0,r,rgb){
|
||||
x:=r; y:=0; radiusError:=1-x;
|
||||
while(x >= y){
|
||||
__sSet(rgb, x + x0, y + y0);
|
||||
__sSet(rgb, y + x0, x + y0);
|
||||
__sSet(rgb,-x + x0, y + y0);
|
||||
__sSet(rgb,-y + x0, x + y0);
|
||||
self[-x + x0, -y + y0]=rgb; // or do it this way, __sSet gets called as above
|
||||
self[-y + x0, -x + y0]=rgb;
|
||||
self[ x + x0, -y + y0]=rgb;
|
||||
self[ y + x0, -x + y0]=rgb;
|
||||
y+=1;
|
||||
if (radiusError<0) radiusError+=2*y + 1;
|
||||
else{ x-=1; radiusError+=2*(y - x + 1); }
|
||||
}
|
||||
}
|
||||
fcn cross(x,y,rgb=0xff|00,len=10){
|
||||
a:=len/2; b:=len-a;
|
||||
line(x-a,y, x+b,y,rgb); line(x,y-a, x,y+b,rgb);
|
||||
}
|
||||
fcn line(x0,y0, x1,y1, rgb){
|
||||
dx:=(x1-x0).abs();
|
||||
dy:=(y1-y0).abs();
|
||||
if(x0 < x1) sx:=1 else sx:=-1;
|
||||
if(y0 < y1) sy:=1 else sy:=-1;
|
||||
err:=dx - dy;
|
||||
while(1){
|
||||
__sSet(rgb,x0,y0);
|
||||
if(x0==x1 and y0==y1) break;
|
||||
e2:=2*err;
|
||||
if(e2 > -dy){ err=err - dy; x0=x0 + sx; }
|
||||
if(e2 < dx) { err=err + dx; y0=y0 + sy; }
|
||||
}
|
||||
}
|
||||
fcn flood(x,y, repl){ // slow!
|
||||
targ:=self[x,y];
|
||||
(stack:=List.createLong(10000)).append(T(x,y));
|
||||
while(stack){
|
||||
x,y:=stack.pop();
|
||||
if((0<=y<h) and (0<=x<w)){
|
||||
p:=self[x,y];
|
||||
if(p==targ){
|
||||
self[x,y]=repl;
|
||||
stack.append( T(x-1,y), T(x+1,y), T(x, y-1), T(x, y+1) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue