BiorhythmCanvas.drawCurves()BiorhythmCanvasクラスのpaint()から呼ばれるメソッドdrawCurves()です。
このメソッドでは身体・感情・知性のバイオリズム曲線を描きます。基本的にサイン・カーブを描くだけです。
サインカーブを描くには、カーブ上のいくつかの値を計算してそれらを直線で結べば良いです。ここではサインカーブの1周期から24点抜き出して計算することにしたので
sin(i / 24 * 2PI) = sin(i / 12 * PI)
のiを0から23まで変化させながら値を計算し、線で結んでいけば良いです。
それではdrawCurves()の骨格部分、サインカーブを描く部分を見ていきましょう。メソッドの真ん中にあるforループの部分になります。
簡単のために身体のバイオリズム曲線を描いている部分だけを抜き出すとforループの部分は
for (int i = -2; i < 27; i++) {
int x = i * gridWidth;
int yPhysical = (int)(amplitude * Math.sin((double)(i - 18) * Math.PI / 12.0));
g.setColor(physicalColor);
g.drawLine(oldX + PHYSICAL_ORIGIN_X, oldYPhysical + ORIGIN_Y,
x + PHYSICAL_ORIGIN_X, yPhysical + ORIGIN_Y);
oldX = x;
oldYPhysical = yPhysical;
}
となります。
iが0から23ではなくて、-2から26に(実際はループに入る前に-3の値を計算しているので、-3から26に)なっているのは、身体・感情・知性の三つのカーブの原点をずらして書いても見栄えを悪くしないためです。(こうしないとどうなるかはforループの条件を変えて試してみて下さい。)
ある点を抜き出して値を計算しているのは
int yPhysical = (int)(amplitude * Math.sin((double)(i - 18) * Math.PI / 12.0));
の一文です。数式で書くと
amplitude * sin((i-18) / 12.0 * PI)
を計算しています。先程の式のiの部分をi-18に変えて、0から23の一周期ではなく、-18から5までの一周期を計算する形にしています。これは身体・感情・知性の三つのカーブが重ならないようにするためです。
amplitudeはカーブの振幅を決める変数で
static final double amplitude = -70.0;
とインスタンス変数として定義されています。
次の文
g.setColor(physicalColor);
で、線の色をphysicalColorにし、
g.drawLine(oldX + PHYSICAL_ORIGIN_X, oldYPhysical + ORIGIN_Y,
x + PHYSICAL_ORIGIN_X, yPhysical + ORIGIN_Y);
で2点(oldX + PHYSICAL_ORIGIN_X, oldYPhysical + ORIGIN_Y)と(x + PHYSICAL_ORIGIN_X, yPhysical + ORIGIN_Y)を直線で結びます。
PHYSICAL_ORIGIN_X、PHYSICAL_ORIGIN_Yはサインカーブの原点がCanvas内のどこにくるか決めていて
static final int PHYSICAL_ORIGIN_X = 45; static final int ORIGIN_Y = 110;
とインスタンス変数として定義してます。
最後に
oldX = x; oldYPhysical = yPhysical;
として今書いた直線の終点を、次に書く直線の始点にします。
これでループがまわるとサインカーブが描かれます。身体についてだけ説明しましたが、感情・知性についても同様です。
サインカーブを描くforループの前にしていることは
g.setColor(biorhythmGraphColor); g.fillRect(0, 35, width, 150);
で、バイオリズム曲線を描く部分をbiorhythmGraphColorで塗り潰し
int oldX = -3 * gridWidth; int oldYPhysical = (int)(amplitude * Math.sin((double)(-3 - 18) * Math.PI / 12.0));
で、ループないで最初に描く直線の始点を計算しています。
ループの後では
g.setColor(borderLineColor); g.drawLine(0, ORIGIN_Y, width, ORIGIN_Y);
で色をborderLineColorにして、0の値を示す線を描き、
g.setColor(biorhythmGraphColor); g.fillRect(width, 35, gridWidth * 3, 150);
で、はみ出してしまったバイオリズム曲線を消しています。