#include #include #include #include #include #include #include #define MAX_DIM 7 /* Don't forget to change MAX_EDGE accordingly */ #define MAX_EDGE 448 /* Depends on MAX_DIM */ #define X_MAG 60.0 #define Y_MAG 50.0 #define X_OFFS 160.0 #define Y_OFFS 100.0 #define X_RES 320 #define Y_RES 200 #define VIDEO 0xA000 #define put_pixel(x,y,color) canvas[x+(y<<8)+(y<<6)] = color #define get_pixel(x,y) canvas[x+(y<<8)+(y<<6)] #define RAD(x) (float)(x)*M_PI/180 #define VERT_SYNC1 asm push dx; \ asm push ax; \ asm mov dx,3dah;\ VRT1: \ asm in al,dx; \ asm test al,8; \ asm jnz VRT1; \ NoVRT1: \ asm in al,dx; \ asm test al,8; \ asm jz NoVRT1; \ asm pop ax; \ asm pop dx; \ #define VERT_SYNC2 asm push dx; \ asm push ax; \ asm mov dx,3dah;\ VRT2: \ asm in al,dx; \ asm test al,8; \ asm jnz VRT2; \ NoVRT2: \ asm in al,dx; \ asm test al,8; \ asm jz NoVRT2; \ asm pop ax; \ asm pop dx; \ #define VERT_SYNC3 asm push dx; \ asm push ax; \ asm mov dx,3dah;\ VRT3: \ asm in al,dx; \ asm test al,8; \ asm jnz VRT3; \ NoVRT3: \ asm in al,dx; \ asm test al,8; \ asm jz NoVRT3; \ asm pop ax; \ asm pop dx; \ unsigned char far *SCREEN=MK_FP(VIDEO,0); unsigned char far *canvas; struct { float vert1[MAX_DIM]; float vert2[MAX_DIM]; } ncube[MAX_EDGE]; int prev_cube_draw[MAX_EDGE][4]; float rot[MAX_DIM][MAX_DIM]; float rotm[MAX_DIM][MAX_DIM]; int n; /* dimension of vector space */ int e; int cube_size; int mat_size; int colpal; //color palettes, user index into palcol struct { float a; float b; } palcol[6]; //subpalette half-widths and centers int defvgapal[256][3]; //to save the default vga palette float ninc_targ_bridge_length; //incrementing n destination bridge length float n_inc_ref[MAX_DIM]; //incrementing n reference vector for bridge expansion animation int vertmchs[2*MAX_EDGE], vertmatch[2*MAX_EDGE]; //vertmatch search results, see vertmatcher() float pushes[2*MAX_EDGE][MAX_DIM]; //2e is the max number of different verts in ncube, //might make do with less here, //,or rely on the smallness of the animation step and do without a push array, //pushing the verts while doing the pushes' calc loop //, or, if using float pushes[2*MAX_EDGE][MAX_DIM], why not just copy the whole ncube instead? int pushvi[2*MAX_EDGE]; //1 or -1 flag for whether there is or isn't an active vector in push[2e+0or1] void vga_mode(int mode) { union REGS regs; regs.x.ax = mode; int86(0x10, ®s, ®s); } void clear_screen(void) { _fmemset(canvas, 0, 64000); } void update_screen(void) { } void old_draw_line(int x1, int y1, int x2, int y2, int color) { register int dx, dy, incr1, incr2, d, x, y, xend, yend, yinc, xinc; dx = abs(x2-x1); dy=abs(y2-y1); if (dx >= dy) { if (x1 >x2) { x=x2;y=y2;xend=x1; if(dy==0) yinc = 0; else { if (y2>y1) yinc = -1; else yinc = 1; } } else { x = x1; y = y1; xend = x2; if (dy==0) yinc=0; else { if (y2>y1) yinc = 1; else yinc = -1; } } incr1 = 2*dy; d = incr1-dx; incr2 = 2*(dy-dx); if (x >= 0 && x < X_RES && y >= 0 && y < Y_RES) put_pixel(x,y,color); while (x= 0 && x < X_RES && y >= 0 && y < Y_RES) put_pixel(x,y,color); } } else { if (y1 >y2) { x=x2;y=y2;yend=y1; if(dx==0) xinc = 0; else { if (x2>x1) xinc = -1; else xinc = 1; } } else { x = x1; y = y1; yend = y2; if (dx==0) xinc=0; else { if (x2>x1) xinc = 1; else xinc = -1; } } incr1 = 2*dx; d = incr1-dy; incr2 = 2*(dx-dy); if (x >= 0 && x < X_RES && y >= 0 && y < Y_RES) put_pixel(x,y,color); while (y= 0 && x < X_RES && y >= 0 && y < Y_RES) put_pixel(x,y,color); } } } void draw_line(int x1, int y1, int x2, int y2, int col1, int col2) { register int dx, dy, incr1, incr2, d, x, y, xend, yend, yinc, xinc; int color, cs; float colf; dx = abs(x2-x1); dy=abs(y2-y1); if (dx >= dy) { if (x1 >x2) { x=x2;y=y2;xend=x1; color=col2; cs = col1-col2; if(dy==0) yinc = 0; else { if (y2>y1) yinc = -1; else yinc = 1; } } else { x = x1; y = y1; xend = x2; color=col1; cs = col2-col1; if (dy==0) yinc=0; else { if (y2>y1) yinc = 1; else yinc = -1; } } incr1 = 2*dy; d = incr1-dx; incr2 = 2*(dy-dx); if (x >= 0 && x < X_RES && y >= 0 && y < Y_RES) put_pixel(x,y,color); colf=(float)color; while (x= 0 && x < X_RES && y >= 0 && y < Y_RES) { put_pixel(x,y,color); } } } else { if (y1 >y2) { x=x2;y=y2;yend=y1; color=col2; cs = col1-col2; if(dx==0) xinc = 0; else { if (x2>x1) xinc = -1; else xinc = 1; } } else { x = x1; y = y1; yend = y2; color=col1; cs = col2-col1; if (dx==0) xinc=0; else { if (x2>x1) xinc = 1; else xinc = -1; } } incr1 = 2*dx; d = incr1-dy; incr2 = 2*(dx-dy); if (x >= 0 && x < X_RES && y >= 0 && y < Y_RES) put_pixel(x,y,color); colf=(float)color; while (y= 0 && x < X_RES && y >= 0 && y < Y_RES) put_pixel(x,y,color); } } } void draw_edge(int edg, int col) { int x1, y1, x2, y2; float ompr1=0, omcs1=0, ompr2=0, omcs2=0, sqn; int col1=col, col2=col, i; x1 = X_MAG * (ncube[edg].vert1[0]) + X_OFFS; y1 = Y_MAG * (ncube[edg].vert1[1]) + Y_OFFS; x2 = X_MAG * (ncube[edg].vert2[0]) + X_OFFS; y2 = Y_MAG * (ncube[edg].vert2[1]) + Y_OFFS; // calculate the pythagorean radical for the truncated component and // shade pixels in the edge line in a gradient, // the sense of it depending on the sum of the omitted coordinates // omitted coordinates pythagorean radicals will range from 0 to root n // omitted coordinates sums // negative omcs shaded bright, positive omcs shaded dimmer if (n>2 && col!=0) { for (i=2;i0.01) match[0] = 0; if (match[0]==1) { vertmem[j][0]=1; for (k=0;k0.01) match[1] = 0; if (match[1]==1) { vertmem[j][1]=1; for (k=0;k0.01) match[0] = 0; if (match[0]==1) { vertmem[j][0]=1; for (k=0;k0.01) match[1] = 0; if (match[1]==1) { vertmem[j][1]=1; for (k=0;k>1].vert1[j])/(10*(1+bdist[ix2])); } } else { for (j=0;j>1].vert2[j])/(10*(1+bdist[ix2])); } } } } else { if ((vertmatch[ix2]&1)==0) { for (j=0;j>1].vert1[j]; } } else { for (j=0;j>1].vert2[j]; } } } if (vertmatch[ix2p1]==-1) { if (vertmchs[ix2p1]<(n-1)) { if ((bdisti[ix2p1]&1)==0) { for (j=0;j>1].vert1[j])/(10*(1+bdist[ix2p1])); } } else { for (j=0;j>1].vert2[j])/(10*(1+bdist[ix2p1])); } } } } else { if ((vertmatch[ix2p1]&1)==0) { for (j=0;j>1].vert1[j]; } } else { for (j=0;j>1].vert2[j]; } } } } } void cont_outl() // contract outliers to cube center // take vector sum of all vertices / 2*e = centroid // find average distance from vertices to center // contract toward center vertices more than 1.2*average distance (1.2,1.1,1.07...) { int i,j; float dist=0.0, dist2, vsum[MAX_DIM]; for (j=0;j(1.07*dist)) { for (j=0;j(1.07*dist)) { for (j=0;j(1.07*dist)) { for (j=0;j(1.07*dist)) { for (j=0;j>1].vert1[j])/(10*(1+bdist[ix2])); } } else { for (j=0;j>1].vert2[j])/(10*(1+bdist[ix2])); } } } } else { if ((vertmatch[ix2]&1)==0) { for (j=0;j>1].vert1[j]; } } else { for (j=0;j>1].vert2[j]; } } } if (vertmatch[ix2p1]==-1) { if (vertmchs[ix2p1]<(n-1)) { if ((bdisti[ix2p1]&1)==0) { for (j=0;j>1].vert1[j])/(10*(1+bdist[ix2p1])); } } else { for (j=0;j>1].vert2[j])/(10*(1+bdist[ix2p1])); } } } } else { if ((vertmatch[ix2p1]&1)==0) { for (j=0;j>1].vert1[j]; } } else { for (j=0;j>1].vert2[j]; } } } } } void rec_cont_mas() // rejoins unattached edge vertices, mas // 'mas' meaning that the rejoining force isn't spent on // coincident vertices { int i,i2,j; // int vertmem[MAX_EDGE][2]; float diff11[MAX_DIM]; float diff22[MAX_DIM]; float diff12[MAX_DIM]; float diff21[MAX_DIM]; float diff11p, diff22p; //space metric squared float diff12p, diff21p; //space metric squared float clsst1, clsst2; //space metric, best so far int i2mem1, i2mem2,i2v1v,i2v2v; float eps; eps=.001*n; // run through each vertex and have it attract the nearest vertex, in space for (i=0;ieps) {clsst1=diff11p;i2mem1=i2;i2v1v=1;} if ((diff12peps) {clsst1=diff12p;i2mem1=i2;i2v1v=2;} if ((diff22peps) {clsst2=diff22p;i2mem2=i2;i2v2v=2;} if ((diff21peps) {clsst2=diff21p;i2mem2=i2;i2v2v=1;} } else { if((diff11peps) {clsst1=diff11p;i2mem1=i2;i2v1v=1;} if((diff12peps) {clsst1=diff12p;i2mem1=i2;i2v1v=2;} if((diff22peps) {clsst2=diff22p;i2mem2=i2;i2v2v=2;} if((diff21peps) {clsst2=diff21p;i2mem2=i2;i2v2v=1;} } // this isn't going to work, re 'mas',unless concident vertices get // bumped together, ie search for matches as in... // 'won't work' as in sort of won't work } // search loop done // vector difference / divide by 10 or diffp add to affected vector for (j=0;j4){ clsst1=sqrt(clsst1); clsst2=sqrt(clsst2);} for (j=0;j4){ clsst1=sqrt(clsst1); clsst2=sqrt(clsst2);} for (j2=0;j2 0) { // put_pixel(x,y,(color-=3)*(color>0)); color-=3; if (color<0) color=0; put_pixel(x,y,color); } } void drop_pixels_xy() { register int color,x,y; for (y=0;y 0) { // put_pixel(x,y,(color-=3)*(color>0)); color-=3; if (color<0) color=0; put_pixel(x,y,color); } } void drop_pixels_buff() { unsigned char canbuff[(unsigned)X_RES*(unsigned)Y_RES]; unsigned int ind_maxp1 = ((unsigned)X_RES*(unsigned)Y_RES); unsigned int i, val; // buffer the canvas for (i=0; i 3) canbuff[i] = val - 3; else canbuff[i]=0; } } // canvas the buffer // for (i=0; i3) canvas[xy]-=3; else canvas[xy]=0; } } void drop_pixels3() //try to drop them faster, see drop_pixels2() { unsigned int xy; for (xy=0;xy<(unsigned)X_RES*(unsigned)Y_RES;xy++) { if (canvas[xy]>3) canvas[xy]-=3; else canvas[xy]=0; } } void drop_pixels3v2() //try to drop them faster, see drop_pixels2() { unsigned char *p = canvas; // if (canvas[xy]) for (; p<(canvas + (X_RES*Y_RES)); p++) if (*p) { if (*p > 3) *p-=3; else *p=0; } } void drop_pixels3v3() //try to drop them faster, see drop_pixels2() { unsigned char *p = canvas; unsigned char *p_max = p + (X_RES*Y_RES); // register unsigned char val; /* try a register int here as well */ // register int val; /* try a register int here as well */ // unsigned char val; int val; for (; p 3) *p = val - 3; else *p=0; } } } void drop_pixels3v() //try to drop them faster, see drop_pixels2() { unsigned char *p = canvas; for (; p<(canvas + ((unsigned)X_RES*(unsigned)Y_RES)); p++) { if (*p > 3) *p-=3; else *p=0; } } void drop_pixels4() //try to drop them faster, see drop_pixels3() { unsigned int xy; for (xy=0;xy<(unsigned)X_RES*(unsigned)Y_RES;xy++) { if (canvas[xy]>3) canvas[xy]-=3; else if (canvas[xy]) canvas[xy]=0; } } void print_ncube() { int i,j; // int p=23; // float max=0.0, min=0.0; // float max=-MAXFLOAT, min=MAXFLOAT; float max, min; max = ncube[0].vert1[0]; min = ncube[0].vert1[0]; for (i=0;i max) max = ncube[i].vert1[j]; else if (ncube[i].vert1[j] < min) min = ncube[i].vert1[j]; if (ncube[i].vert2[j] > max) max = ncube[i].vert2[j]; else if (ncube[i].vert2[j] < min) min = ncube[i].vert2[j]; } printf(" - "); for (j=0;jp) { p=p+23; printf("Page. (Hit key)\n"); pauser(); }*/ } printf("MaxCoordVal: %f, MinCoordVal: %f\n",max,min); // printf("randmax: %u\n",RAND_MAX); // Spinmodes report, spinmode 2, ang_inc indexing report /* for (i=0;i>=1; // gcola[j]=(gcola[j]>0)*gcola[j]/2+(gcola[j]<0)*gcola[j]/2; } } else for(i=1;i<256;i++) { if ((abs(sml)%77)<19) { for(j=0;j<3;j++) { // vgapal[i][j]=(i/255.0)*gcola[j] + (255-i)/255.0*gcolb[j]; vgapal[i][(j+(sml%5))%3]=(i/255.0)*gcola[j] + (255-i)/255.0*gcolb[j]; } } else if ((abs(sml)%77)<26) { // 0 1 2 c m y vgapal[i][(0+(sml%5))%3]=(i/255.0)*gcola[1] + (255-i)/255.0*gcolb[2]; vgapal[i][(1+(sml%5))%3]=(i/255.0)*gcola[0] + (255-i)/255.0*gcolb[1]; vgapal[i][(2+(sml%5))%3]=(i/255.0)*gcola[0] + (255-i)/255.0*gcolb[2]; } else if ((abs(sml)%77)<34) { // 0 1 2 - c r by mg vgapal[i][(0+sml)%3]=(i/255.0)*gcola[2] + (255-i)/255.0*gcolb[2]; vgapal[i][(1+sml)%3]=(i/255.0)*gcola[0] + (255-i)/255.0*gcolb[0]; vgapal[i][(2+sml)%3]=(i/255.0)*gcola[0] + (255-i)/255.0*gcolb[1]; } else if ((abs(sml)%77)<39) { // 0 1 2 - c g vgapal[i][(0+sml)%3]=(i/255.0)*gcola[2] + (255-i)/255.0*gcolb[0]; vgapal[i][(1+sml)%3]=(i/255.0)*gcola[0] + (255-i)/255.0*gcolb[2]; vgapal[i][(2+sml)%3]=(i/255.0)*gcola[0] + (255-i)/255.0*gcolb[0]; } else if ((abs(sml)%77)<45) { // 0 1 2 - c b vgapal[i][(0+sml)%3]=(i/255.0)*gcola[2] + (255-i)/255.0*gcolb[0]; vgapal[i][(1+sml)%3]=(i/255.0)*gcola[0] + (255-i)/255.0*gcolb[0]; vgapal[i][(2+sml)%3]=(i/255.0)*gcola[0] + (255-i)/255.0*gcolb[2]; } else if ((abs(sml)%77)<51) { // 0 1 2 c-gray-black c cmy vgapal[i][(0+sml)%3]=(i/255.0)*gcola[1] + (255-i)/255.0*gcolb[0]; vgapal[i][(1+sml)%3]=(i/255.0)*gcola[0] + (255-i)/255.0*gcolb[0]; vgapal[i][(2+sml)%3]=(i/255.0)*gcola[0] + (255-i)/255.0*gcolb[0]; } else if ((abs(sml)%77)<56) { // 0 1 2 - r-gray-black r rgb vgapal[i][(0+sml)%3]=(i/255.0)*gcola[2] + (255-i)/255.0*gcolb[0]; vgapal[i][(1+sml)%3]=(i/255.0)*gcola[0] + (255-i)/255.0*gcolb[0]; vgapal[i][(2+sml)%3]=(i/255.0)*gcola[0] + (255-i)/255.0*gcolb[0]; } else if ((abs(sml)%77)==56) { // 0 1 2 - gray vgapal[i][ 0 ]=(i/255.0)*gcola[0]; vgapal[i][ 1 ]=(i/255.0)*gcola[0]; vgapal[i][ 2 ]=(i/255.0)*gcola[0]; } else if ((abs(sml)%77)<60) { // 0 1 2 - red-gg-dred ?. vgapal[i][(2+sml)%3]=(i/255.0)*gcola[0] + ((i>90)*(i<170))*gcolb[1]; vgapal[i][( sml)%3]=(i/255.0)*gcola[2] + (i/255.0)*((i>90)*(i<170))*gcolb[2]; vgapal[i][(1+sml)%3]=(i/255.0)*gcola[2] + (i/255.0)*((i>90)*(i<170))*gcolb[2]; } else if ((abs(sml)%77)<63) { // 0 1 2 - c-green-black vgapal[i][(0+sml)%3]=(i/255.0)*gcola[2] + ((i>90)*(i<170))*gcolb[0]; vgapal[i][(1+sml)%3]=(i/255.0)*gcola[0] + (i/255.0)*((i>90)*(i<170))*gcolb[2]; vgapal[i][(2+sml)%3]=(i/255.0)*gcola[0] + ((i>90)*(i<170))*gcolb[0]; } else if ((abs(sml)%77)<66) { // 0 1 2 - c-red-black vgapal[i][(0+sml)%3]=(i/255.0)*gcola[2] + (i/255.0)*((i>90)*(i<170))*gcolb[2]; vgapal[i][(1+sml)%3]=(i/255.0)*gcola[0] + ((i>90)*(i<170))*gcolb[0]; vgapal[i][(2+sml)%3]=(i/255.0)*gcola[0] + ((i>90)*(i<170))*gcolb[0]; } else if ((abs(sml)%77)<69) { // 0 1 2 - c-blue-black vgapal[i][(0+sml)%3]=(i/255.0)*gcola[2] + ((i>90)*(i<170))*gcolb[0]; vgapal[i][(1+sml)%3]=(i/255.0)*gcola[0] + ((i>90)*(i<170))*gcolb[0]; vgapal[i][(2+sml)%3]=(i/255.0)*gcola[0] + (i/255.0)*((i>90)*(i<170))*gcolb[2]; } else if ((abs(sml)%77)<73) { // 0 1 2 - r-black rgb vgapal[i][(0+sml)%3]=(i/255.0)*gcola[0] ; vgapal[i][(1+sml)%3]=(i/255.0)*gcola[2] ; vgapal[i][(2+sml)%3]=(i/255.0)*gcola[2] ; } else //if ((abs(sml)%77)<77) { // 0 1 2 - c-black vgapal[i][(0+sml)%3]=(i/255.0)*gcola[2] ; vgapal[i][(1+sml)%3]=(i/255.0)*gcola[0] ; vgapal[i][(2+sml)%3]=(i/255.0)*gcola[0] ; } } /* for(i=127;i<255;i++) { // vgapal[i][0]=63-(int)((float)i/4.05); // vgapal[i][1]=51-(int)((float)i/5.0); // vgapal[i][2]=43-(int)((float)i/6.0); // vgapal[i][0]=(int)((float)i/4.05); // vgapal[i][1]=(int)((float)i/5.0); // vgapal[i][2]=(int)((float)i/6.0); // vgapal[i][0]=(int)((float)i/5.05); // vgapal[i][1]=10+(int)((float)i/6.05); // vgapal[i][2]=30+(int)((float)i/8.0); vgapal[i][(1+sml)%3]=10-(int)((float)i/32.05); vgapal[i][(2+sml)%3]=0+(int)((float)i/8.05); vgapal[i][(0+sml)%3]=11+(int)((float)i/5.05); } for(i=1;i<127;i++) { vgapal[i][(1+sml)%3]=5-(int)((float)i/32.05); vgapal[i][(0+sml)%3]=0+(int)((float)i/14.05); vgapal[i][(2+sml)%3]=33-(int)((float)i/7.05); } */ for(j=0;j<3;j++) {vgapal[0][j]=0;} // outp(0x03C6,0xff); outp(0x03c8, 0); for(i=0;i<256;i++) { for(j=0;j<3;j++) { outp(0x03c9, vgapal[i][j]); } } } void vertmatcher() { // a match is a vertex within distance^2 epsilon of another, epsilon^2=.0001*n // extern int vertmchs[], vertmatch[]; // the indexes to vertices are indexed by edge*2 plus 0 or 1 //int vertmchs[2*MAX_EDGE], vertmatch[2*MAX_EDGE]; int i, i2, ix2, i2x2, j, ix2p1, i2x2p1; float dist, eps; for (i=0;(i<(e+e));i++) //init { vertmchs[i]=0; vertmatch[i]=-1; // it has no matches; it isn't a match of another (of a previous) } eps=.0001*n; for (i=0;(i<(e-1));i++) { ix2=2*i; ix2p1=ix2+1; if ((vertmatch[ix2]==-1)){ if ((vertmatch[ix2p1]==-1)){ dist=distance(ncube[i].vert1,ncube[i].vert2); if (dist6.0) ninc_targ_bridge_length=2.1; //add -0.05 at coordinate new_n for all the old edges //add edges for cube at new_n //duplicate all the old edges with +.05 in the new dimension for (i=0;i=n2) // try a random distribution for the >n2 case in later revision, seniority now { i3=old_e+old_e; for (i=0;i=ninc_targ_bridge_length) return 0; on2 = pow(2,n-1); vertmatcher(); //returns extern int vertmchs[2*MAX_EDGE], vertmatch[2*MAX_EDGE]; // vertmatch[2e+0or1], if -1 it is not a match of a previous, otherwise is a 2e+0or1 index to that match // vertmchs[2e+0or1] is the number of matches it has if it is not a match of a previous for (i=e-1;i>=e-on2;i--) { for (j=0;j>1].vert1[j]= ncube[i].vert1[j]; } } else { for (j=0;j>1].vert2[j]= ncube[i].vert1[j]; } } for (i2=vertmatch[ix2]>>1; i2>1].vert1[j]= ncube[i].vert2[j]; } } else { for (j=0;j>1].vert2[j]= ncube[i].vert2[j]; } } for (i2=vertmatch[ix2p1]>>1; i2=ninc_targ_bridge_length) return 0; else return 1; } void equi_edge_legth(void) // spring-like force on edges of length other than the original edge length, 2.0, // combined on coincident vertices { float ave; int i, j, i2; int ix2,ix2p1,i2x2,i2x2p1; float el; for (i=0;i0.0003) { el = ( el - ave ) / (50.0 * el); for (j=0;j0) { /* if (vertmatch[ix2p1]==ix2) // this case means this and the previous spring vector are null, but anyway { el=distance(ncube[i].vert2,ncube[i].vert1); el = sqrt(el); if (el>0.0003) { el = ( el - ave ) / (50.0 * el); for (j=0;j0.0003) { el = ( el - ave ) / (50.0 * el); for (j=0;j0.0003) { el = ( el - ave ) / (50.0 * el); for (j=0;j0.0003) { el = ( el - ave ) / (50.0 * el); for (j=0;j0) if (i0.0003) { el = ( el - ave ) / (50.0 * el); for (j=0;j0.0003) { el = ( el - ave ) / (50.0 * el); for (j=0;j0) { if (vertmatch[ix2p1]==ix2) { for (j=0;j0) if (i= 3) *spinmodes = 0; if (*spinmodes == 0) switch (spin%8) { case 0: case 1: case 2: case 3: for (i=n-2;i>=0;i--) { for (j=n-1;j>=i+1;j--) { switch (spin%4) { case 0: rotatem(ang_inc[0], i, j); break; case 1: rotatem(RAD((float)(i+j+2)/10), i, j); break; case 2: rotatem(ang_inc[(i+j) % 4], i, j); break; case 3: rotatem(ang_inc[(i+j) % 6], i, j); break; // } } } break; case 4: if (n>3) rotatem(ang_inc[3], 1, 3); if (n>4) rotatem(ang_inc[1], 2, 4); if (n>5) rotatem(ang_inc[1], 0, 5); if (n>1) rotatem(ang_inc[1], 0, 1); break; case 5: // spin from old ncube'6' if (n>3) rotatem(ang_inc[3], 0, 3); if (n>4) rotatem(ang_inc[1], 3, 4); if (n>5) rotatem(ang_inc[1], 4, 5); if (n>2) rotatem(ang_inc[1], 1, 2); break; case 6: if (n>3) rotatem(ang_inc[3], 1, 3); if (n>4) rotatem(ang_inc[1], 2, 4); if (n>5) rotatem(ang_inc[1], 2, 5); if (n>1) rotatem(ang_inc[0], 0, 1); break; case 7: break; } if (*spinmodes == 1) for (i=n-2;i>=0;i--) { for (j=n-1;j>=i+1;j--) { switch (spin%8) { case 0: rotatem(ang_inc[0]*(0-j+i), i, j); break; case 1: rotatem(ang_inc[abs((0-j+i) % 4)]*((0-j+i) % 4), i, j); break; case 2: rotatem(ang_inc[abs(( (j-i)*(i-j) ) % 6)]*(( (j-i)*(i-j) ) % 6), i, j); break; case 3: /*rotatem(ang_inc[sml]*(0-j+i), i, j);*/ break; case 4: rotatem(ang_inc[(i+j)%5]*(0-j+i), i, j); break; case 5: ji=(i-j)%4;rotatem(ang_inc[ji]*(ji>=0),i,j); break; case 6: ij=((j-i)*(i-j))%6;rotatem(ang_inc[ij]*(ij>=0), i, j); break; case 7: break; } } } if (*spinmodes == 2) switch (spin%8) { case 0: for (i=n-2;i>=0;i--) for (j=n-1;j>=i+1;j--) rotatem(ang_inc[(i+j)%5]*50, i, j ); break; case 1: for (i=n-2;i>=0;i--) for (j=n-1;j>=i+1;j--) if (n>2) rotatem(ang_inc[(i+j)%5], (i%(n-2)), (j%(n-2)) ); else rotatem(ang_inc[(i+j)%5], i, j ); break; case 2: for (i=n-2;i>=0;i--) for (j=n-1;j>=i+1;j--) rotatem(ang_inc[(i+j)%5], (i%(n-1)), (j%(n-1)) ); break; case 3: // spin from old ncube'6' // may produce false rotation matrices for n<6 rotatem(ang_inc[3], 0, 3*(n>3)); rotatem(ang_inc[1], 3*(n>3), 4*(n>4)); rotatem(ang_inc[1], 4*(n>4), 5*(n>5)); rotatem(ang_inc[1], 1, 2*(n>2)); break; case 4: for (i=n-2;i>=0;i--) for (j=n-1;j>=i+1;j--) if((j<(n-1))&&(i<(n-1))) rotatem(ang_inc[(i+j)%5],i,j);break; case 5: for (i=n-2;i>=0;i--) for (j=n-1;j>=i+1;j--) if((j<(n-2))&&(i<(n-2))) rotatem(ang_inc[(i+j)%5],i,j);break; case 6: for (i=n-2;i>=0;i--) for (j=n-1;j>=i+1;j--) if((j<(n-1))&&(i<(n-2))) rotatem(ang_inc[(i+j)%6],i,j);break; case 7: break; } // cases 1, 2, and 3 may cause false rotation matrices } for (i=0;i= 3) *spinmodes = 0; if (*spinmodes == 0) switch (spin%8) { case 0: case 1: case 2: case 3: for (i=0;i1) rotate(ang_inc[1], 0, 1); if (n>5) rotate(ang_inc[1], 0, 5); if (n>4) rotate(ang_inc[1], 2, 4); if (n>3) rotate(ang_inc[3], 1, 3); break; case 5: // spin from old ncube'6' if (n>2) rotate(ang_inc[1], 1, 2); if (n>5) rotate(ang_inc[1], 4, 5); if (n>4) rotate(ang_inc[1], 3, 4); if (n>3) rotate(ang_inc[3], 0, 3); break; case 6: if (n>1) rotate(ang_inc[0], 0, 1); if (n>5) rotate(ang_inc[1], 2, 5); if (n>4) rotate(ang_inc[1], 2, 4); if (n>3) rotate(ang_inc[3], 1, 3); break; case 7: break; } if (*spinmodes == 1) for (i=0;i=0),i,j); break; case 6: ij=((j-i)*(i-j))%6;rotate(ang_inc[ij]*(ij>=0), i, j); break; case 7: break; } } } if (*spinmodes == 2) switch (spin%8) { case 0: for (i=0;i2) rotate(ang_inc[(i+j)%5], (i%(n-2)), (j%(n-2)) ); else rotate(ang_inc[(i+j)%5], i, j ); break; case 2: for (i=0;i2)); rotate(ang_inc[1], 4*(n>4), 5*(n>5)); rotate(ang_inc[1], 3*(n>3), 4*(n>4)); rotate(ang_inc[3], 0, 3*(n>3)); break; case 4: for (i=0;iMAX_DIM)) { while (!kbhit()); nd = (getch() - 48); } init_dimension(nd); // choose n here vga_mode(0x13); wipe=1; quit=0; spin=0; colpal=0; ang_inc[0] = RAD(.05*5); ang_inc[1] = RAD(.07*5); ang_inc[2] = RAD(.04*5); ang_inc[3] = RAD(.03*5); ang_inc[4] = RAD(.10*5); ang_inc[5] = RAD(.13*5); palcol[0].a= 7.5; palcol[0].b= 23.5; palcol[1].a= 15.5; palcol[1].b= 34.5; palcol[2].a= 30.5; palcol[2].b= 34.5; palcol[3].a= 60.5; palcol[3].b= 64.5; palcol[4].a= 63.5; palcol[4].b= 190.5; palcol[5].a= 120.5; palcol[5].b= 127.5; for(i=0;i<6;i++) pcbalts[0][i]=127.5; for(i=0;i<6;i++) pcbalts[1][i]=255-palcol[i].b; outp(0x03c7, 0); //saving the default vga palette for(i=0;i<256;i++) { for(j=0;j<3;j++) { defvgapal[i][j]=inp(0x03c9); } } //done saving the default vga palette for(j=0;j=31) { up=-1; } // if (col<=16) { up=1; } if (col>=palcol[colpal].b+palcol[colpal].a) {up=-1;} if (col<=palcol[colpal].b-palcol[colpal].a) {up=1; } } else draw_ncube(10); delay( delnum ); if (kbhit()) { ch=getch(); if (ch=='w') wipe= !wipe; else if (ch=='z') old_draw_flag= !old_draw_flag; else if (ch=='r') reduce= !reduce; else if (ch=='c') clear_screen(); else if (ch=='v') vertsy=!vertsy; else if (ch=='s') spin=spin+1; else if (ch=='S') delnum=(delnum+1)%28; else if(ch=='!') delnum=0; else if (ch=='M') spinmodes = spinmodes +1; else if (ch=='f') { faster_rot = (faster_rot+1)%2; faster_rot_changed = 1; } else if (ch=='A') sml += 1; else if (ch=='Q') sml -= 1; else if (ch=='W') sml = 82; else if (ch=='d') distort(); else if (ch=='b') breakdist(); else if (ch=='a') shrink(); else if (ch=='t') grow(); else if (ch=='e') exp_from_centr(); else if (ch=='E') blow_from_centr(); else if (ch=='Y') blow_astr(); else if (ch=='y') exp_astr(); else if (ch=='R') knock_left(); else if (ch=='X') knock_cent_left(); else if (ch=='N') { if (nMAX_DIM)) { while (!kbhit()); nd = (getch() - 48); } init_dimension(nd); // choose n here contract=0;contline=0;contpoint=0;contrmas=0;contrmas2=0;contrmas2d=0; contoutl=0;contoutld=0; n_inc_flag=0; equiel=0; faster_rot_changed = 1; } else if (ch==0x1b) quit=1; else pauser(); } if (reduce) { switch (abs(sml%4)) { case 0: drop_pixels(); break; case 1: drop_pixels_buff(); break; case 2: drop_pixels3v3(); break; case 3: drop_pixels_xy(); break; // case 3: drop_pixels3v(); break; // case 4: drop_pixels2(); break; // case 5: drop_pixels4(); break; } } if (n_inc_flag==1) { n_inc_flag = animate_n_inc(); } if (contract!=0) { recube_cont(); /*contract+=1;*/ } if (contline!=0) { rec_cont_liner(); } if (contpoint!=0) { rec_cont_point(); } if (contrmas!=0) { rec_cont_mas(); } if (contrmas2!=0) { rec_cont_mas2(); } if (contrmas2d!=0) { rec_cont_mas2d(); } if (contoutl!=0) { cont_outl(); } if (contoutld!=0) { cont_outld(contoutld); } if (equiel!=0) { equi_edge_legth(); } } vga_mode(0x03); print_ncube(); pauser(); }