更新情報
広告
PRサイト
関連サイト

RepeatingMorifをランダマイズできる様にする

まだMasterMotifをランダマイズする機能しか持っていませんが、ここでRepeatingMotifをランダマイズする機能を追加します。Repeating Motif Saverの方では既に持っている機能なので、これを移植していく感じになります。


JISColor.plistを読み込む

下請けのルーチンからボトムアップで追加していきます。まず下準備として第八のプロジェクトで作成したJISColor.plistを読み込んでおきましょう。これはJISで「物体色の色名」として規定されている色の情報が入ったプロパティリストです。色をランダムに選ぶ際にこの中の色から選びたいので、インスタンス変数にNSArrayを追加して、initメソッドでこの配列にJISColor.plistを読み込む処理を追加します。

まず配列を追加します。

Randomizer.h
@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しておきます。

Randomizer.m
- (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を得る

「原図のパラメータを乱数を使って決定する」でランダムな整数を得るメソッドを作りました。短いので再掲しますが、以下のメソッドです。

Randomizer.m
- (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版を作ると以下の様になります。

Randomizer.m
- (float)randomFloatBetweenA:(float)a andB:(float)b
{
    return a + (b-a)*((float)random()/(float)LONG_MAX);
}

これのbool版を作ると以下の様になります。

Randomizer.m
- (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として完全不透明にしています。

Randomizer.m
- (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];
}


ページの先頭へ戻る