RepeatingMorifをランダマイズできる様にする
まだMasterMotifをランダマイズする機能しか持っていませんが、ここでRepeatingMotifをランダマイズする機能を追加します。Repeating Motif Saverの方では既に持っている機能なので、これを移植していく感じになります。
JISColor.plistを読み込む
下請けのルーチンからボトムアップで追加していきます。まず下準備として第八のプロジェクトで作成したJISColor.plistを読み込んでおきましょう。これはJISで「物体色の色名」として規定されている色の情報が入ったプロパティリストです。色をランダムに選ぶ際にこの中の色から選びたいので、インスタンス変数にNSArrayを追加して、initメソッドでこの配列にJISColor.plistを読み込む処理を追加します。
まず配列を追加します。
@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;
NSArray *colorInfoArray;
}
+ (id)sharedRandomizer;
- (void)randomizeMasterMotif:(MasterMotif *)masterMotif
withUndoManager:(NSUndoManager *)undoManager
lockFrequency:(BOOL)isLockFrequency;
@end
NSBundleのpathForResource:ofType:メソッドを使ってプロパティリストのパスを入手します。このパスを使ってNSArrayのarrayWithContentsOfFile:メソッドで配列に読み込みます。JISColor.plistをプロジェクトに追加する事をお忘れなく。
colorInfoArrayの所有権が発生したので、deallocメソッドで忘れずにreleaseしておきます。
- (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"];
}
return self;
}
- (void)dealloc
{
[colorInfoArray release];
[super dealloc];
}
ランダムなfloat,boolを得る
「原図のパラメータを乱数を使って決定する」でランダムな整数を得るメソッドを作りました。短いので再掲しますが、以下のメソッドです。
- (int)randomIntBetweenA:(int)a andB:(int)b
{
int range = b - a < 0 ? b - a - 1 : b - a + 1;
int value = (int)(range*((float)random()/(float)LONG_MAX));
return value == range ? a : a + value;
}
これのfloat版を作ると以下の様になります。
- (float)randomFloatBetweenA:(float)a andB:(float)b
{
return a + (b-a)*((float)random()/(float)LONG_MAX);
}
これのbool版を作ると以下の様になります。
- (BOOL)randomBool
{
if( (float)random()/(float)LONG_MAX > 0.5 )
return YES;
else
return NO;
}
ランダムな色を得る
colorInfoArrayの中には267個の色のデータが入っています。その中からランダムに一つを選び出してcolorInfoに入れます。colorInfoもまた配列ですが、キー文字列、シアン、マゼンタ、イエロー、ブラックの順にデータが格納されています。データは0から100までの整数値ですので、100で割る事で規格化してcolorWithDeviceCyan:magenta:yellow:black:alpha:メソッドに渡しています。アルファ値は1.0として完全不透明にしています。
- (NSColor *)randomColor
{
NSArray *colorInfo = [colorInfoArray objectAtIndex:
[self randomIntBetweenA:0 andB:266]];
int cyanValue,magentaValue,yellowValue,blackValue;
cyanValue = [[colorInfo objectAtIndex:1] intValue];
magentaValue = [[colorInfo objectAtIndex:2] intValue];
yellowValue = [[colorInfo objectAtIndex:3] intValue];
blackValue = [[colorInfo objectAtIndex:4] intValue];
return [NSColor colorWithDeviceCyan:cyanValue/100.0
magenta:magentaValue/100.0
yellow:yellowValue/100.0
black:blackValue/100.0
alpha:1.0];
}