8x8x8 Led Cube driven by 4x PCF8575 for the columns and 1x PCF8574 for the layers

Committer:
Bas
Date:
Thu Nov 01 22:31:54 2012 +0000
Revision:
1:e08a4d27f534
Parent:
0:920c5ed65a45
Added several simple graphic functions helping to create animations

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Bas 0:920c5ed65a45 1 #include "led_cube.h"
Bas 0:920c5ed65a45 2
Bas 0:920c5ed65a45 3 LED_CUBE::LED_CUBE(I2C* _interface)
Bas 0:920c5ed65a45 4 : row(_interface, 0x07,PCF8574_TYPE),
Bas 0:920c5ed65a45 5 colums_0_1(_interface, 0x00),
Bas 0:920c5ed65a45 6 colums_2_3(_interface, 0x01),
Bas 0:920c5ed65a45 7 colums_4_5(_interface, 0x02),
Bas 0:920c5ed65a45 8 colums_6_7(_interface, 0x03)
Bas 0:920c5ed65a45 9 {
Bas 0:920c5ed65a45 10 _interface->frequency(400000); //400KHz
Bas 0:920c5ed65a45 11 duty.attach_us(this, &LED_CUBE::UpdateRow,1250);// each row = 1/8 duty
Bas 0:920c5ed65a45 12 }
Bas 0:920c5ed65a45 13
Bas 0:920c5ed65a45 14 LED_CUBE::~LED_CUBE() {}
Bas 0:920c5ed65a45 15
Bas 0:920c5ed65a45 16 void LED_CUBE::UpdateRow()
Bas 0:920c5ed65a45 17 {
Bas 0:920c5ed65a45 18 static int rownr = 0;
Bas 0:920c5ed65a45 19
Bas 0:920c5ed65a45 20 if (rownr < 0 || rownr > 7) {
Bas 0:920c5ed65a45 21 rownr = 0;
Bas 0:920c5ed65a45 22 }
Bas 0:920c5ed65a45 23 row.WriteByte(0xFF); // switch off all rows before updating next colums to avoid ghost data from previous colums
Bas 0:920c5ed65a45 24 colums_0_1.WriteBytes(~cubeData[8 * rownr + 0],~cubeData[8 * rownr + 2]); //update the columns
Bas 0:920c5ed65a45 25 colums_2_3.WriteBytes(~cubeData[8 * rownr + 1],~cubeData[8 * rownr + 3]);
Bas 0:920c5ed65a45 26 colums_4_5.WriteBytes(~cubeData[8 * rownr + 6],~cubeData[8 * rownr + 4]);
Bas 0:920c5ed65a45 27 colums_6_7.WriteBytes(~cubeData[8 * rownr + 7],~cubeData[8 * rownr + 5]);
Bas 0:920c5ed65a45 28 row.WriteByte(~(1<<rownr)); // now display the row
Bas 0:920c5ed65a45 29 rownr++;
Bas 0:920c5ed65a45 30 }
Bas 0:920c5ed65a45 31
Bas 0:920c5ed65a45 32 //clear everything
Bas 1:e08a4d27f534 33 void LED_CUBE::clear_cube(void)
Bas 1:e08a4d27f534 34 {
Bas 0:920c5ed65a45 35 row.WriteByte(0xFF);
Bas 0:920c5ed65a45 36 colums_0_1.WriteBytes(0xFF,0xFF);
Bas 0:920c5ed65a45 37 colums_2_3.WriteBytes(0xFF,0xFF);
Bas 0:920c5ed65a45 38 colums_4_5.WriteBytes(0xFF,0xFF);
Bas 0:920c5ed65a45 39 colums_6_7.WriteBytes(0xFF,0xFF);
Bas 0:920c5ed65a45 40 clearVoxels();
Bas 0:920c5ed65a45 41 }
Bas 0:920c5ed65a45 42
Bas 1:e08a4d27f534 43 //set a voxel in the cube array
Bas 1:e08a4d27f534 44 void LED_CUBE::setVoxel(unsigned char x, unsigned char y, unsigned char z)
Bas 1:e08a4d27f534 45 {
Bas 1:e08a4d27f534 46 if (inrange(x, y, z))
Bas 1:e08a4d27f534 47 cubeData[z*8 + x] |= 0x01<<y;
Bas 0:920c5ed65a45 48 }
Bas 0:920c5ed65a45 49
Bas 1:e08a4d27f534 50 //clear a single voxel in the cube array
Bas 1:e08a4d27f534 51 void LED_CUBE::clearVoxel(unsigned char x, unsigned char y, unsigned char z)
Bas 1:e08a4d27f534 52 {
Bas 1:e08a4d27f534 53 if (inrange(x, y, z))
Bas 1:e08a4d27f534 54 cubeData[z*8 + x] &= ~(0x01<<y);
Bas 0:920c5ed65a45 55 }
Bas 0:920c5ed65a45 56
Bas 1:e08a4d27f534 57 //return the value of a single voxel in the cube array
Bas 1:e08a4d27f534 58 unsigned char LED_CUBE::getVoxel(unsigned char x, unsigned char y, unsigned char z)
Bas 1:e08a4d27f534 59 {
Bas 1:e08a4d27f534 60 if (inrange(x, y, z)) {
Bas 1:e08a4d27f534 61 if(cubeData[z*8 + x] & 0x01<<y) {
Bas 1:e08a4d27f534 62 return 1;
Bas 1:e08a4d27f534 63 } else {
Bas 1:e08a4d27f534 64 return 0;
Bas 1:e08a4d27f534 65 }
Bas 1:e08a4d27f534 66 } else {
Bas 0:920c5ed65a45 67 return 0;
Bas 0:920c5ed65a45 68 }
Bas 0:920c5ed65a45 69 }
Bas 0:920c5ed65a45 70
Bas 1:e08a4d27f534 71 void LED_CUBE::copyColumn(unsigned char x, unsigned char y, unsigned char col)
Bas 1:e08a4d27f534 72 {
Bas 1:e08a4d27f534 73 for(unsigned char z = 0; z < 8; z++) {
Bas 1:e08a4d27f534 74 if(col&(0x01<<z)) {
Bas 0:920c5ed65a45 75 setVoxel(x, y, z);
Bas 1:e08a4d27f534 76 } else {
Bas 0:920c5ed65a45 77 clearVoxel(x, y, z);
Bas 0:920c5ed65a45 78 }
Bas 0:920c5ed65a45 79 }
Bas 0:920c5ed65a45 80 }
Bas 1:e08a4d27f534 81
Bas 1:e08a4d27f534 82 // In some effect we want to just take bool and write it to a voxel
Bas 1:e08a4d27f534 83 // this function calls the apropriate voxel manipulation function.
Bas 1:e08a4d27f534 84 void LED_CUBE::alterVoxel(unsigned char x, unsigned char y, unsigned char z, unsigned char state)
Bas 1:e08a4d27f534 85 {
Bas 1:e08a4d27f534 86 if (state == 1) {
Bas 1:e08a4d27f534 87 setVoxel(x,y,z);
Bas 1:e08a4d27f534 88 } else {
Bas 1:e08a4d27f534 89 clearVoxel(x,y,z);
Bas 1:e08a4d27f534 90 }
Bas 1:e08a4d27f534 91 }
Bas 1:e08a4d27f534 92
Bas 1:e08a4d27f534 93 // Flip the state of a voxel.
Bas 1:e08a4d27f534 94 // If the voxel is 1, its turned into a 0, and vice versa.
Bas 1:e08a4d27f534 95 void LED_CUBE::flipVoxel(unsigned char x, unsigned char y, unsigned char z)
Bas 1:e08a4d27f534 96 {
Bas 1:e08a4d27f534 97 if (inrange(x, y, z))
Bas 1:e08a4d27f534 98 cubeData[z*8 + x] ^= (1 << y);
Bas 1:e08a4d27f534 99 }
Bas 1:e08a4d27f534 100
Bas 1:e08a4d27f534 101 void LED_CUBE::setPlane_x (int x)
Bas 1:e08a4d27f534 102 {
Bas 1:e08a4d27f534 103 int z;
Bas 1:e08a4d27f534 104
Bas 1:e08a4d27f534 105 if (x>=0 && x<8) {
Bas 1:e08a4d27f534 106 for (z=0; z<8; z++)
Bas 1:e08a4d27f534 107 cubeData[z*8 + x] = 0xFF;
Bas 1:e08a4d27f534 108 }
Bas 1:e08a4d27f534 109 }
Bas 1:e08a4d27f534 110
Bas 1:e08a4d27f534 111 void LED_CUBE::clearPlane_x (int x)
Bas 1:e08a4d27f534 112 {
Bas 1:e08a4d27f534 113 int z;
Bas 1:e08a4d27f534 114
Bas 1:e08a4d27f534 115 if (x>=0 && x<8) {
Bas 1:e08a4d27f534 116 for (z=0; z<8; z++)
Bas 1:e08a4d27f534 117 cubeData[z*8 + x] = 0x00;
Bas 1:e08a4d27f534 118 }
Bas 1:e08a4d27f534 119 }
Bas 1:e08a4d27f534 120
Bas 1:e08a4d27f534 121 void LED_CUBE::setPlane_y (int y)
Bas 1:e08a4d27f534 122 {
Bas 1:e08a4d27f534 123 int z;
Bas 1:e08a4d27f534 124 int x;
Bas 1:e08a4d27f534 125
Bas 1:e08a4d27f534 126 if (y>=0 && y<8) {
Bas 1:e08a4d27f534 127 for (z=0; z<8; z++) {
Bas 1:e08a4d27f534 128 for (x=0; x<8; x++) {
Bas 1:e08a4d27f534 129 cubeData[z*8 + x] |= (1 << y);
Bas 1:e08a4d27f534 130 }
Bas 1:e08a4d27f534 131 }
Bas 1:e08a4d27f534 132 }
Bas 1:e08a4d27f534 133 }
Bas 1:e08a4d27f534 134
Bas 1:e08a4d27f534 135 void LED_CUBE::clearPlane_y (int y)
Bas 1:e08a4d27f534 136 {
Bas 1:e08a4d27f534 137 int z;
Bas 1:e08a4d27f534 138 int x;
Bas 1:e08a4d27f534 139
Bas 1:e08a4d27f534 140 if (y>=0 && y<8) {
Bas 1:e08a4d27f534 141 for (z=0; z<8; z++) {
Bas 1:e08a4d27f534 142 for (x=0; x<8; x++) {
Bas 1:e08a4d27f534 143 cubeData[z*8 + x] &= ~(1 << y);
Bas 1:e08a4d27f534 144 }
Bas 1:e08a4d27f534 145 }
Bas 1:e08a4d27f534 146 }
Bas 1:e08a4d27f534 147 }
Bas 1:e08a4d27f534 148 // Sets all voxels along a X/Y plane at a given point
Bas 1:e08a4d27f534 149 // on axis Z
Bas 1:e08a4d27f534 150 void LED_CUBE::setPlane_z (int z)
Bas 1:e08a4d27f534 151 {
Bas 1:e08a4d27f534 152 int i;
Bas 1:e08a4d27f534 153
Bas 1:e08a4d27f534 154 if (z>=0 && z<8) {
Bas 1:e08a4d27f534 155 for (i=0; i<8; i++)
Bas 1:e08a4d27f534 156 cubeData[z*8 + i] = 0xFF;
Bas 1:e08a4d27f534 157 }
Bas 1:e08a4d27f534 158 }
Bas 1:e08a4d27f534 159
Bas 1:e08a4d27f534 160 // Clears voxels in the same manner as above
Bas 1:e08a4d27f534 161 void LED_CUBE::clearPlane_z (int z)
Bas 1:e08a4d27f534 162 {
Bas 1:e08a4d27f534 163 int i;
Bas 1:e08a4d27f534 164
Bas 1:e08a4d27f534 165 if (z>=0 && z<8) {
Bas 1:e08a4d27f534 166 for (i=0; i<8; i++)
Bas 1:e08a4d27f534 167 cubeData[z*8 + i] = 0x00;
Bas 1:e08a4d27f534 168 }
Bas 1:e08a4d27f534 169 }
Bas 1:e08a4d27f534 170
Bas 1:e08a4d27f534 171 void LED_CUBE::setPlane (char axis, unsigned char i)
Bas 1:e08a4d27f534 172 {
Bas 1:e08a4d27f534 173 switch (axis) {
Bas 1:e08a4d27f534 174 case AXIS_X:
Bas 1:e08a4d27f534 175 setPlane_x(i);
Bas 1:e08a4d27f534 176 break;
Bas 1:e08a4d27f534 177 case AXIS_Y:
Bas 1:e08a4d27f534 178 setPlane_y(i);
Bas 1:e08a4d27f534 179 break;
Bas 1:e08a4d27f534 180 case AXIS_Z:
Bas 1:e08a4d27f534 181 setPlane_z(i);
Bas 1:e08a4d27f534 182 break;
Bas 1:e08a4d27f534 183 }
Bas 1:e08a4d27f534 184 }
Bas 1:e08a4d27f534 185
Bas 1:e08a4d27f534 186 void LED_CUBE::clearPlane (char axis, unsigned char i)
Bas 1:e08a4d27f534 187 {
Bas 1:e08a4d27f534 188 switch (axis) {
Bas 1:e08a4d27f534 189 case AXIS_X:
Bas 1:e08a4d27f534 190 clearPlane_x(i);
Bas 1:e08a4d27f534 191 break;
Bas 1:e08a4d27f534 192 case AXIS_Y:
Bas 1:e08a4d27f534 193 clearPlane_y(i);
Bas 1:e08a4d27f534 194 break;
Bas 1:e08a4d27f534 195 case AXIS_Z:
Bas 1:e08a4d27f534 196 clearPlane_z(i);
Bas 1:e08a4d27f534 197 break;
Bas 1:e08a4d27f534 198 }
Bas 1:e08a4d27f534 199 }
Bas 1:e08a4d27f534 200 void LED_CUBE::setSlope_XY(int x1, int y1, int x2, int y2)
Bas 1:e08a4d27f534 201 {
Bas 1:e08a4d27f534 202 float slope, offset;
Bas 1:e08a4d27f534 203 int x,y,z;
Bas 1:e08a4d27f534 204
Bas 1:e08a4d27f534 205 if (x1>x2) {
Bas 1:e08a4d27f534 206 int tmp;
Bas 1:e08a4d27f534 207 tmp = x2;
Bas 1:e08a4d27f534 208 x2 = x1;
Bas 1:e08a4d27f534 209 x1 = tmp;
Bas 1:e08a4d27f534 210 tmp = y2;
Bas 1:e08a4d27f534 211 y2 = y1;
Bas 1:e08a4d27f534 212 y1 = tmp;
Bas 1:e08a4d27f534 213 }
Bas 1:e08a4d27f534 214
Bas 1:e08a4d27f534 215 slope=float(y2-y1)/float(x2-x1);
Bas 1:e08a4d27f534 216 offset=-x1*slope +y1;
Bas 1:e08a4d27f534 217
Bas 1:e08a4d27f534 218 if ((x2-x1)>=7) {
Bas 1:e08a4d27f534 219 for(x=0; x<8; x++) {
Bas 1:e08a4d27f534 220 y = floor((x*slope + offset)+0.5);
Bas 1:e08a4d27f534 221 for(z=0; z<8; z++) {
Bas 1:e08a4d27f534 222 setVoxel(x,y,z);
Bas 1:e08a4d27f534 223 }
Bas 1:e08a4d27f534 224 }
Bas 1:e08a4d27f534 225 } else if(x1==x2) {
Bas 1:e08a4d27f534 226 for(y=0; y<8; y++) {
Bas 1:e08a4d27f534 227 for(z=0; z<8; z++) {
Bas 1:e08a4d27f534 228 setVoxel(x1,y,z);
Bas 1:e08a4d27f534 229 }
Bas 1:e08a4d27f534 230 }
Bas 1:e08a4d27f534 231 } else {
Bas 1:e08a4d27f534 232 for(y=0; y<8; y++) {
Bas 1:e08a4d27f534 233 x = floor(((y-offset)/slope)+0.5);
Bas 1:e08a4d27f534 234 for(z=0; z<8; z++) {
Bas 1:e08a4d27f534 235 setVoxel(x,y,z);
Bas 1:e08a4d27f534 236 }
Bas 1:e08a4d27f534 237
Bas 1:e08a4d27f534 238 }
Bas 1:e08a4d27f534 239 }
Bas 1:e08a4d27f534 240 }
Bas 1:e08a4d27f534 241
Bas 1:e08a4d27f534 242 void LED_CUBE::setSlope_XZ(int x1, int z1, int x2, int z2)
Bas 1:e08a4d27f534 243 {
Bas 1:e08a4d27f534 244 float slope, offset;
Bas 1:e08a4d27f534 245 int x,z;
Bas 1:e08a4d27f534 246
Bas 1:e08a4d27f534 247 if (x1>x2) {
Bas 1:e08a4d27f534 248 int tmp;
Bas 1:e08a4d27f534 249 tmp = x2;
Bas 1:e08a4d27f534 250 x2 = x1;
Bas 1:e08a4d27f534 251 x1 = tmp;
Bas 1:e08a4d27f534 252 tmp = z2;
Bas 1:e08a4d27f534 253 z2 = z1;
Bas 1:e08a4d27f534 254 z1 = tmp;
Bas 1:e08a4d27f534 255 }
Bas 1:e08a4d27f534 256
Bas 1:e08a4d27f534 257 slope=float(z2-z1)/float(x2-x1);
Bas 1:e08a4d27f534 258 offset=-x1*slope +z1;
Bas 1:e08a4d27f534 259
Bas 1:e08a4d27f534 260 if ((x2-x1)>=7) {
Bas 1:e08a4d27f534 261 for(x=0; x<8; x++) {
Bas 1:e08a4d27f534 262 z = floor((x*slope + offset)+0.5);
Bas 1:e08a4d27f534 263 cubeData[z*8 + x] = 0xFF;
Bas 1:e08a4d27f534 264
Bas 1:e08a4d27f534 265 }
Bas 1:e08a4d27f534 266 } else if(x1==x2) {
Bas 1:e08a4d27f534 267 for(z=0; z<8; z++) {
Bas 1:e08a4d27f534 268 cubeData[z*8 + x1] = 0xFF;
Bas 1:e08a4d27f534 269
Bas 1:e08a4d27f534 270 }
Bas 1:e08a4d27f534 271 } else {
Bas 1:e08a4d27f534 272 for(z=0; z<8; z++) {
Bas 1:e08a4d27f534 273 x = floor(((z-offset)/slope)+0.5);
Bas 1:e08a4d27f534 274 cubeData[z*8 + x] = 0xFF;
Bas 1:e08a4d27f534 275
Bas 1:e08a4d27f534 276 }
Bas 1:e08a4d27f534 277
Bas 1:e08a4d27f534 278 }
Bas 1:e08a4d27f534 279 }
Bas 1:e08a4d27f534 280
Bas 1:e08a4d27f534 281
Bas 1:e08a4d27f534 282 void LED_CUBE::setSlope_YZ(int y1, int z1, int y2, int z2)
Bas 1:e08a4d27f534 283 {
Bas 1:e08a4d27f534 284 float slope, offset;
Bas 1:e08a4d27f534 285 int x,y,z;
Bas 1:e08a4d27f534 286
Bas 1:e08a4d27f534 287 if (y1>y2) {
Bas 1:e08a4d27f534 288 int tmp;
Bas 1:e08a4d27f534 289 tmp = y2;
Bas 1:e08a4d27f534 290 y2 = y1;
Bas 1:e08a4d27f534 291 y1 = tmp;
Bas 1:e08a4d27f534 292 tmp = z2;
Bas 1:e08a4d27f534 293 z2 = z1;
Bas 1:e08a4d27f534 294 z1 = tmp;
Bas 1:e08a4d27f534 295 }
Bas 1:e08a4d27f534 296
Bas 1:e08a4d27f534 297 slope=float(z2-z1)/float(y2-y1);
Bas 1:e08a4d27f534 298 offset=-y1*slope +z1;
Bas 1:e08a4d27f534 299
Bas 1:e08a4d27f534 300 if ((y2-y1)>=7) {
Bas 1:e08a4d27f534 301 for(y=0; y<8; y++) {
Bas 1:e08a4d27f534 302 z = floor((y*slope + offset)+0.5);
Bas 1:e08a4d27f534 303 for(x=0; x<8; x++) {
Bas 1:e08a4d27f534 304 setVoxel(x,y,z);
Bas 1:e08a4d27f534 305 }
Bas 1:e08a4d27f534 306 }
Bas 1:e08a4d27f534 307 } else if(y1==y2) {
Bas 1:e08a4d27f534 308 for(z=0; z<8; z++) {
Bas 1:e08a4d27f534 309 for(x=0; x<8; x++) {
Bas 1:e08a4d27f534 310 setVoxel(x,y1,z);
Bas 1:e08a4d27f534 311 }
Bas 1:e08a4d27f534 312 }
Bas 1:e08a4d27f534 313 } else {
Bas 1:e08a4d27f534 314 for(z=0; z<8; z++) {
Bas 1:e08a4d27f534 315 y = floor(((z-offset)/slope)+0.5);
Bas 1:e08a4d27f534 316 for(x=0; x<8; x++) {
Bas 1:e08a4d27f534 317 setVoxel(x,y,z);
Bas 1:e08a4d27f534 318 }
Bas 1:e08a4d27f534 319 }
Bas 1:e08a4d27f534 320
Bas 1:e08a4d27f534 321 }
Bas 1:e08a4d27f534 322 }
Bas 1:e08a4d27f534 323
Bas 0:920c5ed65a45 324 //clear all the voxels in the array
Bas 1:e08a4d27f534 325 void LED_CUBE::clearVoxels(void)
Bas 1:e08a4d27f534 326 {
Bas 0:920c5ed65a45 327 memset(cubeData, 0, 64*sizeof(unsigned char));
Bas 1:e08a4d27f534 328 }
Bas 1:e08a4d27f534 329
Bas 1:e08a4d27f534 330 // Fill a value into all 64 byts of the cube buffer
Bas 1:e08a4d27f534 331 // Mostly used for clearing. fill(0xr0)
Bas 1:e08a4d27f534 332 // or setting all on. fill(0xff)
Bas 1:e08a4d27f534 333 void LED_CUBE::fill (unsigned char pattern)
Bas 1:e08a4d27f534 334 {
Bas 1:e08a4d27f534 335 memset(cubeData, pattern, 64*sizeof(unsigned char));
Bas 1:e08a4d27f534 336 }
Bas 1:e08a4d27f534 337
Bas 1:e08a4d27f534 338 // Draw a box with all walls drawn and all voxels inside set
Bas 1:e08a4d27f534 339 void LED_CUBE::box_filled(int x1, int y1, int z1, int x2, int y2, int z2)
Bas 1:e08a4d27f534 340 {
Bas 1:e08a4d27f534 341 int ix;
Bas 1:e08a4d27f534 342 int iz;
Bas 1:e08a4d27f534 343
Bas 1:e08a4d27f534 344 argorder(x1, x2, &x1, &x2);
Bas 1:e08a4d27f534 345 argorder(y1, y2, &y1, &y2);
Bas 1:e08a4d27f534 346 argorder(z1, z2, &z1, &z2);
Bas 1:e08a4d27f534 347 for (iz=z1; iz<=z2; iz++) {
Bas 1:e08a4d27f534 348 for (ix=x1; ix<=x2; ix++) {
Bas 1:e08a4d27f534 349 cubeData[iz*8 + ix] |= byteline(y1,y2);
Bas 1:e08a4d27f534 350 }
Bas 1:e08a4d27f534 351 }
Bas 1:e08a4d27f534 352 }
Bas 1:e08a4d27f534 353
Bas 1:e08a4d27f534 354 // Draw a hollow box with side walls.
Bas 1:e08a4d27f534 355 void LED_CUBE::box_walls(int x1, int y1, int z1, int x2, int y2, int z2)
Bas 1:e08a4d27f534 356 {
Bas 1:e08a4d27f534 357 int ix;
Bas 1:e08a4d27f534 358 int iz;
Bas 1:e08a4d27f534 359
Bas 1:e08a4d27f534 360 argorder(x1, x2, &x1, &x2);
Bas 1:e08a4d27f534 361 argorder(y1, y2, &y1, &y2);
Bas 1:e08a4d27f534 362 argorder(z1, z2, &z1, &z2);
Bas 1:e08a4d27f534 363 for (iz=z1; iz<=z2; iz++) {
Bas 1:e08a4d27f534 364 for (ix=x1; ix<=x2; ix++) {
Bas 1:e08a4d27f534 365 if (ix == x1 || ix == x2 || iz == z1 || iz == z2) {
Bas 1:e08a4d27f534 366 cubeData[iz*8 + ix] = byteline(y1,y2);
Bas 1:e08a4d27f534 367 } else {
Bas 1:e08a4d27f534 368 cubeData[iz*8 + ix] |= ((0x01 << y1) | (0x01 << y2));
Bas 1:e08a4d27f534 369 }
Bas 1:e08a4d27f534 370 }
Bas 1:e08a4d27f534 371 }
Bas 1:e08a4d27f534 372 }
Bas 1:e08a4d27f534 373
Bas 1:e08a4d27f534 374 // Draw a wireframe box. This only draws the corners and edges,
Bas 1:e08a4d27f534 375 // no walls.
Bas 1:e08a4d27f534 376 void LED_CUBE::box_wireframe(int x1, int y1, int z1, int x2, int y2, int z2)
Bas 1:e08a4d27f534 377 {
Bas 1:e08a4d27f534 378 int ix;
Bas 1:e08a4d27f534 379 int iz;
Bas 1:e08a4d27f534 380
Bas 1:e08a4d27f534 381 argorder(x1, x2, &x1, &x2);
Bas 1:e08a4d27f534 382 argorder(y1, y2, &y1, &y2);
Bas 1:e08a4d27f534 383 argorder(z1, z2, &z1, &z2);
Bas 1:e08a4d27f534 384 // Lines along Y axis
Bas 1:e08a4d27f534 385 cubeData[z1*8 + x1] |= byteline(y1,y2);
Bas 1:e08a4d27f534 386 cubeData[z1*8 + x2] |= byteline(y1,y2);
Bas 1:e08a4d27f534 387 cubeData[z2*8 + x1] |= byteline(y1,y2);
Bas 1:e08a4d27f534 388 cubeData[z2*8 + x2] |= byteline(y1,y2);
Bas 1:e08a4d27f534 389 // Lines along X axis
Bas 1:e08a4d27f534 390 for (ix=x1; ix<=x2; ix++) {
Bas 1:e08a4d27f534 391 setVoxel(ix,y1,z1);
Bas 1:e08a4d27f534 392 setVoxel(ix,y1,z2);
Bas 1:e08a4d27f534 393 setVoxel(ix,y2,z1);
Bas 1:e08a4d27f534 394 setVoxel(ix,y2,z2);
Bas 1:e08a4d27f534 395 }
Bas 1:e08a4d27f534 396 // Lines along Z axis
Bas 1:e08a4d27f534 397 for (iz=z1; iz<=z2; iz++) {
Bas 1:e08a4d27f534 398 setVoxel(x1,y1,iz);
Bas 1:e08a4d27f534 399 setVoxel(x1,y2,iz);
Bas 1:e08a4d27f534 400 setVoxel(x2,y1,iz);
Bas 1:e08a4d27f534 401 setVoxel(x2,y2,iz);
Bas 1:e08a4d27f534 402 }
Bas 1:e08a4d27f534 403 }
Bas 1:e08a4d27f534 404
Bas 1:e08a4d27f534 405 // Draw a line between any coordinates in 3d space.
Bas 1:e08a4d27f534 406 // Uses integer values for input, so dont expect smooth animations.
Bas 1:e08a4d27f534 407 void LED_CUBE::line(int x1, int y1, int z1, int x2, int y2, int z2)
Bas 1:e08a4d27f534 408 {
Bas 1:e08a4d27f534 409 float xy;
Bas 1:e08a4d27f534 410 // how many voxels do we move on the y axis for each step on the x axis
Bas 1:e08a4d27f534 411 float xz;
Bas 1:e08a4d27f534 412 // how many voxels do we move on the y axis for each step on the x axis
Bas 1:e08a4d27f534 413 unsigned char x,y,z;
Bas 1:e08a4d27f534 414 // We always want to draw the line from x=0 to x=7.
Bas 1:e08a4d27f534 415 // If x1 is bigget than x2, we need to flip all the values.
Bas 1:e08a4d27f534 416 if (x1>x2) {
Bas 1:e08a4d27f534 417 int tmp;
Bas 1:e08a4d27f534 418 tmp = x2;
Bas 1:e08a4d27f534 419 x2 = x1;
Bas 1:e08a4d27f534 420 x1 = tmp;
Bas 1:e08a4d27f534 421 tmp = y2;
Bas 1:e08a4d27f534 422 y2 = y1;
Bas 1:e08a4d27f534 423 y1 = tmp;
Bas 1:e08a4d27f534 424 tmp = z2;
Bas 1:e08a4d27f534 425 z2 = z1;
Bas 1:e08a4d27f534 426 z1 = tmp;
Bas 1:e08a4d27f534 427 }
Bas 1:e08a4d27f534 428 if (y1>y2) {
Bas 1:e08a4d27f534 429 xy = (float)(y1-y2)/(float)(x2-x1);
Bas 1:e08a4d27f534 430 } else {
Bas 1:e08a4d27f534 431 xy = (float)(y2-y1)/(float)(x2-x1);
Bas 1:e08a4d27f534 432 }
Bas 1:e08a4d27f534 433 if (z1>z2) {
Bas 1:e08a4d27f534 434 xz = (float)(z1-z2)/(float)(x2-x1);
Bas 1:e08a4d27f534 435 } else {
Bas 1:e08a4d27f534 436 xz = (float)(z2-z1)/(float)(x2-x1);
Bas 1:e08a4d27f534 437 }
Bas 1:e08a4d27f534 438 // For each step of x, y increments by:
Bas 1:e08a4d27f534 439 for (x = x1; x<=x2; x++) {
Bas 1:e08a4d27f534 440 y = (xy*(x-x1))+y1;
Bas 1:e08a4d27f534 441 z = (xz*(x-x1))+z1;
Bas 1:e08a4d27f534 442 setVoxel(x,y,z);
Bas 1:e08a4d27f534 443 }
Bas 1:e08a4d27f534 444 }
Bas 1:e08a4d27f534 445 void LED_CUBE::circle(int xr, int yr, int zr, int d ,char axis)
Bas 1:e08a4d27f534 446 {
Bas 1:e08a4d27f534 447 if (d%2) { // odd diameter, place center on half pixels
Bas 1:e08a4d27f534 448 // later
Bas 1:e08a4d27f534 449 } else { // use midpoint circle algorithm
Bas 1:e08a4d27f534 450 int r = d/2;
Bas 1:e08a4d27f534 451 int f = 1 - r;
Bas 1:e08a4d27f534 452 int ddF_x = 1;
Bas 1:e08a4d27f534 453 int ddF_y = -2 * r;
Bas 1:e08a4d27f534 454 int x = 0;
Bas 1:e08a4d27f534 455 int y = r;
Bas 1:e08a4d27f534 456
Bas 1:e08a4d27f534 457 setVoxel(xr, yr+r, zr);
Bas 1:e08a4d27f534 458 setVoxel(xr, yr-r, zr);
Bas 1:e08a4d27f534 459 setVoxel(xr+r, yr, zr);
Bas 1:e08a4d27f534 460 setVoxel(xr-r, yr, zr);
Bas 1:e08a4d27f534 461 while (x<y) {
Bas 1:e08a4d27f534 462 if (f >= 0) {
Bas 1:e08a4d27f534 463 y--;
Bas 1:e08a4d27f534 464 ddF_y += 2;
Bas 1:e08a4d27f534 465 f += ddF_y;
Bas 1:e08a4d27f534 466 }
Bas 1:e08a4d27f534 467 x++;
Bas 1:e08a4d27f534 468 ddF_x += 2;
Bas 1:e08a4d27f534 469 f += ddF_x;
Bas 1:e08a4d27f534 470
Bas 1:e08a4d27f534 471 setVoxel(xr + x, yr + y, zr);
Bas 1:e08a4d27f534 472 setVoxel(xr - x, yr + y, zr);
Bas 1:e08a4d27f534 473 setVoxel(xr + x, yr - y, zr);
Bas 1:e08a4d27f534 474 setVoxel(xr - x, yr - y, zr);
Bas 1:e08a4d27f534 475 setVoxel(xr + y, yr + x, zr);
Bas 1:e08a4d27f534 476 setVoxel(xr - y, yr + x, zr);
Bas 1:e08a4d27f534 477 setVoxel(xr + y, yr - x, zr);
Bas 1:e08a4d27f534 478 setVoxel(xr - y, yr - x, zr);
Bas 1:e08a4d27f534 479 }
Bas 1:e08a4d27f534 480 }
Bas 1:e08a4d27f534 481 }
Bas 1:e08a4d27f534 482
Bas 1:e08a4d27f534 483 void LED_CUBE::CopyBlock(int x1, int y1, int z1, int x2, int y2, int z2, int xc, int yc, int zc)
Bas 1:e08a4d27f534 484 {
Bas 1:e08a4d27f534 485 int ix;
Bas 1:e08a4d27f534 486 int iz;
Bas 1:e08a4d27f534 487 int nx;
Bas 1:e08a4d27f534 488 int nz=0;
Bas 1:e08a4d27f534 489 unsigned char tmp_data[64];
Bas 1:e08a4d27f534 490
Bas 1:e08a4d27f534 491 argorder(x1, x2, &x1, &x2);
Bas 1:e08a4d27f534 492 argorder(y1, y2, &y1, &y2);
Bas 1:e08a4d27f534 493 argorder(z1, z2, &z1, &z2);
Bas 1:e08a4d27f534 494
Bas 1:e08a4d27f534 495 for (iz=z1; iz<=z2; iz++) {
Bas 1:e08a4d27f534 496 nx=0;
Bas 1:e08a4d27f534 497 for (ix=x1; ix<=x2; ix++) {
Bas 1:e08a4d27f534 498 //copy block data into tmp array and mask.
Bas 1:e08a4d27f534 499 tmp_data[iz*8 + ix] = cubeData[iz*8 + ix] & byteline(y1,y2);
Bas 1:e08a4d27f534 500 //shift the tmp data to the new y location
Bas 1:e08a4d27f534 501 if (yc >= y1) {
Bas 1:e08a4d27f534 502 tmp_data[iz*8 + ix] = tmp_data[iz*8 + ix] << (yc-y1);
Bas 1:e08a4d27f534 503 } else {
Bas 1:e08a4d27f534 504 tmp_data[iz*8 + ix] = tmp_data[iz*8 + ix] >> (y1-yc);
Bas 1:e08a4d27f534 505 }
Bas 1:e08a4d27f534 506 //alter the cubedata on the new x and z location with the tmp data. use old y location and copy to the new location
Bas 1:e08a4d27f534 507 cubeData[(zc+nz)*8 + xc+nx] = (cubeData[(zc+nz)*8 + xc+nx] & (~byteline(yc,yc+y2-y1))) | tmp_data[iz*8 + ix];
Bas 1:e08a4d27f534 508 nx++;
Bas 1:e08a4d27f534 509 }
Bas 1:e08a4d27f534 510 nz++;
Bas 1:e08a4d27f534 511 }
Bas 1:e08a4d27f534 512 }
Bas 1:e08a4d27f534 513
Bas 1:e08a4d27f534 514 void LED_CUBE::MoveBlock(int x1, int y1, int z1, int x2, int y2, int z2, int xm, int ym, int zm)
Bas 1:e08a4d27f534 515 {
Bas 1:e08a4d27f534 516 int ix;
Bas 1:e08a4d27f534 517 int iz;
Bas 1:e08a4d27f534 518 int nx;
Bas 1:e08a4d27f534 519 int nz=0;
Bas 1:e08a4d27f534 520 unsigned char tmp_data[64];
Bas 1:e08a4d27f534 521
Bas 1:e08a4d27f534 522 argorder(x1, x2, &x1, &x2);
Bas 1:e08a4d27f534 523 argorder(y1, y2, &y1, &y2);
Bas 1:e08a4d27f534 524 argorder(z1, z2, &z1, &z2);
Bas 1:e08a4d27f534 525
Bas 1:e08a4d27f534 526 for (iz=z1; iz<=z2; iz++) {
Bas 1:e08a4d27f534 527 for (ix=x1; ix<=x2; ix++) {
Bas 1:e08a4d27f534 528 //copy block data into tmp array and mask.
Bas 1:e08a4d27f534 529 tmp_data[iz*8 + ix] = cubeData[iz*8 + ix] & byteline(y1,y2);
Bas 1:e08a4d27f534 530 //clear the original voxels
Bas 1:e08a4d27f534 531 cubeData[iz*8 + ix] &= ~byteline(y1,y2);
Bas 1:e08a4d27f534 532 //shift the tmp data to the new y location
Bas 1:e08a4d27f534 533 if (ym >= y1) {
Bas 1:e08a4d27f534 534 tmp_data[iz*8 + ix] = tmp_data[iz*8 + ix] << (ym-y1);
Bas 1:e08a4d27f534 535 } else {
Bas 1:e08a4d27f534 536 tmp_data[iz*8 + ix] = tmp_data[iz*8 + ix] >> (y1-ym);
Bas 1:e08a4d27f534 537 }
Bas 1:e08a4d27f534 538 }
Bas 1:e08a4d27f534 539 }
Bas 1:e08a4d27f534 540
Bas 1:e08a4d27f534 541 for (iz=z1; iz<=z2; iz++) {
Bas 1:e08a4d27f534 542 nx=0;
Bas 1:e08a4d27f534 543 for (ix=x1; ix<=x2; ix++) {
Bas 1:e08a4d27f534 544
Bas 1:e08a4d27f534 545 //alter the cubedata on the new x and z location with the tmp data. use old y location and copy to the new location
Bas 1:e08a4d27f534 546 cubeData[(zm+nz)*8 + xm+nx] = (cubeData[(zm+nz)*8 + xm+nx] & (~byteline(ym,ym+y2-y1))) | tmp_data[iz*8 + ix];
Bas 1:e08a4d27f534 547 nx++;
Bas 1:e08a4d27f534 548 }
Bas 1:e08a4d27f534 549 nz++;
Bas 1:e08a4d27f534 550 }
Bas 1:e08a4d27f534 551 }
Bas 1:e08a4d27f534 552
Bas 1:e08a4d27f534 553 char LED_CUBE::byteline (int start, int end)
Bas 1:e08a4d27f534 554 {
Bas 1:e08a4d27f534 555 char line=0;
Bas 1:e08a4d27f534 556 int bitnr;
Bas 1:e08a4d27f534 557
Bas 1:e08a4d27f534 558 for (bitnr=0; bitnr<8; bitnr++) {
Bas 1:e08a4d27f534 559 if (bitnr>=start && bitnr<=end) {
Bas 1:e08a4d27f534 560 line |= (1<<bitnr);
Bas 1:e08a4d27f534 561 }
Bas 1:e08a4d27f534 562 }
Bas 1:e08a4d27f534 563 return line;
Bas 1:e08a4d27f534 564 }
Bas 1:e08a4d27f534 565
Bas 1:e08a4d27f534 566 // This function validates that we are drawing inside the cube.
Bas 1:e08a4d27f534 567 unsigned char LED_CUBE::inrange(int x, int y, int z)
Bas 1:e08a4d27f534 568 {
Bas 1:e08a4d27f534 569 if (x >= 0 && x < 8 && y >= 0 && y < 8 && z >= 0 && z < 8) {
Bas 1:e08a4d27f534 570 return 0x01;
Bas 1:e08a4d27f534 571 } else {
Bas 1:e08a4d27f534 572 // One of the coordinates was outside the cube.
Bas 1:e08a4d27f534 573 return 0x00;
Bas 1:e08a4d27f534 574 }
Bas 1:e08a4d27f534 575 }
Bas 1:e08a4d27f534 576
Bas 1:e08a4d27f534 577 void LED_CUBE::argorder(int ix1, int ix2, int *ox1, int *ox2)
Bas 1:e08a4d27f534 578 {
Bas 1:e08a4d27f534 579 if (ix1>ix2) {
Bas 1:e08a4d27f534 580 int tmp;
Bas 1:e08a4d27f534 581 tmp = ix1;
Bas 1:e08a4d27f534 582 ix1= ix2;
Bas 1:e08a4d27f534 583 ix2 = tmp;
Bas 1:e08a4d27f534 584 }
Bas 1:e08a4d27f534 585 *ox1 = ix1;
Bas 1:e08a4d27f534 586 *ox2 = ix2;
Bas 1:e08a4d27f534 587 }
Bas 1:e08a4d27f534 588
Bas 1:e08a4d27f534 589 double LED_CUBE::map(double in, double inMin, double inMax, double outMin, double outMax)
Bas 1:e08a4d27f534 590 {
Bas 1:e08a4d27f534 591 double out;
Bas 1:e08a4d27f534 592 out = (in-inMin)/(inMax-inMin)*(outMax-outMin) + outMin;
Bas 1:e08a4d27f534 593 return out;
Bas 0:920c5ed65a45 594 }