対称性パターンをランダムに選ぶ
インスタンス変数を追加する
ここから実際にRepeatingMotifのパラメータを書き換えるメソッドを実装していきます。そこで対象となるRepeatingMotifとRepeatingMotifLayerを表すインスタンス変数を追加します。
対称性パターンをランダムに選ぶ時に、それぞれの対称性パターンを選択肢の中に入れるかどうかを表すBOOL型のインスタンス変数を追加します。例えばpgとcmmとp31mだけがYESで他が全てNOであった場合、pgとcmmとp31mの三つの中からランダムに選ぶ動作となります。
@class MasterMotif;
@interface Randomizer : NSObject
{
int amplitudeMinX1,amplitudeMinX2,amplitudeMinX3;
int amplitudeMaxX1,amplitudeMaxX2,amplitudeMaxX3;
int amplitudeMinY1,amplitudeMinY2,amplitudeMinY3;
int amplitudeMaxY1,amplitudeMaxY2,amplitudeMaxY3;
int frequencyMinX1,frequencyMinX2,frequencyMinX3;
int frequencyMaxX1,frequencyMaxX2,frequencyMaxX3;
int frequencyMinY1,frequencyMinY2,frequencyMinY3;
int frequencyMaxY1,frequencyMaxY2,frequencyMaxY3;
RepeatingMotif *repeatingMotif;
RepeatingMotifLayer *layer;
BOOL p1,p2,pm,pg,cm,pmm,pmg,pgg,cmm;
BOOL p4,p4m,p4g,p3,p3m1,p31m,p6,p6m;
NSArray *colorInfoArray;
}
+ (id)sharedRandomizer;
- (void)randomizeMasterMotif:(MasterMotif *)masterMotif
withUndoManager:(NSUndoManager *)undoManager
lockFrequency:(BOOL)isLockFrequency;
@end
環境設定では以下の部分で設定します。
追加したインスタンス変数をバインドする
追加したインスタンス変数は環境設定でユーザが設定するものなので、初期化メソッドでデフォルトデータベースとバインドしておきます。
- (id)init
{
self = [super init];
if(self)
{
srandom(time(NULL));
NSString *fileName =
[[NSBundle mainBundle] pathForResource:@"JISColor"
ofType:@"plist"];
colorInfoArray =
[[NSArray arrayWithContentsOfFile:fileName] retain];
[self bindWithName:@"amplitudeMinX1"];
[self bindWithName:@"amplitudeMinX2"];
[self bindWithName:@"amplitudeMinX3"];
[self bindWithName:@"amplitudeMaxX1"];
[self bindWithName:@"amplitudeMaxX2"];
[self bindWithName:@"amplitudeMaxX3"];
[self bindWithName:@"amplitudeMinY1"];
[self bindWithName:@"amplitudeMinY2"];
[self bindWithName:@"amplitudeMinY3"];
[self bindWithName:@"amplitudeMaxY1"];
[self bindWithName:@"amplitudeMaxY2"];
[self bindWithName:@"amplitudeMaxY3"];
[self bindWithName:@"frequencyMinX1"];
[self bindWithName:@"frequencyMinX2"];
[self bindWithName:@"frequencyMinX3"];
[self bindWithName:@"frequencyMaxX1"];
[self bindWithName:@"frequencyMaxX2"];
[self bindWithName:@"frequencyMaxX3"];
[self bindWithName:@"frequencyMinY1"];
[self bindWithName:@"frequencyMinY2"];
[self bindWithName:@"frequencyMinY3"];
[self bindWithName:@"frequencyMaxY1"];
[self bindWithName:@"frequencyMaxY2"];
[self bindWithName:@"frequencyMaxY3"];
[self bindWithName:@"p1"];
[self bindWithName:@"p2"];
[self bindWithName:@"pm"];
[self bindWithName:@"pg"];
[self bindWithName:@"cm"];
[self bindWithName:@"pmm"];
[self bindWithName:@"pmg"];
[self bindWithName:@"pgg"];
[self bindWithName:@"cmm"];
[self bindWithName:@"p4"];
[self bindWithName:@"p4m"];
[self bindWithName:@"p4g"];
[self bindWithName:@"p3"];
[self bindWithName:@"p3m1"];
[self bindWithName:@"p31m"];
[self bindWithName:@"p6"];
[self bindWithName:@"p6m"];
}
return self;
}
対称性パターンをランダムに選んでセットする
それぞれの対称性パターンを選択肢の中に入れるかどうかがBOOL型のインスタンス変数p1〜p6mで表されています。例えばpgとcmmとp31mだけがYESで他が全てNOであった場合、pgとcmmとp31mの三つの中からランダムに選ぶ動作となります。
これをどう実現するかですが、例えるなら
- 箱の中に番号札を入れる
- 箱からランダムに札を引く
という二つの手順を踏んで、実現しています。最初の番号札を箱に入れる時点で選択肢の中に入れるかどうかを見て、これがNOの場合は最初から箱に入れなければよい訳です。
typesが箱に相当するオブジェクトです。p1〜p6mがYESの場合、該当する数値が入ったNSNumberをtypesの中に入れます。最後にNSNumberの数を数えてそれに応じた乱数を作り、その乱数番目のNSNumberを取り出して、中に入っている数値で対称性パターンを決定して終了です。ただし、箱が空っぽという場合もあり得るので、その場合はp1が選ばれた事にします。
- (void)randomizeSymmetryType
{
NSMutableArray *types = [NSMutableArray arrayWithCapacity:17];
if(p1) [types addObject:[NSNumber numberWithInt:0]];
if(p2) [types addObject:[NSNumber numberWithInt:1]];
if(pm) [types addObject:[NSNumber numberWithInt:2]];
if(pg) [types addObject:[NSNumber numberWithInt:3]];
if(cm) [types addObject:[NSNumber numberWithInt:4]];
if(pmm) [types addObject:[NSNumber numberWithInt:5]];
if(pmg) [types addObject:[NSNumber numberWithInt:6]];
if(pgg) [types addObject:[NSNumber numberWithInt:7]];
if(cmm) [types addObject:[NSNumber numberWithInt:8]];
if(p4) [types addObject:[NSNumber numberWithInt:9]];
if(p4m) [types addObject:[NSNumber numberWithInt:10]];
if(p4g) [types addObject:[NSNumber numberWithInt:11]];
if(p3) [types addObject:[NSNumber numberWithInt:12]];
if(p3m1) [types addObject:[NSNumber numberWithInt:13]];
if(p31m) [types addObject:[NSNumber numberWithInt:14]];
if(p6) [types addObject:[NSNumber numberWithInt:15]];
if(p6m) [types addObject:[NSNumber numberWithInt:16]];
int count = [types count];
if(count == 0)
[repeatingMotif setSymmetryTypeIndex:0];
else
[repeatingMotif setSymmetryTypeIndex:
[[types objectAtIndex:
[self randomIntBetweenA:0 andB:count-1]] intValue]];
}