|
本帖最后由 p857211 于 2013-6-18 00:19 编辑
视频:Arduino 8x8x8 Cube http://www.youtube.com/watch?v=1YnRPepOV4E
先前实验制作的4x4x4 http://www.youtube.com/watch?v=daCo3CaDQsA
- #include <avr/interrupt.h>
- #include <string.h>
- #define AXIS_X 1
- #define AXIS_Y 2
- #define AXIS_Z 3
- volatile unsigned char cube[8][8];
- volatile int current_layer = 0;
- void setup()
- {
- int i;
-
- for(i=0; i<14; i++)
- pinMode(i, OUTPUT);
-
-
- DDRC = 0xff;
- PORTC = 0x00;
-
- TCCR2A = 0x00;
- TCCR2B = 0x00;
- TCCR2A |= (0x01 << WGM21);
- OCR2A = 10;
- TCNT2 = 0x00;
- TCCR2B |= (0x01 << CS22) | (0x01 << CS21);
-
- TIMSK2 |= (0x01 << OCIE2A);
- }
- ISR (TIMER2_COMPA_vect)
- {
- int i;
-
-
- PORTC = 0x00;
- PORTB &= 0x0f;
-
- PORTB |= 0x08;
-
- for (i=0; i<8; i++)
- {
- PORTD = cube[current_layer][i];
- PORTB = (PORTB & 0xF8) | (0x07 & (i+1));
- }
-
- PORTB &= 0b00110111;
-
- if (current_layer < 6)
- {
- PORTC = (0x01 << current_layer);
- } else if (current_layer == 6)
- {
- digitalWrite(12, HIGH);
- } else
- {
- digitalWrite(13, HIGH);
- }
-
- current_layer++;
-
- if (current_layer == 8)
- current_layer = 0;
- }
- void loop()
- {
- int i,x,y,z;
-
- while (true)
- { effect_planboing(AXIS_Z, 1000);
- effect_planboing(AXIS_Y, 1000);
- effect_planboing(AXIS_X, 1000);
- effect_boxside_randsend_parallel (AXIS_X, 0, 100, 1);
- effect_boxside_randsend_parallel (AXIS_X, 1, 100, 1);
- effect_boxside_randsend_parallel (AXIS_Y, 0, 100, 1);
- effect_boxside_randsend_parallel (AXIS_Y, 1, 100, 1);
- effect_boxside_randsend_parallel (AXIS_Z, 0, 100, 1);
- effect_boxside_randsend_parallel (AXIS_Z, 1, 100, 1);
- effect_random_filler(20,1);
- effect_random_filler(20,0);
- effect_random_filler(20,1);
- effect_random_filler(20,0);
- space(100);
- space(100);
- firework(-2,1,600);
-
- effect_planboing(AXIS_Z, 400);
- effect_planboing(AXIS_Y, 400);
- effect_planboing(AXIS_X, 400);
-
- effect_blinky2();
-
- effect_random_filler(75,1);
- effect_random_filler(75,0);
-
- effect_rain(100);
- space(100);
-
-
- effect_boxside_randsend_parallel (AXIS_X, 0, 150, 1);
- effect_boxside_randsend_parallel (AXIS_X, 1, 150, 1);
- effect_boxside_randsend_parallel (AXIS_Y, 0, 150, 1);
- effect_boxside_randsend_parallel (AXIS_Y, 1, 150, 1);
- effect_boxside_randsend_parallel (AXIS_Z, 0, 150, 1);
- effect_boxside_randsend_parallel (AXIS_Z, 1, 150, 1);
- firework(0,0,0);
- firework(-2,-2,50);
- firework(1,1,-250);
- firework(0,1,200);
- firework(1,-3,400);
- firework(2,-3,600);
- firework(2,1,500);
- firework(2,-2,200);
- firework(2,1,0);
- firework(0,0,0);
-
- firework(2,-2,500);
-
- }
- }
- // ==========================================================================================
- // Effect functions
- void space(int iterations){
- int i, ii;
- int rnd_y;
- int rnd_z;
- int rnd_num;
- int time;
-
- time = 700;
- for (ii=0;ii<iterations;ii++)
- {
- time = time - (iterations/15);
- rnd_num = rand()%4;
-
- for (i=0; i < rnd_num;i++)
- {
- rnd_y = rand()%8;
- rnd_z = rand()%8;
- setvoxel(7,rnd_y,rnd_z);
- }
-
- delay_ms(time);
- shift(AXIS_X,-1);
- }
- for (ii=0;ii<iterations;ii++)
- {
- time = time + (iterations/15);
- rnd_num = rand()%4;
-
- for (i=0; i < rnd_num;i++)
- {
- rnd_y = rand()%8;
- rnd_z = rand()%8;
- setvoxel(7,rnd_y,rnd_z);
- }
-
- delay_ms(time);
- shift(AXIS_X,-1);
- }
- }
- void firework(int i,int j, int time){
- fill(0x00);
- setvoxel(3-i,4-j,0);
- delay_ms(900-time);
- clrvoxel(3-i,4-j,0);
- setvoxel(4-i,4-j,1);
- delay_ms(1200-time);
- clrvoxel(4-i,4-j,1);
- setvoxel(4-i,5-j,2);
- delay_ms(1400-time);
- clrvoxel(4-i,5-j,2);
- setvoxel(3-i,5-j,3);
- delay_ms(1700-time);
- clrvoxel(3-i,5-j,3);
- setvoxel(3-i,4-j,4);
- delay_ms(2000-time);
- clrvoxel(3-i,4-j,4);
- setvoxel(4-i,4-j,5);
- delay_ms(2000-time);
- clrvoxel(4-i,4-j,5);
- setvoxel(4-i,3-j,6);
- delay_ms(2000-time);
- //Explode
- clrvoxel(4-i,3-j,6);
- setvoxel(4-i,3-j,7);
- setvoxel(4-i,4-j,6);
- setvoxel(4-i,2-j,6);
- setvoxel(3-i,3-j,6);
- setvoxel(5-i,3-j,6);
- delay_ms(2000-time);
- shift(AXIS_Z,-1);
- setvoxel(4-i,5-j,5);
- setvoxel(4-i,1-j,5);
- setvoxel(2-i,3-j,5);
- setvoxel(6-i,3-j,5);
- delay_ms(900-time);
- shift(AXIS_Z,-1);
- setvoxel(4-i,6-j,3);
- setvoxel(4-i,0-j,3);
- setvoxel(1-i,3-j,3);
- setvoxel(7-i,3-j,3);
- delay_ms(900-time);
- shift(AXIS_Z,-1);
- setvoxel(4-i,7-j,1);
- setvoxel(3-i,0-j,1);
- setvoxel(0-i,3-j,1);
- setvoxel(7-i,2-j,1);
- delay_ms(1400-time);
- shift(AXIS_Z,-1);
- delay_ms(1400-time);
- shift(AXIS_Z,-1);
- delay_ms(1400-time);
- shift(AXIS_Z,-1);
- delay_ms(1400-time);
- shift(AXIS_Z,-1);
- delay_ms(700-time);
- fill(0x00);
- }
- // ==========================================================================================
- void draw_positions_axis (char axis, unsigned char positions[64], int invert)
- {
- int x, y, p;
-
- fill(0x00);
-
- for (x=0; x<8; x++)
- {
- for (y=0; y<8; y++)
- {
- if (invert)
- {
- p = (7-positions[(x*8)+y]);
- } else
- {
- p = positions[(x*8)+y];
- }
-
- if (axis == AXIS_Z)
- setvoxel(x,y,p);
-
- if (axis == AXIS_Y)
- setvoxel(x,p,y);
-
- if (axis == AXIS_X)
- setvoxel(p,y,x);
- }
- }
-
- }
- void effect_boxside_randsend_parallel (char axis, int origin, int delay, int mode)
- {
- int i;
- int done;
- unsigned char cubepos[64];
- unsigned char pos[64];
- int notdone = 1;
- int notdone2 = 1;
- int sent = 0;
-
- for (i=0;i<64;i++)
- {
- pos[i] = 0;
- }
-
- while (notdone)
- {
- if (mode == 1)
- {
- notdone2 = 1;
- while (notdone2 && sent<64)
- {
- i = rand()%64;
- if (pos[i] == 0)
- {
- sent++;
- pos[i] += 1;
- notdone2 = 0;
- }
- }
- } else if (mode == 2)
- {
- if (sent<64)
- {
- pos[sent] += 1;
- sent++;
- }
- }
-
- done = 0;
- for (i=0;i<64;i++)
- {
- if (pos[i] > 0 && pos[i] <7)
- {
- pos[i] += 1;
- }
-
- if (pos[i] == 7)
- done++;
- }
-
- if (done == 64)
- notdone = 0;
-
- for (i=0;i<64;i++)
- {
- if (origin == 0)
- {
- cubepos[i] = pos[i];
- } else
- {
- cubepos[i] = (7-pos[i]);
- }
- }
-
-
- delay_ms(delay);
- draw_positions_axis(axis,cubepos,0);
- }
-
- }
- void effect_rain (int iterations)
- {
- int i, ii;
- int rnd_x;
- int rnd_y;
- int rnd_num;
-
- for (ii=0;ii<iterations;ii++)
- {
- rnd_num = rand()%4;
-
- for (i=0; i < rnd_num;i++)
- {
- rnd_x = rand()%8;
- rnd_y = rand()%8;
- setvoxel(rnd_x,rnd_y,7);
- }
-
- delay_ms(1000);
- shift(AXIS_Z,-1);
- }
- }
- // Set or clear exactly 512 voxels in a random order.
- void effect_random_filler (int delay, int state)
- {
- int x,y,z;
- int loop = 0;
-
-
- if (state == 1)
- {
- fill(0x00);
- } else
- {
- fill(0xff);
- }
-
- while (loop<511)
- {
- x = rand()%8;
- y = rand()%8;
- z = rand()%8;
- if ((state == 0 && getvoxel(x,y,z) == 0x01) || (state == 1 && getvoxel(x,y,z) == 0x00))
- {
- altervoxel(x,y,z,state);
- delay_ms(delay);
- loop++;
- }
- }
- }
- void effect_blinky2()
- {
- int i,r;
- fill(0x00);
-
- for (r=0;r<2;r++)
- {
- i = 750;
- while (i>0)
- {
- fill(0x00);
- delay_ms(i);
-
- fill(0xff);
- delay_ms(100);
-
- i = i - (15+(1000/(i/10)));
- }
-
- delay_ms(1000);
-
- i = 750;
- while (i>0)
- {
- fill(0x00);
- delay_ms(751-i);
-
- fill(0xff);
- delay_ms(100);
-
- i = i - (15+(1000/(i/10)));
- }
- }
- }
- // Draw a plane on one axis and send it back and forth once.
- void effect_planboing (int plane, int speed)
- {
- int i;
- for (i=0;i<8;i++)
- {
- fill(0x00);
- setplane(plane, i);
- delay_ms(speed);
- }
-
- for (i=7;i>=0;i--)
- {
- fill(0x00);
- setplane(plane,i);
- delay_ms(speed);
- }
- }
- // ==========================================================================================
- // Draw functions
- // ==========================================================================================
- // Set a single voxel to ON
- void setvoxel(int x, int y, int z)
- {
- if (inrange(x,y,z))
- cube[z][y] |= (1 << x);
- }
- // Set a single voxel to ON
- void clrvoxel(int x, int y, int z)
- {
- if (inrange(x,y,z))
- cube[z][y] &= ~(1 << x);
- }
- // This function validates that we are drawing inside the cube.
- unsigned char inrange(int x, int y, int z)
- {
- if (x >= 0 && x < 8 && y >= 0 && y < 8 && z >= 0 && z < 8)
- {
- return 0x01;
- } else
- {
- // One of the coordinates was outside the cube.
- return 0x00;
- }
- }
- // Get the current status of a voxel
- unsigned char getvoxel(int x, int y, int z)
- {
- if (inrange(x,y,z))
- {
- if (cube[z][y] & (1 << x))
- {
- return 0x01;
- } else
- {
- return 0x00;
- }
- } else
- {
- return 0x00;
- }
- }
- // In some effect we want to just take bool and write it to a voxel
- // this function calls the apropriate voxel manipulation function.
- void altervoxel(int x, int y, int z, int state)
- {
- if (state == 1)
- {
- setvoxel(x,y,z);
- } else
- {
- clrvoxel(x,y,z);
- }
- }
- // Flip the state of a voxel.
- // If the voxel is 1, its turned into a 0, and vice versa.
- void flpvoxel(int x, int y, int z)
- {
- if (inrange(x, y, z))
- cube[z][y] ^= (1 << x);
- }
- // Makes sure x1 is alwas smaller than x2
- // This is usefull for functions that uses for loops,
- // to avoid infinite loops
- void argorder(int ix1, int ix2, int *ox1, int *ox2)
- {
- if (ix1>ix2)
- {
- int tmp;
- tmp = ix1;
- ix1= ix2;
- ix2 = tmp;
- }
- *ox1 = ix1;
- *ox2 = ix2;
- }
- // Sets all voxels along a X/Y plane at a given point
- // on axis Z
- void setplane_z (int z)
- {
- int i;
- if (z>=0 && z<8)
- {
- for (i=0;i<8;i++)
- cube[z][i] = 0xff;
- }
- }
- // Clears voxels in the same manner as above
- void clrplane_z (int z)
- {
- int i;
- if (z>=0 && z<8)
- {
- for (i=0;i<8;i++)
- cube[z][i] = 0x00;
- }
- }
- void setplane_x (int x)
- {
- int z;
- int y;
- if (x>=0 && x<8)
- {
- for (z=0;z<8;z++)
- {
- for (y=0;y<8;y++)
- {
- cube[z][y] |= (1 << x);
- }
- }
- }
- }
- void clrplane_x (int x)
- {
- int z;
- int y;
- if (x>=0 && x<8)
- {
- for (z=0;z<8;z++)
- {
- for (y=0;y<8;y++)
- {
- cube[z][y] &= ~(1 << x);
- }
- }
- }
- }
- void setplane_y (int y)
- {
- int z;
- if (y>=0 && y<8)
- {
- for (z=0;z<8;z++)
- cube[z][y] = 0xff;
- }
- }
- void clrplane_y (int y)
- {
- int z;
- if (y>=0 && y<8)
- {
- for (z=0;z<8;z++)
- cube[z][y] = 0x00;
- }
- }
- void setplane (char axis, unsigned char i)
- {
- switch (axis)
- {
- case AXIS_X:
- setplane_x(i);
- break;
-
- case AXIS_Y:
- setplane_y(i);
- break;
- case AXIS_Z:
- setplane_z(i);
- break;
- }
- }
- void clrplane (char axis, unsigned char i)
- {
- switch (axis)
- {
- case AXIS_X:
- clrplane_x(i);
- break;
-
- case AXIS_Y:
- clrplane_y(i);
- break;
- case AXIS_Z:
- clrplane_z(i);
- break;
- }
- }
- // Fill a value into all 64 byts of the cube buffer
- // Mostly used for clearing. fill(0x00)
- // or setting all on. fill(0xff)
- void fill (unsigned char pattern)
- {
- int z;
- int y;
- for (z=0;z<8;z++)
- {
- for (y=0;y<8;y++)
- {
- cube[z][y] = pattern;
- }
- }
- }
- // Draw a box with all walls drawn and all voxels inside set
- void box_filled(int x1, int y1, int z1, int x2, int y2, int z2)
- {
- int iy;
- int iz;
- argorder(x1, x2, &x1, &x2);
- argorder(y1, y2, &y1, &y2);
- argorder(z1, z2, &z1, &z2);
- for (iz=z1;iz<=z2;iz++)
- {
- for (iy=y1;iy<=y2;iy++)
- {
- cube[iz][iy] |= byteline(x1,x2);
- }
- }
- }
- // Darw a hollow box with side walls.
- void box_walls(int x1, int y1, int z1, int x2, int y2, int z2)
- {
- int iy;
- int iz;
-
- argorder(x1, x2, &x1, &x2);
- argorder(y1, y2, &y1, &y2);
- argorder(z1, z2, &z1, &z2);
- for (iz=z1;iz<=z2;iz++)
- {
- for (iy=y1;iy<=y2;iy++)
- {
- if (iy == y1 || iy == y2 || iz == z1 || iz == z2)
- {
- cube[iz][iy] = byteline(x1,x2);
- } else
- {
- cube[iz][iy] |= ((0x01 << x1) | (0x01 << x2));
- }
- }
- }
- }
- // Draw a wireframe box. This only draws the corners and edges,
- // no walls.
- void box_wireframe(int x1, int y1, int z1, int x2, int y2, int z2)
- {
- int iy;
- int iz;
- argorder(x1, x2, &x1, &x2);
- argorder(y1, y2, &y1, &y2);
- argorder(z1, z2, &z1, &z2);
- // Lines along X axis
- cube[z1][y1] = byteline(x1,x2);
- cube[z1][y2] = byteline(x1,x2);
- cube[z2][y1] = byteline(x1,x2);
- cube[z2][y2] = byteline(x1,x2);
- // Lines along Y axis
- for (iy=y1;iy<=y2;iy++)
- {
- setvoxel(x1,iy,z1);
- setvoxel(x1,iy,z2);
- setvoxel(x2,iy,z1);
- setvoxel(x2,iy,z2);
- }
- // Lines along Z axis
- for (iz=z1;iz<=z2;iz++)
- {
- setvoxel(x1,y1,iz);
- setvoxel(x1,y2,iz);
- setvoxel(x2,y1,iz);
- setvoxel(x2,y2,iz);
- }
- }
- // Returns a byte with a row of 1's drawn in it.
- // byteline(2,5) gives 0b00111100
- char byteline (int start, int end)
- {
- return ((0xff<<start) & ~(0xff<<(end+1)));
- }
- // Flips a byte 180 degrees.
- // MSB becomes LSB, LSB becomes MSB.
- char flipbyte (char byte)
- {
- char flop = 0x00;
- flop = (flop & 0b11111110) | (0b00000001 & (byte >> 7));
- flop = (flop & 0b11111101) | (0b00000010 & (byte >> 5));
- flop = (flop & 0b11111011) | (0b00000100 & (byte >> 3));
- flop = (flop & 0b11110111) | (0b00001000 & (byte >> 1));
- flop = (flop & 0b11101111) | (0b00010000 & (byte << 1));
- flop = (flop & 0b11011111) | (0b00100000 & (byte << 3));
- flop = (flop & 0b10111111) | (0b01000000 & (byte << 5));
- flop = (flop & 0b01111111) | (0b10000000 & (byte << 7));
- return flop;
- }
- // Draw a line between any coordinates in 3d space.
- // Uses integer values for input, so dont expect smooth animations.
- void line(int x1, int y1, int z1, int x2, int y2, int z2)
- {
- float xy; // how many voxels do we move on the y axis for each step on the x axis
- float xz; // how many voxels do we move on the y axis for each step on the x axis
- unsigned char x,y,z;
- unsigned char lasty,lastz;
- // We always want to draw the line from x=0 to x=7.
- // If x1 is bigget than x2, we need to flip all the values.
- if (x1>x2)
- {
- int tmp;
- tmp = x2; x2 = x1; x1 = tmp;
- tmp = y2; y2 = y1; y1 = tmp;
- tmp = z2; z2 = z1; z1 = tmp;
- }
-
- if (y1>y2)
- {
- xy = (float)(y1-y2)/(float)(x2-x1);
- lasty = y2;
- } else
- {
- xy = (float)(y2-y1)/(float)(x2-x1);
- lasty = y1;
- }
- if (z1>z2)
- {
- xz = (float)(z1-z2)/(float)(x2-x1);
- lastz = z2;
- } else
- {
- xz = (float)(z2-z1)/(float)(x2-x1);
- lastz = z1;
- }
- // For each step of x, y increments by:
- for (x = x1; x<=x2;x++)
- {
- y = (xy*(x-x1))+y1;
- z = (xz*(x-x1))+z1;
- setvoxel(x,y,z);
- }
-
- }
- // 動畫Delay迴圈
- void delay_ms(uint16_t x)
- {
- uint8_t y, z;
- for ( ; x > 0 ; x--){
- for ( y = 0 ; y < 90 ; y++){
- for ( z = 0 ; z < 6 ; z++){
- asm volatile ("nop");
- }
- }
- }
- }
- //Z axiz的下雨動畫
- void shift (char axis, int direction)
- {
- int i, x ,y;
- int ii, iii;
- int state;
- for (i = 0; i < 8; i++)
- {
- if (direction == -1)
- {
- ii = i;
- } else
- {
- ii = (7-i);
- }
-
-
- for (x = 0; x < 8; x++)
- {
- for (y = 0; y < 8; y++)
- {
- if (direction == -1)
- {
- iii = ii+1;
- } else
- {
- iii = ii-1;
- }
-
- if (axis == AXIS_Z)
- {
- state = getvoxel(x,y,iii);
- altervoxel(x,y,ii,state);
- }
-
- if (axis == AXIS_Y)
- {
- state = getvoxel(x,iii,y);
- altervoxel(x,ii,y,state);
- }
-
- if (axis == AXIS_X)
- {
- state = getvoxel(iii,y,x);
- altervoxel(ii,y,x,state);
- }
- }
- }
- }
-
- if (direction == -1)
- {
- i = 7;
- } else
- {
- i = 0;
- }
-
- for (x = 0; x < 8; x++)
- {
- for (y = 0; y < 8; y++)
- {
- if (axis == AXIS_Z)
- clrvoxel(x,y,i);
-
- if (axis == AXIS_Y)
- clrvoxel(x,i,y);
-
- if (axis == AXIS_X)
- clrvoxel(i,y,x);
- }
- }
- }
复制代码 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
评分
-
查看全部评分
|