/* Simple 3D graphics routines - academic use only - by Chuck Liang, Hofstra University Computer Science. 10/04 C# .Net version DirectX sound routines added 10/05. */ using System; using System.Drawing; using Microsoft.DirectX; using Microsoft.DirectX.DirectSound; using SBuffer = Microsoft.DirectX.DirectSound.SecondaryBuffer; using SDevice = Microsoft.DirectX.DirectSound.Device; public class boxworld { public readonly int XDIM; public readonly int YDIM; public readonly int ZDIM; // zoom ratio - right now, not tied to ZDIM, but probably should! private double ZR = 0.5; private double tiltR = Math.PI/2; // tilt angle in radians // shortening ratio (scales z axis): usually should set to one: private double SR = 1.0; public readonly int xshift; // static display shift values public readonly int yshift; public void setSR(double s) {SR = s;} public void setZR(double z) {ZR=z;} public void tilt(int d) {tiltR=toRadians(d);} public static double toRadians(int degrees) { return degrees * Math.PI / 180.0; } public boxworld(int xd, int yd, int zd, double zr0, int trd) { XDIM=xd; YDIM=yd; ZDIM=zd; ZR=zr0; tiltR = toRadians(trd); xshift = (int)(ZDIM * Math.Cos(tiltR) * SR); yshift = (int)(ZDIM * Math.Sin(tiltR) * SR); } public boxworld(int xd, int yd, int zd, double zr0, int trd, double sr0) { XDIM=xd; YDIM=yd; ZDIM=zd; ZR=zr0; tiltR = toRadians(trd); SR = sr0; xshift = (int)(ZDIM * Math.Cos(tiltR)*SR); yshift = (int)(ZDIM * Math.Sin(tiltR)*SR); // note that here SR does not affect xshift, yshift } // critical function to convert 3d coordinate to 2d coordinate public Point point32(int x, int y, int z) { double s; int x2; int y2; s = (1-((1-ZR)*(double)z/((double)ZDIM))); x2 = (int) ((s*x) + (z * Math.Cos(tiltR) * SR)); y2 = (int) ((s*y) + (z * Math.Sin(tiltR) * SR)); y2 += 30 + Math.Abs(yshift); if(xshift<0) x2 -= (int)xshift; x2 += 10; return new Point(x2,y2); } // point32 public void drawbox(Graphics gdc, int x0, int y0, int z0, int xd, int yd, int zd, Color mc) { int a, b, u, v, x, y, p, q; Point ab, xy, uv, pq; Pen pn = new Pen(mc); ab = point32(x0,y0,z0); xy = point32(x0+xd,y0,z0); uv = point32(x0,y0+yd,z0); pq = point32(x0+xd,y0+yd,z0); a = ab.X; b = ab.Y; x = xy.X; y= xy.Y; u = uv.X; v = uv.Y; p = pq.X; q=pq.Y; // front gdc.DrawLine(pn,a,b,x,y); gdc.DrawLine(pn,a,b,u,v); gdc.DrawLine(pn,u,v,p,q); gdc.DrawLine(pn,p,q,x,y); // sides xy = point32(x0,y0,z0+zd); pq = point32(x0,y0+yd,z0+zd); gdc.DrawLine(pn,a,b,xy.X,xy.Y); gdc.DrawLine(pn,u,v,pq.X,pq.Y); gdc.DrawLine(pn,xy.X,xy.Y,pq.X,pq.Y); ab = point32(x0+xd,y0,z0+zd); uv = point32(x0+xd,y0+yd,z0+zd); gdc.DrawLine(pn,xy.X,xy.Y,ab.X,ab.Y); gdc.DrawLine(pn,pq.X,pq.Y,uv.X,uv.Y); gdc.DrawLine(pn,ab.X,ab.Y,uv.X,uv.Y); xy = point32(x0+xd,y0,z0); pq = point32(x0+xd,y0+yd,z0); gdc.DrawLine(pn,ab.X,ab.Y,xy.X,xy.Y); gdc.DrawLine(pn,uv.X,uv.Y,pq.X,pq.Y); } //drawbox public void drawline(Graphics gdc, int x0, int y0, int z0, int x1, int y1, int z1, Color mc) { Point ab = point32(x0,y0,z0); Point xy = point32(x1,y1,z1); Pen pn = new Pen(mc); gdc.DrawLine(pn,ab.X,ab.Y,xy.X,xy.Y); } // fill circle with scaled radius public void fillcircle(Graphics gdc, int x0, int y0, int z0, double r, Color mc) { int x, y, rs; Point xy = point32(x0,y0,z0); x = xy.X; y=xy.Y; rs = (int) ((1-((1-ZR)*((double)z0)/ZDIM)) * r); if (rs<1) rs = 1; // radius can't be too small. Brush br = new SolidBrush(mc); gdc.FillEllipse(br,x-rs,y-rs,2*rs,2*rs); } // draw circle with scaled radius public void drawcircle(Graphics gdc, int x0, int y0, int z0, double r, Color mc) { int x, y, rs; Point xy = point32(x0,y0,z0); x = xy.X; y=xy.Y; rs = (int) ((1-((1-ZR)*((double)z0)/ZDIM)) * r); if (rs<1) rs = 1; // radius can't be too small. Pen pn = new Pen(mc); gdc.DrawEllipse(pn,x-rs,y-rs,2*rs,2*rs); // MPE_Draw_circle(graph,x,y,(int)rs-2,MPE_BLACK); // 3d effect? } // draw image to scale - w,h represent the original size of the image public void drawimage(Graphics gdc, Image im, int x, int y, int z, int w, int h) { int ws, hs; Point xy = point32(x,y,z); ws = (int)dscale(w,z); hs = (int)dscale(h,z); gdc.DrawImage(im,xy.X,xy.Y,ws,hs); } public void drawimage(Graphics gdc, Image im, int x, int y, int z) { int w, h, ws, hs; Point xy = point32(x,y,z); w = im.Width; h = im.Height; ws = (int)dscale(w,z); hs = (int)dscale(h,z); gdc.DrawImage(im,xy.X,xy.Y,ws,hs); } // scale size x based on z coordinate z0: public double dscale(double x, double z0) { return (1-((1-ZR)*((double)z0)/ZDIM)) * x; } // suggested window width and height public int wwidth() { return XDIM+Math.Abs(xshift)+20;} public int wheight() { return YDIM+Math.Abs(yshift)+40;} }// boxworld // simplified sound playing class, so users won't need directX dev libs. // This class can be called an "object adapter" public class wavsound { public static SDevice snd; public SBuffer sbuf; public wavsound(string filename) { sbuf = new SBuffer(filename,snd); } public static void init(System.Windows.Forms.Form cc) { snd = new SDevice(); snd.SetCooperativeLevel(cc,CooperativeLevel.Normal); } public void play() { sbuf.Play(0,BufferPlayFlags.Default); } public void stop() {sbuf.Stop();} } //wavsound // laplace transformation public class laplace { public double[,] A, B, temp; int r; int c; public double min; public double max; public laplace(int a, int b, double mi, double mx) { Random randnum = new Random(); r = a; c = b; min = mi; max = mx; A = new double[r,c]; B = new double[r,c]; for(a=0;a0) {ns++; nsum += A[i-1,j];} if (i0) {ns++; nsum+=A[i,j-1];} if (jth) diffs = true; } // for i,j // swap A, B matrices temp = A; A= B; B = temp; // Console.WriteLine("doing "+diffs); } while (diffs); } // transform } // laplace //Compile into .dll with csc /t:library r:/Microsoft.DirectX.DLL,Microsoft.DirectX.DirectSound.DLL boxworld.cs