September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -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

View file

@ -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_

View file

@ -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)
}
}

View file

@ -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");

View file

@ -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) );
}
}
}
}
}