매트릭스를 사용하는지 여부는 중요하지 않습니다. 여기에 간단한 C++ 내 의견에 언급 무엇을 모두 사용하여 매트릭스없이 예 :
//---------------------------------------------------------------------------
const int xs=32;
const int ys=32;
char pic[xs][ys];
//---------------------------------------------------------------------------
void cls();
void rot45cw();
void rot90cw();
//---------------------------------------------------------------------------
void cls()
{
int x,y;
// clear screen
for (y=0;y<ys;y++)
for (x=0;x<xs;x++)
pic[x][y]=' ';
// add diagonal line for testing
for (x=xs/2;(x<xs)&&(x<ys);x++) pic[x][x]='\\';
}
//---------------------------------------------------------------------------
void rot45cw()
{
int x,y,ix,iy,x0,y0;
float fx,fy,a,c,s;
char tmp[xs][ys],q;
a=-45.0*M_PI/180.0; // rotation angle [rad]
x0=xs/2; // center of rotation
y0=ys/2;
c=cos(a); s=sin(a);
// copy pic to tmp
for (y=0;y<ys;y++)
for (x=0;x<xs;x++)
tmp[x][y]=pic[x][y];
// rotate
for (y=0;y<ys;y++)
for (x=0;x<xs;x++)
{
// offset so (0,0) is center of rotation
fx=x-x0;
fy=y-y0;
// rotate (fx,fy) by ang
ix=float((fx*c)-(fy*s));
iy=float((fx*s)+(fy*c));
// offset back
ix+=x0;
iy+=y0;
// transform tmp to pic
if ((ix>=0)&&(ix<xs)&&(iy>=0)&&(iy<ys)) q=tmp[ix][iy]; else q=' ';
if (q=='/') q='\\';
else if (q=='\\') q='/';
else if (q=='-') q='|';
else if (q=='|') q='-';
pic[x][y]=q;
}
}
//---------------------------------------------------------------------------
void rot90cw()
{
int x,y,ix,iy,x0,y0;
char tmp[xs][ys],q;
// center of rotation
x0=xs/2;
y0=ys/2;
// copy pic to tmp
for (y=0;y<ys;y++)
for (x=0;x<xs;x++)
tmp[x][y]=pic[x][y];
// rotate
for (y=0;y<ys;y++)
for (x=0;x<xs;x++)
{
// rotate
iy=x0-(x-x0);
ix=y0+(y-y0);
// transform tmp to pic
if ((ix>=0)&&(ix<xs)&&(iy>=0)&&(iy<ys)) q=tmp[ix][iy]; else q=' ';
if (q=='-') q='\\';
else if (q=='\\') q='|';
else if (q=='|') q='/';
else if (q=='/') q='-';
pic[x][y]=q;
}
}
//---------------------------------------------------------------------------
및 사용 :
여기
// clear and add diagonal line for testing once:
cls();
// and this do in some timer or whatever:
//rot45cw();
rot90cw();
90DEG 미리보기 :
다음
45deg 미리보기 :
위에서 볼 수 있듯이 1 : 1 매핑이 아니기 때문에 45도 회전이 문제가되므로 일부 셀이 둘 이상의 셀에 매핑됩니다. 고정 해상도의 경우 수동으로 1 : 1 매핑을 할 수 있지만 동적 해상도의 경우 알고리즘 적으로 쉽게 구현할 수 있을지는 의문입니다.
예 개별 픽셀을 매핑 할 때 일부는 다시 복사되기 때문에 45도 회전이 가능하지만 문제는 지속되는 단지 (3x3) 맵만 사용하고 일부는 다시 복사되고 고려하면 문자가 보입니다. .
나는
문자 회전
이 LUT를
[EDIT1]
45 학위를 가속화 할 수 있습니다 ... 이미지의 벡터 표현을 가지고하지 않는 한 나는 오히려 90DEG 회전을 사용하는 것이 모두 함께 넣어 경우 rotation
나는 그것을 더 많이 가르쳐주고 45도 회전을위한 해결책을 찾는다. 다른 회전 커널을 사용해야합니다. 원주의 1/8로 원을 그리지 않고 정사각형으로 회전하지 않습니다. 여기에 작은 예제를 더 잘 이해하기 위해 :
이것은 1 : 1 매핑이므로 문제가 없습니다.C++의 코드는 다음과 같습니다
//---------------------------------------------------------------------------
void rot45cw()
{
int x0,y0,ax,ay,ad,bx,by,bd,a,b,i,r,rs;
char tmp[xs][ys],q;
// rotation kernel 4 directions
const int dx[4]={ 0,-1, 0,+1};
const int dy[4]={-1, 0,+1, 0};
// center of rotation
x0=xs/2;
y0=ys/2;
// copy pic to tmp
for (ay=0;ay<ys;ay++)
for (ax=0;ax<xs;ax++)
tmp[ax][ay]=pic[ax][ay];
// rotate all "screws" to fill entire map
rs=xs; if (rs<ys) rs=ys;
for (r=1;r<rs;r++)
{
ax=x0+r; ay=y0+r; ad=0; a=0; // start position a
bx=x0 ; by=y0+r; bd=3; b=r; // start position b
for (i=8*r;i>0;i--) // process one screw
{
// fetch and convert processed character
if ((ax>=0)&&(ax<xs)&&(ay>=0)&&(ay<ys))
if ((bx>=0)&&(bx<xs)&&(by>=0)&&(by<ys))
{
q=tmp[ax][ay];
if (q=='-') q='\\';
else if (q=='\\') q='|';
else if (q=='|') q='/';
else if (q=='/') q='-';
pic[bx][by]=q;
}
// update position
ax+=dx[ad]; bx+=dx[bd];
ay+=dy[ad]; by+=dy[bd];
// update direction
a++; if (a>=r+r) { a=0; ad=(ad+1)&3; }
b++; if (b>=r+r) { b=0; bd=(bd+1)&3; }
}
}
// fetch and convert center of rotation
if ((x0>=0)&&(x0<xs)&&(y0>=0)&&(y0<ys))
{
q=pic[x0][y0];
if (q=='-') q='\\';
else if (q=='\\') q='|';
else if (q=='|') q='/';
else if (q=='/') q='-';
pic[x0][y0]=q;
}
}
//---------------------------------------------------------------------------
void rot45ccw()
{
int x0,y0,ax,ay,ad,bx,by,bd,a,b,i,r,rs;
char tmp[xs][ys],q;
// rotation kernel 4 directions
const int dx[4]={ 0,-1, 0,+1};
const int dy[4]={-1, 0,+1, 0};
// center of rotation
x0=xs/2;
y0=ys/2;
// copy pic to tmp
for (ay=0;ay<ys;ay++)
for (ax=0;ax<xs;ax++)
tmp[ax][ay]=pic[ax][ay];
// rotate all "screws" to fill entire map
rs=xs; if (rs<ys) rs=ys;
for (r=1;r<rs;r++)
{
ax=x0+r; ay=y0+r; ad=0; a=0; // start position a
bx=x0 ; by=y0+r; bd=3; b=r; // start position b
for (i=8*r;i>0;i--) // process one screw
{
// fetch and convert processed character
if ((ax>=0)&&(ax<xs)&&(ay>=0)&&(ay<ys))
if ((bx>=0)&&(bx<xs)&&(by>=0)&&(by<ys))
{
q=tmp[bx][by];
if (q=='-') q='/';
else if (q=='/') q='|';
else if (q=='|') q='\\';
else if (q=='\\') q='-';
pic[ax][ay]=q;
}
// update position
ax+=dx[ad]; bx+=dx[bd];
ay+=dy[ad]; by+=dy[bd];
// update direction
a++; if (a>=r+r) { a=0; ad=(ad+1)&3; }
b++; if (b>=r+r) { b=0; bd=(bd+1)&3; }
}
}
// fetch and convert center of rotation
if ((x0>=0)&&(x0<xs)&&(y0>=0)&&(y0<ys))
{
q=pic[x0][y0];
if (q=='-') q='/';
else if (q=='/') q='|';
else if (q=='|') q='\\';
else if (q=='\\') q='-';
pic[x0][y0]=q;
}
}
//---------------------------------------------------------------------------
dx,dy
테이블 sin
및 cos
단순히 비유입니다. 마지막으로 여기에 미리보기는 다음과 같습니다
하지만 굵은의 당신이 그 중심 주위에 사각형 회전 경우 예상대로되지 않을 것! 여기 CCW 예 :
는 항상 기원에 대한 ASCII 아트를 회전하고 있는가? –
@TimBiegeleisen 당신은 회전의 중심점을 의미합니까? – Max
예, 이것이 제가 묻는 것입니다. –