// Written in the D Programming Language v1 ( http://www.digitalmars.com/d/1.0/ ) module render; import std.stdio; import std.file; import std.path; import std.string; import std.conv; import std.math; bool[100][100] image, frame; const header = "P4\n100 100\n"; //const EYEDISTANCE = 200f; //const SCREENDISTANCE = EYEDISTANCE - 10.1f; const STRIPE_HEIGHT = 5; const STRIPE_APPEARANCES = 6; void main(string[] args) { loadImage(args[1]); /+foreach(ref row;image) { foreach(b;row) writef(b?"x":" "); writefln; }+/ int frames = toInt(args[2]); float eyeDistance = toFloat(args[3]); float screenDistance = toFloat(args[4]) + 0.1f; float thickness = toFloat(args[5]); for (int f=0;f0.5) { //stripePos = (ff + (stripePos-0.5)*2) / STRIPE_APPEARANCES; float segment = 1f / STRIPE_APPEARANCES; stripePos = segment * (cast(int)(ff / segment) + (stripePos-0.5)*2); stripeTop = cast(int)(stripePos*90); stripeBottom = stripeTop + STRIPE_HEIGHT*2; } foreach(int y,ref row;image) foreach(int x,p;row) if (p) for (float z=-thickness/2;z<=thickness/2;z+=0.50001) for (float ax = 0; ax < 1; ax += 0.501) for (float ay = 0; ay < 1; ay += 0.501) { float fx = x + ax - 50; float fy = y + ay - 50; float fz = z; float pixelAngle = getAngle(fx, fz); pixelAngle -= angle; float r = sqrt(fz*fz + fx*fx); fx = cos(pixelAngle)*r; fz = sin(pixelAngle)*r; float ratio = (screenDistance / (fz + eyeDistance)); float sx = fx * ratio; float sy = fy * ratio; int ix = cast(int)sx + 50; int iy = cast(int)sy + 50; if (ix>=0 && ix<100 && iy>=0 && iy<100 && (iy&1)==0 && (iy=stripeBottom)) frame[iy][ix] = true; } saveFrame(format("output/%s-%04d.pnm", getBaseName(args[1]), f)); } } void loadImage(string fileName) { auto data = cast(string)read(fileName); if (data[3]=='#') data = data[0..3] ~ data[3+find(data[3..$], '\n')+1..$]; if (data.length != 1311) throw new Exception("Invalid type or dimensions (must be 100x100)"); if (data[0..11]!=header) throw new Exception("Invalid type or dimensions (must be 100x100)"); auto rows = cast(ubyte[13][])data[11..$]; foreach (y,ref row;rows) { for (int x=0;x<100;x++) image[y][x] = (row[x/8] & (1 << (7-x%8))) != 0; } } void saveFrame(string fileName) { string data; data.length = 1311; data[] = '\0'; data[0..11] = header; foreach(y,ref row;frame) foreach(x,p;row) if (p) (cast(ubyte[])data)[11+13*y+x/8] |= (1 << (7-x%8)); write(fileName, data); debug { foreach(ref row;frame) { foreach(b;row) writef(b?"x":" "); writefln; } writefln("================================================"); } } float getAngle(float x, float y) { if (x==0 && y==0) return 0; if (x==0 && y>0) return PI/2; if (x==0 && y<0) return 3*PI/2; if (x>0 && y>=0) return atan(y/x); if (x>0 && y<0) return atan(y/x) + 2*PI; if (x<0) return atan(y/x) + PI; } float fpart(float x) { return x - trunc(x); }