[英]Rotating a 2d array -> reversing a loop
我使用以下代碼旋轉位掩碼(壓縮的2d數組)。 老實說,我對所使用的算法沒有把握,我復制並修改了pygame庫中的旋轉代碼(用於旋轉曲面)。 由於bitmask
的實現,我可以通過反轉內部循環來加快旋轉速度。 我的意思是,不是要做foreach y { foreach x { ... } }
而是做foreach x { foreach y { ... } }
。 我在反轉循環時遇到了麻煩,因為三角函數必須以目前我目前看不到的方式進行調整。
這是代碼:
typedef struct bitmask {
int w,h;
BITMASK_W bits[1];
} bitmask_t;
bitmask_t* bitmask_rotate(const bitmask_t *mask, float angle) {
bitmask_t *newmask = NULL;
double radangle, sangle, cangle;
int isin, icos;
double cx, cy, sx, sy;
int x, y, ax, ay, xd, yd, dx, dy;
int nxmax, nymax, xmaxval, ymaxval;
radangle = angle * DEG_TO_RAD;
sangle = sin(radangle);
cangle = cos(radangle);
isin = (int)(sangle * 65536);
icos = (int)(cangle * 65536);
x = mask->w;
y = mask->h;
cx = cangle*x;
cy = cangle*y;
sx = sangle*x;
sy = sangle*y;
nxmax = (int) (MAX (MAX (MAX (fabs (cx + sy), fabs (cx - sy)), fabs (-cx + sy)), fabs (-cx - sy)));
nymax = (int) (MAX (MAX (MAX (fabs (sx + cy), fabs (sx - cy)), fabs (-sx + cy)), fabs (-sx - cy)));
newmask = bitmask_create(nxmax, nymax, 0);
if (!newmask) return NULL;
cy = newmask->h / 2;
xd = ((mask->w - newmask->w) << 15);
yd = ((mask->h - newmask->h) << 15);
ax = ((newmask->w) << 15) - (int)(cangle * ((newmask->w - 1) << 15));
ay = ((newmask->h) << 15) - (int)(sangle * ((newmask->w - 1) << 15));
xmaxval = ((mask->w) << 16) - 1;
ymaxval = ((mask->h) << 16) - 1;
for (y = 0; y < newmask->h; y++) {
dx = (ax + (isin * (cy - y))) + xd;
dy = (ay - (icos * (cy - y))) + yd;
for (x = 0; x < newmask->w; x++) {
if (!(dx < 0 || dy < 0 || dx > xmaxval || dy > ymaxval)) {
if (bitmask_getbit(mask, dx >> 16, dy >> 16)) {
bitmask_setbit(newmask, x, y);
}
}
dx += icos;
dy += isin;
}
}
return newmask;
}
在人們問“您嘗試了什么?”之前 ,我在Wikipedia上循環旋轉矩陣,然后可以看到發生了什么,以及它們如何在此算法中實現(預先計算起始dx
和dy
,然后使用icos
和isin
遞增),但是位移位和參數我不知道無法理解(例如ax
)使我難以跟隨。
for (x = 0; x < newmask->w; x++) {
dx = (ax + (isin * cy + icos * x)) + xd;
dy = (ay - (icos * cy - isin * x)) + yd;
for (y = 0; y < newmask->h; y++) {
if (!(dx < 0 || dy < 0 || dx > xmaxval || dy > ymaxval)) {
if (bitmask_getbit(mask, dx >> 16, dy >> 16)) {
bitmask_setbit(newmask, x, y);
}
}
dx -= isin;
dy += icos;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.