FC2ブログ
2017-10-16 00:10 | カテゴリ:PIC応用回路

まずは、LEDの基本的な仕組みを理解し、ドットのオン・オフが座標指定で可能になりました。

次に考えなければならないことは、

1)任意のドットパターンを配列に定義しておいて、それを任意の位置に書き出す処理

2)任意のドットパターンを配列に定義しておいて、それを任意の位置を中心として、自由に回転する処理

といった所でしょうか。
さて、どうしたものでしょうか?


(MTX05)
MTX055.jpg





続きは、、、


1)任意のパターンの表示

これは、それほど複雑ではない気がします。
前回、任意の座標(x,y)のドットを点灯させる関数を製作しましたので、それを利用します。

まず、表示したいパターンをドットで描き、そのドットの(x,y)座標を配列に定義して、それを順次読みだして、
ドット表示関数に送れば、簡単です。
また、パターンを記述した配列の最初に、いくつのドットが定義されているかの個数を記述して、繰り返しループの抜け出すポイントとします。

具体的な例を挙げてみます。

まず、パターンを定義。
例として、アルファベットの「F」を12ドットで定義して、その座標を記録します。


//---------------------------------------
// 表示パターン定義(F文字の例)
//---------------------------------------
const int Ptn01[13][2] = {
{ 12, 0}, // 配列の個数、0
{ 0, 5}, // No#1のドットのデータ座標(x, y))
{ 1, 0}, // 2
{ 1, 1}, // 3
{ 1, 2}, // 4
{ 1, 3}, // 5
{ 1, 4}, // 6
{ 1, 5}, // 7
{ 2, 2}, // 8
{ 2, 5}, // 9
{ 3, 2}, // 10
{ 3, 5}, // 11
{ 4, 5} // 12
};

関数プログラムからは、それを順次読みだして、既に定義してある、(x、y)座標ドット表示関数に座標を渡して、点灯させます。
終了の判断は、配列の最初の数字、この場合は、12ですが、12回繰り返します。
また、表示させる座標の値をxとyで指定しておきます。



//--------------------------------
// 配列に定義されたデータを表示
//--------------------------------

void Put_Pat(int Dot_Data[][2], int x, int y) {
int i;
for (i = 1; i <= Dot_Data[0][0]; i++) {
Dot_On(Dot_Data[i][0] + x, Dot_Data[i][1] + y);
}
Data_Buff_Out();
}


そして、最後に、書き込んだドットデータのバッファ(Data_Buff)を一括してLEDモジュールに転送して、実際にLEDを点灯させます。
表示させる座標のxとyを変化させると表示位置もそれにつれて移動します。


(MTX06)
MTX06.jpg

これは静止画像ですが、Fという文字を任意の位置に書き込むことが出来ました。



続いて

2)任意のドットパターンを任意の位置を中心として、自由に回転する処理

ドットで任意の位置への表示は単純ですが、ドットパターンを回転させるのは、ちょっと大変そうです。
回転させるので、これまでの(x,y)座標系で処理するのは難しそうです。
そこで、昔、中学か高校の数学で習った、極座標を使うことにしました。
あの、Sin、Cos、Tanが出てきます。(笑)
極座標をうまく使えば、回転はとても簡単そうです。

まずは、x、yの直交座標と極座標の関係を整理します。
A点の座標が(x,y)の時、極座標で表すと

(MTX07)
MTX07.jpg


x=rcosθ
y=rsinθ


となります。 θは、0から2πの値をとります。
回転は、θを加減させるだけで、任意の点(この場合は原点(0,0)を中心に回転させることができます。

つまり、整理すると

1)直交座標系の任意の点(x、y)を極座標に変換。

2)回転させる(θの加減)

3)その極座標を再度直交座標の点(x1、y1)に再変換する。

4)その点を表示させる。

これらのプロセスで、任意の点を、任意の座標を中心に、任意の角度回転させることができます。
あとは、プログラムを組むだけです。

まずは、直交座標から極座標への変換です。

//-------------------------------------------------------
// 直交座標から極座標へ変換
// x0, y0からr0, θ0へ
// x - 16がゼロの場合はPI/2とする
//
//-------------------------------------------------------
// x = 0, y > 0 θ=PI/2
// x = 0, y < 0 θ=PI 3/2
// y = 0, x < 0 θ=PI
// y = 0, x > 0 θ=0
//--------------------------------------------------------

void To_RT_Conv(float Convert[][6], int x0, int y0) {
float xx, yy, r0, theta0;
int n, m;
m = (int) (Convert[0][0]);
for (n = 1; n <= m; n++) {
xx = Convert[n][0] - x0;
yy = Convert[n][1] - y0;

Convert[n][2] = sqrt((xx * xx) + (yy * yy)); // r0 をセット

theta0 = atan(yy / xx);

//-----------------------------------------
// Tanが無限大になることを回避
//-----------------------------------------
if ((xx == 0) & (yy > 0)) theta0 = PI / 2;
if ((xx == 0) & (yy < 0)) theta0 = PI / 2 * 3;
if ((yy == 0) & (xx < 0)) theta0 = PI;
if ((yy == 0) & (xx > 0)) theta0 = 0;

//-----------------------------------------
// 直交座標の正負により角度を補正
//-----------------------------------------

if ((yy > 0) & (xx < 0)) theta0 = theta0 - PI;
if ((yy < 0) & (xx < 0)) theta0 = theta0 + PI;
if ((yy > 0) & (xx > 0)) theta0 = theta0 - 0;
if ((yy < 0) & (xx > 0)) theta0 = theta0;

Convert[n][3] = theta0;

}
}


次に、極座標から直交座標への変換です。

//---------------------------------------------
// 極座標から直交座標へRot_theta分回転させて変換
// r1, θ1からx1, y1へ
//
//---------------------------------------------

void Fm_RT_Conv(float Rconvert[][6], float Rot_theta, int x0, int y0) { //極座標から直交座標へ変換
float r1, theta1;
int n, m;
m = (int) (Rconvert[0][0]);
for (n = 1; n <= m; n++) {
r1 = Rconvert[n][2]; // r1 <-- r0
theta1 = Rconvert[n][3] + Rot_theta; // Rot_theta分回転後に座標変換


if (theta1 >= PI2) theta1 = theta1 - PI2;
if (theta1 <= 0) theta1 = theta1 + PI2;
Rconvert[n][4] = r1 * cos(theta1) + x0; // x1
Rconvert[n][5] = r1 * sin(theta1) + y0; // y1
}
}




実施に一列のドットを回転させてみました。
ドットの数が限定されていますので、滑らかな直線の回転とは程遠いですが、夜目遠目で、直線が回転している様に見えます(笑)


(MTX08)
MTX08.jpg

(MTX09)
MTX09.jpg

(MTX10)
MTX10.jpg

(MTX11)
MTX11.jpg

(MTX12)
MTX12.jpg



次に、四角形を描画して、回転させてみました。
こちらは直線よりさらに「苦しい」回転となりました(笑)


(MTX13)
MTX13.jpg

(MTX14)
MTX14.jpg

(MTX15)
MTX15.jpg

(MTX16)
MTX16.jpg

(MTX17)
MTX17.jpg

(MTX18)
MTX18.jpg




なお、直交座標と極座標との関係は、こちらの「高校数学の美しい物語」さんのHPをご覧いただくとわかりやすく解説されています。

(MTX19)

MTX19.jpg
関連記事
【ジャンル】:趣味・実用 【テーマ】:電子工作
コメント(4)

管理者のみに表示する