Всем привет. Собрали куб 8x8x8 - делаем эффекты. Лично у меня такие вопросы: 1. Как правильно (интересует логика - формула) зажечь светодиод в середине куба ??? Как для этого вывести формулу. Я могу зажечь уровень, столбец, но с другими эффектами проблемы. 2. Как правильно вращать допустим фигуру в координатах x=8, y=8, z=8? 3. Как можно оптимизировать данный код во вложении???
2. Описать фигуру в полярных координатах. Тогда ее вращение - это прибавление угла, а потом проекция на ось.
Каждый диод определяется вектором (i,j,k) фактически это координаты диода. Дальше гуглим "афинные преобразования". Там будет и оператор движения, и оператор поворота, и оператор подобия. Оператор это матрица. Если умножить вектор на матрицу (гуглим), то этот вектор (координаты) изменится в соответствии с параметрами оператора. Чтобы повернуть, например, куб в пространстве потребно на все его вершины (векторы) подействовать оператором (умножить на матрицу).
Допустим, делаю массив для каждой координинаты (x,y,z) byte Massive[8][8][8]={}; , далее заполняю массив данными, т.е. координатами в байтах. А вот дальше начинаются вопросы, как с этими данными работать )))) .
Ничего сложного там нет. Я не написал готовых формул только потому, что очень длинно. Умножение матрицы на вектор это три довольно длинные строчки.
С такой маленькой матрицей растеризовать векторные фигуры будет не очень рационально, хотя и идеологически правильно. Думаю имеет смысл нарисовать заранее визуально выверенных 3D-спрайтов.
Со спрайтами проще конечно. Я вот двумя способами проецирую картинку на 8х8: 1. Два одномерных байтовых массива, в одном биты зеленого по строкам, во втором красного. Получается оптимально для компьютера, то есть он тратит минимум ресурсов на закидывание информации в регистры. Но не очень удобно для меня, так как цветоделение надо делать в голове. ) 2. Один двумерный массив 8х8 в котором каждый член может принимать три значения: 0-выкл, 1-зеленый, 2-красный, 3- оба цвета, то есть желтый. Спрайт нарисовать проще, так как картинка практически видна невооруженным глазом, но на побайтное построковое разделение тратятся ресурсы, боюсь что дополнительные вычисления могут привести к дрожанию картинки. Сделать небольшой мультик из нескольких кадров достаточно легко, а вот что то шевелящееся в зависимости от датчиков или времени... Даже не знаю с какого угла подойти. вот оба типа данных для картинок: Код (Text): byte masRed1[8] = { // красная матрица: 0-вкл, 1-выкл 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, }; byte masGreen1[8] = { // зеленая матрица: 0-вкл, 1-выкл 0b11100111, 0b11100111, 0b11100111, 0b00000000, 0b00000000, 0b11100111, 0b11100111, 0b11100111, }; byte masRG [8][8] = { // красн-зеленая матрица: 0-выкл, 1-Red, 2-Green, 3-Yellow {1, 1, 1, 1, 1, 1, 1, 1}, {1, 2, 2, 2, 2, 2, 2, 1}, {1, 2, 1, 1, 1, 1, 2, 1}, {1, 2, 1, 0, 3, 1, 2, 1}, {1, 2, 1, 3, 0, 1, 2, 1}, {1, 2, 1, 1, 1, 1, 2, 1}, {1, 2, 2, 2, 2, 2, 2, 1}, {1, 1, 1, 1, 1, 1, 1, 1} };
Спрайты можно нарисовать и на компе в графическом редакторе, потом на чем-нибудь наваять компилятор спрайтов в сишный код, его подключить в скетч библиотекой и залить в ардуину.
Я вот думаю, может спрайты на SD записать в текстовом виде например? Потом считывать в массив по мере надобности. Или это медленно будет?
Вот такой код у нас генерирует эффекты для куба Код (Text): //Пин подключен к ST_CP входу 74HC595 int latchPin = 3; //Пин подключен к SH_CP входу 74HC595 int clockPin = 2; //Пин подключен к DS входу 74HC595 int dataPin = 4; int myPins[] = {6, 7, 8, 9, 10, 11, 12, 13}; //массив пинов - выходы для строк byte MyMassive[64]; //массив диодов byte Massive[8]={1,2,4,8,16,32,64,128}; byte films[1536]; int i,j,x,y,z,f,ff; byte a,aa,bb,b,ab,c,cc; void setup() { // Serial.begin(9600); a,aa,b,bb=0; //устанавливаем режим OUTPUT pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); for (i = 0; i <=7; i++) { //столбы pinMode(myPins[i],OUTPUT); digitalWrite(latchPin, LOW); // передаем последовательно на dataPin } for(ff=0; ff<7; ff++){ for(f=0; f<63; f++){ films[f+ff*64]=0; } // Serial.print(films[f]); } int abc; abc=73; // 72 вверх, 73 диагональ, 65 направо, 56 вертикаль-вниз films[0]=255; films[abc*1]=255; films[abc*2]=255; films[abc*3]=255; films[abc*4]=255; films[abc*5]=255; films[abc*6]=255; films[abc*7]=255; abc=63; //71 //галочка 56 //films[512+0]=255; films[512+abc*1]=255; films[512+abc*2]=255; films[512+abc*3]=255; films[512+abc*4]=255; films[512+abc*5]=255; films[512+abc*6]=255; films[512+abc*7]=255; abc=56; // диагональ 73, горизонталь 65 //films[1024+0]=255; films[1024+abc*1]=255; films[1024+abc*2]=255; films[1024+abc*3]=255; films[1024+abc*4]=255; films[1024+abc*5]=255; films[1024+abc*6]=255; films[1024+abc*7]=255; //abc=65; // диагональ 73, горизонталь 65 //films[512+0]=255; //films[512+abc*1]=255; //films[512+abc*2]=255; //films[512+abc*3]=255; //films[512+abc*4]=255; //films[512+abc*5]=255; //films[512+abc*6]=255; //films[512+abc*7]=255; } void loop() { for (f=0; f<24; f++){ for (x=0; x<=63; x++){ MyMassive[x]=films[f*64+x]; } myMultiplyFunction(); } } byte myMultiplyFunction(){ // устанавливаем синхронизацию "защелки" на LOW for(j=0; j<=7; j++) { //этаж for(z=0; z<=7; z++) { shiftOut(dataPin, clockPin, MSBFIRST, MyMassive[z+(j*8)]); // shiftOut(dataPin, clockPin, MSBFIRST, (z+(j*8))); // Serial.println (MyMassive[z+(j*8)]); //"защелкиваем" регистр, тем самым устанавливая значения на выходах } digitalWrite(latchPin, HIGH); // пауза перед следующей итерацией // delay(1); digitalWrite(latchPin, LOW); // передаем последовательно на dataPin digitalWrite(myPins[j], HIGH); delay(5); // wait for a second digitalWrite(myPins[j], LOW); // turn the LED off by making the voltage LOW // delay(1000); } } [CODE]