Martin Deng / Mbed 2 deprecated mbed_shapedriver

Dependencies:   mbed

Committer:
martydd3
Date:
Fri May 01 05:25:19 2015 +0000
Revision:
5:495d64d8934d
Parent:
4:75498bd2e742
Child:
6:baece3338bfe
Moved all drawing to primative functions

Who changed what in which revision?

UserRevisionLine numberNew contents of line
martydd3 4:75498bd2e742 1 #include "constants.h"
martydd3 5:495d64d8934d 2 #include "mbed.h"
martydd3 5:495d64d8934d 3 #include <math.h>
martydd3 5:495d64d8934d 4
martydd3 5:495d64d8934d 5 static char work_buffer[SLICES][WIDTH];
martydd3 5:495d64d8934d 6
martydd3 5:495d64d8934d 7 static void erase(){
martydd3 5:495d64d8934d 8 for(int i = 0; i < SLICES; i++){
martydd3 5:495d64d8934d 9 for(int j = 0; j < WIDTH; j++){
martydd3 5:495d64d8934d 10 work_buffer[i][j] = 0x00;
martydd3 5:495d64d8934d 11 }
martydd3 5:495d64d8934d 12 }
martydd3 5:495d64d8934d 13 }
martydd3 5:495d64d8934d 14
martydd3 5:495d64d8934d 15 void draw_circle(float r, float h){
martydd3 5:495d64d8934d 16 for(int i = 0; i < SLICES; i++){
martydd3 5:495d64d8934d 17 work_buffer[i][(int)rint(r)] |= (0x01 << (int)rint(h));
martydd3 5:495d64d8934d 18 }
martydd3 5:495d64d8934d 19 }
martydd3 5:495d64d8934d 20
martydd3 5:495d64d8934d 21 void draw_wavecircle(float r, float freq, float disp){
martydd3 5:495d64d8934d 22 for(int i = 0; i < SLICES; i++){
martydd3 5:495d64d8934d 23 float h = 3.5*sin(2.0 * M_PI * (i + disp) * freq / SLICES) + 3.5;
martydd3 5:495d64d8934d 24 work_buffer[i][(int)rint(r)] |= (0x01 << (int)rint(h));
martydd3 5:495d64d8934d 25 }
martydd3 5:495d64d8934d 26 }
martydd3 5:495d64d8934d 27
martydd3 5:495d64d8934d 28 #define VERT 1
martydd3 5:495d64d8934d 29 #define HORZ 0
martydd3 5:495d64d8934d 30
martydd3 5:495d64d8934d 31 static void draw_zvert_line(float x, float y, float z1, float z2);
martydd3 5:495d64d8934d 32 static void draw_orig_line(float x1, float x2, float z1, float z2, int ori);
martydd3 5:495d64d8934d 33 static void draw_perp_line(float a1, float a2, float b, float z1, float z2, int ori);
martydd3 5:495d64d8934d 34 static void draw_arb_line(float x1, float x2, float y1, float y2, float z1, float z2);
martydd3 5:495d64d8934d 35
martydd3 5:495d64d8934d 36 static void norm_angle(float &p){
martydd3 5:495d64d8934d 37 p = p < 0 ? p + 2 * M_PI : p;
martydd3 5:495d64d8934d 38 p = p > 2 * M_PI ? p - 2 * M_PI : p;
martydd3 5:495d64d8934d 39 }
martydd3 5:495d64d8934d 40
martydd3 5:495d64d8934d 41 static float deg2rad(float p){
martydd3 5:495d64d8934d 42 return 2 * M_PI * p / SLICES;
martydd3 5:495d64d8934d 43 }
martydd3 5:495d64d8934d 44
martydd3 5:495d64d8934d 45 static float rad2deg(float p){
martydd3 5:495d64d8934d 46 return p * SLICES / (2 * M_PI);
martydd3 5:495d64d8934d 47 }
martydd3 5:495d64d8934d 48
martydd3 5:495d64d8934d 49 static void step_i(float a, float b, int &i){
martydd3 5:495d64d8934d 50 float diff = abs(a - b);
martydd3 5:495d64d8934d 51 if(diff > SLICES / 2)
martydd3 5:495d64d8934d 52 i = a > b ? i + 1: i - 1;
martydd3 5:495d64d8934d 53 else
martydd3 5:495d64d8934d 54 i = a > b ? i - 1: i + 1;
martydd3 5:495d64d8934d 55
martydd3 5:495d64d8934d 56 i = (i == SLICES) ? 0 : i;
martydd3 5:495d64d8934d 57 i = (i == -1) ? SLICES - 1 : i;
martydd3 5:495d64d8934d 58 }
martydd3 5:495d64d8934d 59
martydd3 5:495d64d8934d 60 void draw_line(float x1, float y1, float z1, float x2, float y2, float z2){
martydd3 5:495d64d8934d 61
martydd3 5:495d64d8934d 62 //Perfectly vertical depth lines
martydd3 5:495d64d8934d 63 if(x1 == x2 && y1 == y2){
martydd3 5:495d64d8934d 64 draw_zvert_line(x1, y1, z1, z2);
martydd3 5:495d64d8934d 65 }
martydd3 5:495d64d8934d 66
martydd3 5:495d64d8934d 67 //Perfectly horizontal lines through origin
martydd3 5:495d64d8934d 68 else if(y1 == 0 && y2 == 0){
martydd3 5:495d64d8934d 69 draw_orig_line(x1, x2, z1, z2, HORZ);
martydd3 5:495d64d8934d 70 }
martydd3 5:495d64d8934d 71
martydd3 5:495d64d8934d 72 //Perfectly vertical lines through origin
martydd3 5:495d64d8934d 73 else if(x1 == 0 && x2 == 0){
martydd3 5:495d64d8934d 74 draw_orig_line(y1, y2, z1, z2, VERT);
martydd3 5:495d64d8934d 75 }
martydd3 5:495d64d8934d 76
martydd3 5:495d64d8934d 77 //Perfectly horizontal lines
martydd3 5:495d64d8934d 78 else if(y1 == y2){
martydd3 5:495d64d8934d 79 draw_perp_line(x1, x2, y1, z1, z2, HORZ);
martydd3 5:495d64d8934d 80 }
martydd3 5:495d64d8934d 81
martydd3 5:495d64d8934d 82 //Perfectly vertical lines
martydd3 5:495d64d8934d 83 // r = b / r cos p
martydd3 5:495d64d8934d 84 else if(x1 == x2){
martydd3 5:495d64d8934d 85 draw_perp_line(y1, y2, x1, z1, z2, VERT);
martydd3 5:495d64d8934d 86 }
martydd3 5:495d64d8934d 87
martydd3 5:495d64d8934d 88 //Arbitrary lines
martydd3 5:495d64d8934d 89 else {
martydd3 5:495d64d8934d 90 draw_arb_line(x1, x2, y1, y2, z1, z2);
martydd3 5:495d64d8934d 91 }
martydd3 5:495d64d8934d 92 }
martydd3 4:75498bd2e742 93
martydd3 5:495d64d8934d 94 static void draw_arb_line(float x1, float x2, float y1, float y2, float z1, float z2){
martydd3 5:495d64d8934d 95 // y = mx + b,
martydd3 5:495d64d8934d 96 // r = b / (sin p - m cos p)
martydd3 5:495d64d8934d 97 //
martydd3 5:495d64d8934d 98 // if m is close to infinity, better to use
martydd3 5:495d64d8934d 99 // x = ny + c
martydd3 5:495d64d8934d 100 // r = c / (cos p - n sin p)
martydd3 5:495d64d8934d 101
martydd3 5:495d64d8934d 102 float m_1 = 1.0*(y2 - y1)/(x2 - x1);
martydd3 5:495d64d8934d 103 float m_2 = 1.0*(x2 - x1)/(y2 - y1);
martydd3 5:495d64d8934d 104 float d = sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1));
martydd3 5:495d64d8934d 105 float m_h = (z2 - z1)/d;
martydd3 5:495d64d8934d 106 float m, p1, p2, b, h;
martydd3 5:495d64d8934d 107 int ori;
martydd3 5:495d64d8934d 108
martydd3 5:495d64d8934d 109 //x = m_2 y + b is steeper than y = m_1 x + b
martydd3 5:495d64d8934d 110 if(abs(m_2) > abs(m_1)){
martydd3 5:495d64d8934d 111 m = m_1;
martydd3 5:495d64d8934d 112 b = y1 - m * x1;
martydd3 5:495d64d8934d 113 ori = HORZ;
martydd3 5:495d64d8934d 114 } else {
martydd3 5:495d64d8934d 115 m = m_2;
martydd3 5:495d64d8934d 116 b = x1 - m * y1;
martydd3 5:495d64d8934d 117 ori = VERT;
martydd3 5:495d64d8934d 118 }
martydd3 5:495d64d8934d 119
martydd3 5:495d64d8934d 120 p1 = atan2(y1, x1);
martydd3 5:495d64d8934d 121 p2 = atan2(y2, x2);
martydd3 5:495d64d8934d 122
martydd3 5:495d64d8934d 123 norm_angle(p1);
martydd3 5:495d64d8934d 124 norm_angle(p2);
martydd3 5:495d64d8934d 125
martydd3 5:495d64d8934d 126 h = z1;
martydd3 5:495d64d8934d 127
martydd3 5:495d64d8934d 128 int i1 = rad2deg(p1);
martydd3 5:495d64d8934d 129 int i2 = rad2deg(p2);
martydd3 5:495d64d8934d 130
martydd3 5:495d64d8934d 131 while(true){
martydd3 5:495d64d8934d 132 float p = deg2rad(i1);
martydd3 5:495d64d8934d 133 float r = (ori == HORZ) ? b / (sin(p) - m * cos(p)) : b / (cos(p) - m * sin(p));
martydd3 5:495d64d8934d 134
martydd3 5:495d64d8934d 135 float dx = r * cos(p);
martydd3 5:495d64d8934d 136 float dy = r * sin(p);
martydd3 5:495d64d8934d 137
martydd3 5:495d64d8934d 138 float dd = sqrt((x1 - dx)*(x1 - dx) + (y1 - dy)*(y1 - dy));
martydd3 5:495d64d8934d 139 h = z1 + m_h * dd;
martydd3 5:495d64d8934d 140
martydd3 5:495d64d8934d 141 if((int)rint(r) < WIDTH)
martydd3 5:495d64d8934d 142 work_buffer[i1][(int)rint(r)] |= (0x01 << (int)rint(h));
martydd3 5:495d64d8934d 143
martydd3 5:495d64d8934d 144 if(i1 == i2)
martydd3 5:495d64d8934d 145 break;
martydd3 5:495d64d8934d 146
martydd3 5:495d64d8934d 147 step_i(i1, i2, i1);
martydd3 5:495d64d8934d 148 }
martydd3 5:495d64d8934d 149 }
martydd3 5:495d64d8934d 150
martydd3 5:495d64d8934d 151 static void draw_perp_line(float a1, float a2, float b, float z1, float z2, int ori){
martydd3 5:495d64d8934d 152 float p1 = (ori == HORZ) ? atan2(b, a1) : atan2(a1, b);
martydd3 5:495d64d8934d 153 float p2 = (ori == HORZ) ? atan2(b, a2) : atan2(a2, b);
martydd3 5:495d64d8934d 154
martydd3 5:495d64d8934d 155 norm_angle(p1);
martydd3 5:495d64d8934d 156 norm_angle(p2);
martydd3 5:495d64d8934d 157
martydd3 5:495d64d8934d 158 int i1 = rad2deg(p1);
martydd3 5:495d64d8934d 159 int i2 = rad2deg(p2);
martydd3 5:495d64d8934d 160
martydd3 5:495d64d8934d 161 float m = (z2 - z1)/(a2 - a1);
martydd3 5:495d64d8934d 162
martydd3 5:495d64d8934d 163 while(true){
martydd3 5:495d64d8934d 164 float p = deg2rad(i1);
martydd3 5:495d64d8934d 165 float r = (ori == HORZ) ? b / sin(p) : b / cos(p);
martydd3 5:495d64d8934d 166 float d = (ori == HORZ) ? b / tan(p) : b * tan(p);
martydd3 5:495d64d8934d 167 float h = z1 + m * (d - a1);
martydd3 5:495d64d8934d 168
martydd3 5:495d64d8934d 169 if((int)rint(r) < WIDTH)
martydd3 5:495d64d8934d 170 work_buffer[i1][(int)rint(r)] |= (0x01 << (int)rint(h));
martydd3 5:495d64d8934d 171
martydd3 5:495d64d8934d 172 if(i1 == i2)
martydd3 5:495d64d8934d 173 break;
martydd3 5:495d64d8934d 174
martydd3 5:495d64d8934d 175 step_i(i1, i2, i1);
martydd3 5:495d64d8934d 176 }
martydd3 5:495d64d8934d 177 }
martydd3 5:495d64d8934d 178
martydd3 5:495d64d8934d 179 static void draw_orig_line(float r1, float r2, float z1, float z2, int ori){
martydd3 5:495d64d8934d 180 int p1, p2;
martydd3 5:495d64d8934d 181 float m;
martydd3 5:495d64d8934d 182
martydd3 5:495d64d8934d 183 if(ori == HORZ){
martydd3 5:495d64d8934d 184 p1 = 0;
martydd3 5:495d64d8934d 185 p2 = SLICES / 2 - 1;
martydd3 5:495d64d8934d 186 m = (1.0*z2 - 1.0*z1)/(1.0*r2 - 1.0*r1);
martydd3 5:495d64d8934d 187 } else {
martydd3 5:495d64d8934d 188 p1 = SLICES / 4 - 1;
martydd3 5:495d64d8934d 189 p2 = 3 * SLICES / 4 - 1;
martydd3 5:495d64d8934d 190 m = (1.0*z2 - 1.0*z1)/(1.0*r2 - 1.0*r1);
martydd3 5:495d64d8934d 191 }
martydd3 5:495d64d8934d 192
martydd3 5:495d64d8934d 193 int i = r1;
martydd3 5:495d64d8934d 194 while(true){
martydd3 5:495d64d8934d 195 float h = z1 + m * (i - r1);
martydd3 5:495d64d8934d 196
martydd3 5:495d64d8934d 197 if(i >= 0){
martydd3 5:495d64d8934d 198 work_buffer[p1][i] |= (0x01 << (int)rint(h));
martydd3 5:495d64d8934d 199 } else if(i <= 0){
martydd3 5:495d64d8934d 200 work_buffer[p2][-i] |= (0x01 << (int)rint(h));
martydd3 5:495d64d8934d 201 }
martydd3 5:495d64d8934d 202
martydd3 5:495d64d8934d 203 if(i == r2)
martydd3 5:495d64d8934d 204 break;
martydd3 5:495d64d8934d 205
martydd3 5:495d64d8934d 206 printf("i: %d, h: %d\n", i, (int)rint(h));
martydd3 5:495d64d8934d 207
martydd3 5:495d64d8934d 208 i = r1 > r2 ? i - 1 : i + 1;
martydd3 5:495d64d8934d 209 }
martydd3 5:495d64d8934d 210 }
martydd3 5:495d64d8934d 211
martydd3 5:495d64d8934d 212 static void draw_zvert_line(float x, float y, float z1, float z2){
martydd3 5:495d64d8934d 213 float r = sqrt(1.0*x*x + 1.0*y*y);
martydd3 5:495d64d8934d 214 float p = atan2(y, x);
martydd3 5:495d64d8934d 215
martydd3 5:495d64d8934d 216 //set p to 0 - 2p range, and convert to slice index
martydd3 5:495d64d8934d 217 norm_angle(p);
martydd3 5:495d64d8934d 218 p = rad2deg(p);
martydd3 5:495d64d8934d 219
martydd3 5:495d64d8934d 220 int i = z1;
martydd3 5:495d64d8934d 221 while(true){
martydd3 5:495d64d8934d 222 work_buffer[(int)rint(p)][(int)rint(r)] |= (0x01 << i);
martydd3 5:495d64d8934d 223
martydd3 5:495d64d8934d 224 if(i == z2)
martydd3 5:495d64d8934d 225 break;
martydd3 5:495d64d8934d 226
martydd3 5:495d64d8934d 227 step_i(z1, z2, i);
martydd3 5:495d64d8934d 228 }
martydd3 5:495d64d8934d 229 }
martydd3 5:495d64d8934d 230
martydd3 5:495d64d8934d 231 /*
martydd3 5:495d64d8934d 232 Moves shapes in work_buffer over to display_buffer in a format that accounts for
martydd3 5:495d64d8934d 233 displaced blades on display
martydd3 5:495d64d8934d 234 */
martydd3 5:495d64d8934d 235 static void init_displacements();
martydd3 5:495d64d8934d 236 static int displacements[HEIGHT];
martydd3 5:495d64d8934d 237
martydd3 5:495d64d8934d 238 void move_buffer(char (*buffer)[SLICES][WIDTH]){
martydd3 5:495d64d8934d 239 static bool initialized = false;
martydd3 5:495d64d8934d 240
martydd3 5:495d64d8934d 241 if(!initialized){
martydd3 5:495d64d8934d 242 init_displacements();
martydd3 5:495d64d8934d 243 }
martydd3 5:495d64d8934d 244
martydd3 5:495d64d8934d 245 for(int i = 0; i < SLICES; i++){
martydd3 5:495d64d8934d 246 for(int j = 0; j < WIDTH; j++){
martydd3 5:495d64d8934d 247 char bit = 0x00;
martydd3 5:495d64d8934d 248
martydd3 5:495d64d8934d 249 for(int h = 0; h < HEIGHT; h++){
martydd3 5:495d64d8934d 250 bit |= (work_buffer[(i + displacements[h]) % SLICES][j] & (0x01 << h));
martydd3 5:495d64d8934d 251 }
martydd3 5:495d64d8934d 252
martydd3 5:495d64d8934d 253 (*buffer)[i][j] = bit;
martydd3 5:495d64d8934d 254 }
martydd3 5:495d64d8934d 255 }
martydd3 5:495d64d8934d 256
martydd3 5:495d64d8934d 257 erase();
martydd3 5:495d64d8934d 258 }
martydd3 5:495d64d8934d 259
martydd3 5:495d64d8934d 260 /*
martydd3 5:495d64d8934d 261 Initializes buffer used to adjust for vertical misalignment of display blades
martydd3 5:495d64d8934d 262 */
martydd3 5:495d64d8934d 263 static void init_displacements(){
martydd3 5:495d64d8934d 264
martydd3 5:495d64d8934d 265 for(int i = 0; i < HEIGHT; i++){
martydd3 5:495d64d8934d 266 switch(i){
martydd3 5:495d64d8934d 267 case 0: displacements[i] = 0; break;
martydd3 5:495d64d8934d 268 case 1: displacements[i] = 4 * SLICES / 8; break;
martydd3 5:495d64d8934d 269 case 2: displacements[i] = 7 * SLICES / 8 - 5; break;
martydd3 5:495d64d8934d 270 case 3: displacements[i] = 3 * SLICES / 8 - 8; break;
martydd3 5:495d64d8934d 271 case 4: displacements[i] = 6 * SLICES / 8 - 6; break;
martydd3 5:495d64d8934d 272 case 5: displacements[i] = 2 * SLICES / 8 - 7; break;
martydd3 5:495d64d8934d 273 case 6: displacements[i] = 5 * SLICES / 8 - 7; break;
martydd3 5:495d64d8934d 274 case 7: displacements[i] = 1 * SLICES / 8 - 8; break;
martydd3 5:495d64d8934d 275 }
martydd3 5:495d64d8934d 276 }
martydd3 5:495d64d8934d 277 }
martydd3 5:495d64d8934d 278
martydd3 5:495d64d8934d 279
martydd3 5:495d64d8934d 280