|
The Hilbert Curve, named from the german mathmatician Hilbert, is a well known fractal curve.
希爾伯特曲線,以德國數(shù)學(xué)家希爾伯特命名,是一個(gè)很有名的分形曲線。
下面將以“山寨機(jī)”版本的MediaTek的MT6225版本號(hào)為W0812F1為例來演示曲線的生成過程。算法來源于ACM Graphics Gems,右圖為模擬生成的圖像,請(qǐng)注意盡量減少迭代的次數(shù),在嵌入式當(dāng)中玩迭代,純粹是搞怪,慎用。
/* Hibert Curve */
#define STEP_SIZE 4 /* # of pixels in each step */
long orgin[2]; long coord[2]; /* X,Y for graphics calls */
static void step(long angle) { while (angle > 270) angle -= 360; /* Fold ANGLE to be 0, 90, 180, 270 */ while (angle < 0) angle += 360; if (angle == 0) {orgin[0] = coord[0]; coord[0] += STEP_SIZE;} /* +X */ else if (angle == 90) {orgin[1] = coord[1]; coord[1] += STEP_SIZE;} /* +Y */ else if (angle == 180) {orgin[0] = coord[0]; coord[0] -= STEP_SIZE;} /* -X */ else if (angle == 270) {orgin[1] = coord[1]; coord[1] -= STEP_SIZE;} /* -Y */ gdi_draw_line(orgin[0], orgin[1], coord[0], coord[1], GDI_COLOR_TRANSPARENT); gdi_layer_blt_previous(0, 0, UI_DEVICE_WIDTH - 1, UI_DEVICE_HEIGHT - 1); }
/* Recursive Hilbert-curve generation algorithm */ /* ORIENT is either +1 or -1...it swaps left turns and right turns */ /* ANGLE is some multiple of 90 degrees...positive or negative */ /* LEVEL is the recursion level */ /* 2^LEVEL by 2^LEVEL points will be visited in total */
void hilbert (long orient,long *angle, long level) { if (level-- <= 0) return; *angle += orient * 90; hilbert(-orient,angle,level); step(*angle); *angle -= orient * 90; hilbert(orient,angle,level); step(*angle); hilbert(orient,angle,level); *angle -= orient * 90; step(*angle); hilbert(-orient,angle,level); *angle += orient * 90; }
/* Recursive Peano-curve generation */ /* Same parameters as Hilbert above */ /* 3^LEVEL by 3^LEVEL points visited */
void peano (long orient, long *angle, long level) { if (level-- <= 0) return; peano(orient,angle,level); step(*angle); peano(-orient,angle,level); step(*angle); peano(orient,angle,level); *angle -= orient * 90; step(*angle); *angle -= orient * 90; peano(-orient,angle,level); step(*angle); peano(orient,angle,level); step(*angle); peano(-orient,angle,level); *angle += orient * 90; step(*angle); *angle += orient * 90; peano(orient,angle,level); step(*angle); peano(-orient,angle,level); step(*angle); peano(orient,angle,level); }
void HilbertCurve(void) { long initial_angle; orgin[0] = 0; orgin[1] = 0; coord[0] = 0; coord[1] = 0;
gdi_layer_push_and_set_active(effect_layer_1); gdi_layer_set_source_key(TRUE, GDI_COLOR_TRANSPARENT); gdi_layer_clear(GDI_COLOR_BLACK); gdi_layer_pop_and_restore_active();
gdi_layer_set_blt_layer(effect_layer_1, 0, 0, 0); gdi_layer_blt_previous(0, 0, UI_DEVICE_WIDTH - 1, UI_DEVICE_HEIGHT - 1);
gdi_layer_push_and_set_active(effect_layer_1); gdi_layer_set_blt_layer(effect_layer_2, effect_layer_1, 0, 0); /* Visit 128x128 points along Hilbert curve using STEP_SIZE steps, */ /* so pattern will fill 512x512 area on screen since STEP_SIZE = 4 */ initial_angle = 0; hilbert(1,&initial_angle,7);
/* Visit 81x81 points along Peano curve using STEP_SIZE steps, */ /* so pattern will fill 324x324 area on screen since STEP_SIZE = 4 */ initial_angle = 0; peano(-1,&initial_angle,4);
gdi_layer_pop_and_restore_active(); }
|