4

私は最近 GLPaint サンプル コードをダウンロードし、非常に興味深い部分を調べました。GLPaint によって読み取られ、描画されるポイントを持つrecordedPaths NSMutableArray があります。

ここで宣言されています:

NSMutableArray *recordedPaths;
recordedPaths = [NSMutableArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Recording" ofType:@"data"]];
if([recordedPaths count])
     [self performSelector:@selector(playback:) withObject:recordedPaths afterDelay:0.2];

これは再生用のコードです:

 - (void) playback:(NSMutableArray*)recordedPaths {

     NSData*                    data = [recordedPaths objectAtIndex:0];

     CGPoint*               point = (CGPoint*)[data bytes];

     NSUInteger               count = [data length] / sizeof(CGPoint),

                              i;



     //Render the current path

     for(i = 0; i < count - 1; ++i, ++point)

          [self renderLineFromPoint:*point toPoint:*(point + 1)];



     //Render the next path after a short delay 

     [recordedPaths removeObjectAtIndex:0];

     if([recordedPaths count])

          [self performSelector:@selector(playback:) withObject:recordedPaths afterDelay:0.01];

}

このことから、recordedPaths は変更可能な配列であり、その中にある CGPoint の struct c 配列が読み取られてレンダリングされることがわかります。自分の配列を入れたいのですが、それで問題が発生しています。

私はrecordedPaths宣言をこれに変更しようとしました:

      NSMutableArray *myArray = [[NSMutableArray alloc] init];

      CGPoint* points;

      CGPoint a = CGPointMake(50,50);

      int i;

      for (i=0; i<100; i++,points++) {

           a = CGPointMake(i,i);

           points = &a;

      }

      NSData *data = [NSData dataWithBytes:&points length:sizeof(*points)];

      [myArray addObject:data];

これはうまくいきませんでした...何かアドバイスはありますか?

4

3 に答える 3

6

Recording.data を見ると、各行が独自の配列であることがわかります。インクをキャプチャして再生するには、配列の配列が必要です。このデモの目的のために - 可変配列を宣言します - writRay

    @synthesize writRay;
//init in code
 writRay = [[NSMutableArray alloc]init];

インクをキャプチャ

// Handles the continuation of a touch.
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{  

 CGRect    bounds = [self bounds];
 UITouch*   touch = [[event touchesForView:self] anyObject];

 // Convert touch point from UIView referential to OpenGL one (upside-down flip)
 if (firstTouch) {
  firstTouch = NO;
  previousLocation = [touch previousLocationInView:self];
  previousLocation.y = bounds.size.height - previousLocation.y;
  /******************* create a new array for this stroke's points **************/
  [writRay addObject:[[NSMutableArray alloc]init]];
  /***** add 1st point *********/
  [[writRay objectAtIndex:[writRay count] -1]addObject:[NSValue valueWithCGPoint:previousLocation]];
 } else {
  location = [touch locationInView:self];
     location.y = bounds.size.height - location.y;
  previousLocation = [touch previousLocationInView:self];
  previousLocation.y = bounds.size.height - previousLocation.y;
  /********* add additional points *********/
  [[writRay objectAtIndex:[writRay count] -1]addObject:[NSValue valueWithCGPoint:previousLocation]];
 }

 // Render the stroke
 [self renderLineFromPoint:previousLocation toPoint:location];

}

インクを再生します。

- (void)playRay{

 if(writRay != NULL){

  for(int l = 0; l < [writRay count]; l++){
    //replays my writRay -1 because of location point
   for(int p = 0; p < [[writRay objectAtIndex:l]count] -1; p ++){
    [self renderLineFromPoint:[[[writRay objectAtIndex:l]objectAtIndex:p]CGPointValue] toPoint:[[[writRay objectAtIndex:l]objectAtIndex:p + 1]CGPointValue]];
   }
  }
 }
}

最良の効果を得るには、画面を振ってクリアし、AppController の changeBrushColor から playRay を呼び出します。

于 2010-12-09T16:20:20.100 に答える
1
  CGPoint* points;
  CGPoint a = CGPointMake(50,50);
  int i;
  for (i=0; i<100; i++,points++) {
       a = CGPointMake(i,i);
       points = &a;
  }
  NSData *data = [NSData dataWithBytes:&points length:sizeof(*points)];

不正なコード。

(1)ポイントの配列が必要です。宣言CGPoint* points;するだけでは点の配列は作成されず、CGPoint の初期化されていないポインターが作成されます。次のいずれかを使用して、配列にスペースを割り当てる必要があります

CGPoint points[100];

また

CGPoint* points = malloc(sizeof(CGPoint)*100);

free方法を選択する場合は、ポイントを覚えておいてくださいmalloc

(2)使用する必要があるポインタの内容に値をコピーするには

*points = a;

ただしpoints、後で再利用するため、ポインターをループ内で不変に保つことをお勧めします。配列構文を使用しますpoints[i]

(3)

sizeof(*points)

*pointsは CGPoint が 1 つだけなので、sizeof は常に 8 バイトです。正しい長さを得るには、結果に 100 を掛ける必要があります。

(4)

 [NSData dataWithBytes:&points ...

pointsalready は実際のデータへのポインタです。そのアドレスを再度取得する必要はありません。points直接渡すだけ。


したがって、最終的なコードは次のようになります

  CGPoint* points = malloc(sizeof(CGPoint)*100); // make a cast if the compiler warns.
  CGPoint a;
  int i;
  for (i=0; i<100; i++) {
       a = CGPointMake(i,i);
       points[i] = a;
  }
  NSData *data = [NSData dataWithBytes:points length:sizeof(*points)*100];
  free(points);
于 2010-02-28T06:50:44.067 に答える
1

同様のことを達成しようとしているので、この投稿を読んでいました。Apple による元のプロジェクトへの変更により、コードを適宜変更することで、新しい「形状」を作成することができました。

対角線のみを描画することに注意してください...数回。しかし、独自の図面を作成するための理論があります。

KennyTM の投稿からコードを取得し、それを「payback」関数に組み込みました。これは、initWithCoder 関数で配列を作成し、元のコードのように送信するように適合させることができますが、今のところ、これで結果が得られます。 .

    CGPoint* points = malloc(sizeof(CGPoint)*100);
CGPoint a;
int iter;
for (iter=0; iter<200; iter++) {
    a = CGPointMake(iter,iter);
    points[iter] = a;
}
NSData *data = [NSData dataWithBytes:points length:sizeof(*points)*100];
free(points);

CGPoint*            point = (CGPoint*)[data bytes];
NSUInteger      count = [data length] / sizeof(CGPoint),
                    i;

for(i = 0; i < count - 1; ++i, ++point)
    [self renderLineFromPoint:*point toPoint:*(point + 1)];

[recordedPaths removeObjectAtIndex:0];
if([recordedPaths count])
    [self performSelector:@selector(playback:) withObject:recordedPaths afterDelay:0.01];

私はまだ openGL コーディングの最初の数週間にいるので、明らかな間違いや悪い方法を許してください。助けてくれてありがとう!

お役に立てれば

于 2010-04-08T22:44:07.420 に答える