ハンサムスーツ観ますた。
今までのCTMやベジェ曲線描画実験を応用して、チンパンジーゲーム用のビューに独自のレベル設定用ビュー描画を組み込むわけだけど、本体への移植をやりやすくするために、機能をまとめたクラスとして定義してみる。
こんな感じ。
LevelMeterの画面上の中心、半径、角度を指定する。
![テン・シー・シー-fig.1](https://stat.ameba.jp/user_images/20090317/23/xcc/1b/a6/j/o0348036810153705093.jpg?caw=800)
受け取った座標inPosからLevelMeterが描く扇の円弧上のどの位置か0.0~1.0の値で返す。
![テン・シー・シー-fig.2](https://stat.ameba.jp/user_images/20090317/23/xcc/d4/a1/j/o0312019010153706890.jpg?caw=800)
inContext上にLevelMeterを描画する。この時、矢印の向きを0.0~1.0の範囲でinNumberによって指定。
pointToNumberでの計算
中心点と受け取ったinPos点で指定されるベクトルを単位ベクトルにしたさいのx,y成分はそれぞれ、consΘ、sinΘとなる。
![テン・シー・シー-fig.3](https://stat.ameba.jp/user_images/20090317/23/xcc/1c/fa/j/o0272026710153709409.jpg?caw=800)
そのため、今回ならacosによってΘを求めることができる(asinでは変化する範囲がLevelMeterの扇の範囲をカバーできない)。
![テン・シー・シー-fig.4](https://stat.ameba.jp/user_images/20090317/23/xcc/f7/27/j/o0292019810153710708.jpg?caw=800)
もちろんasinの変化はacosが上側のエリアでの変化なのか、下側のエリアなのかの判断には使える。
![テン・シー・シー-fig.5](https://stat.ameba.jp/user_images/20090317/23/xcc/64/e4/j/o0247018710153711565.jpg?caw=800)
が、今回はもっと簡単に中心点よりy座標が大きければ、下側のエリアと判断し、x座標で0.0か1.0にしてしまう。
受け取ったinPos点と中心点が一致した場合は、計算不可能。今回は0.0を返すことにする。
![テン・シー・シー-fig.6](https://stat.ameba.jp/user_images/20090317/23/xcc/3c/65/j/o0289026010153713237.jpg?caw=800)
ま、こんな感じでLevelMeter実装の準備ができたので、あとは「iPhoneアプリ開発、その(60)」や「その(40)」を参考に実際の実装をおこない、helloCTMView.mで利用する。
例のごとくinitWithFrameは呼ばれないので、setupLevelMeterってのを用意しました。
解放の方はdeallocでばっちり対応可能。
drawRectでLevelMeterインスタンスを使って描画するのと、「iPhoneアプリ開発、その(63)」を参考にtouchesBegan、touchesMovedを実装しLevelMeter インスタンスのpointToNumberを呼び出す。
今回は、まだ上のエリアか、下のエリアかとか、扇の角度とかぜんぜん対応してません。
とりあえず、画面触ると前回の矢印がグルグル動くので、腕に自信のある人は、こいつを参考に前の前の数字表示まで実装しちゃってください。
![テン・シー・シー-fig.7](https://stat.ameba.jp/user_images/20090318/00/xcc/c8/2e/j/o0205037810153733237.jpg?caw=800)
あと、drawメソッドの中で使われてる
は、今回お初です。これがどういう役割を果たしているかはその次の行
を削ってみるとわかるよん。
詳細は次回!
------------
サンプルプロジェクト:helloCTM-7.zip
今までのCTMやベジェ曲線描画実験を応用して、チンパンジーゲーム用のビューに独自のレベル設定用ビュー描画を組み込むわけだけど、本体への移植をやりやすくするために、機能をまとめたクラスとして定義してみる。
@interface LevelMeter : NSObject {
double radius;
double angle;
CGPoint center;
}
- (void)set:(CGPoint)inPos r:(int)inRadius angle:(double)inRadian;
- (double)pointToNumber:(CGPoint)inPos;
- (void)draw:(CGContextRef)inContext num:(double)inNumber;
@end
こんな感じ。
- (void)set:(CGPoint)inPos r:(int)inRadius angle:(double)inRadian;
LevelMeterの画面上の中心、半径、角度を指定する。
![テン・シー・シー-fig.1](https://stat.ameba.jp/user_images/20090317/23/xcc/1b/a6/j/o0348036810153705093.jpg?caw=800)
- (double)pointToNumber:(CGPoint)inPos;
受け取った座標inPosからLevelMeterが描く扇の円弧上のどの位置か0.0~1.0の値で返す。
![テン・シー・シー-fig.2](https://stat.ameba.jp/user_images/20090317/23/xcc/d4/a1/j/o0312019010153706890.jpg?caw=800)
-(void)draw:()inContext num:(double)inNumber
inContext上にLevelMeterを描画する。この時、矢印の向きを0.0~1.0の範囲でinNumberによって指定。
pointToNumberでの計算
中心点と受け取ったinPos点で指定されるベクトルを単位ベクトルにしたさいのx,y成分はそれぞれ、consΘ、sinΘとなる。
![テン・シー・シー-fig.3](https://stat.ameba.jp/user_images/20090317/23/xcc/1c/fa/j/o0272026710153709409.jpg?caw=800)
そのため、今回ならacosによってΘを求めることができる(asinでは変化する範囲がLevelMeterの扇の範囲をカバーできない)。
![テン・シー・シー-fig.4](https://stat.ameba.jp/user_images/20090317/23/xcc/f7/27/j/o0292019810153710708.jpg?caw=800)
もちろんasinの変化はacosが上側のエリアでの変化なのか、下側のエリアなのかの判断には使える。
![テン・シー・シー-fig.5](https://stat.ameba.jp/user_images/20090317/23/xcc/64/e4/j/o0247018710153711565.jpg?caw=800)
が、今回はもっと簡単に中心点よりy座標が大きければ、下側のエリアと判断し、x座標で0.0か1.0にしてしまう。
受け取ったinPos点と中心点が一致した場合は、計算不可能。今回は0.0を返すことにする。
![テン・シー・シー-fig.6](https://stat.ameba.jp/user_images/20090317/23/xcc/3c/65/j/o0289026010153713237.jpg?caw=800)
ま、こんな感じでLevelMeter実装の準備ができたので、あとは「iPhoneアプリ開発、その(60)」や「その(40)」を参考に実際の実装をおこない、helloCTMView.mで利用する。
例のごとくinitWithFrameは呼ばれないので、setupLevelMeterってのを用意しました。
- (void)setupLevelMeter {
meter = [[[LevelMeter alloc] init] retain];
[meter set:CGPointMake(self.frame.size.width / 2, self.frame.size.height / 2) r:100.0 angle:0.0];
}
解放の方はdeallocでばっちり対応可能。
- (void)dealloc {
[super dealloc];
[meter release];
}
drawRectでLevelMeterインスタンスを使って描画するのと、「iPhoneアプリ開発、その(63)」を参考にtouchesBegan、touchesMovedを実装しLevelMeter インスタンスのpointToNumberを呼び出す。
今回は、まだ上のエリアか、下のエリアかとか、扇の角度とかぜんぜん対応してません。
とりあえず、画面触ると前回の矢印がグルグル動くので、腕に自信のある人は、こいつを参考に前の前の数字表示まで実装しちゃってください。
![テン・シー・シー-fig.7](https://stat.ameba.jp/user_images/20090318/00/xcc/c8/2e/j/o0205037810153733237.jpg?caw=800)
あと、drawメソッドの中で使われてる
CGContextConvertPointToDeviceSpace
は、今回お初です。これがどういう役割を果たしているかはその次の行
CGContextTranslateCTM
を削ってみるとわかるよん。
詳細は次回!
------------
サンプルプロジェクト:helloCTM-7.zip