Martin Deng / Mbed 2 deprecated mbed_shapedriver

Dependencies:   mbed

Committer:
martydd3
Date:
Fri May 01 16:17:52 2015 +0000
Revision:
7:2db895370298
Parent:
6:baece3338bfe
A

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