如何在GLPaint示例代码中创建自己的recordedPath

时间:2010-02-28 05:16:34

标签: iphone objective-c quartz-2d

我最近下载了GLPaint示例代码并查看了其中一个非常有趣的部分。有一个recordsPaths NSMutableArray,其中包含点,然后由GLPaint读取和绘制。

这里宣布:

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数组,然后进行读取和渲染。 我想放入自己的阵列,我一直遇到麻烦。

我尝试将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];

这虽然不起作用...... 有什么建议吗?

3 个答案:

答案 0 :(得分: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。

答案 1 :(得分: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,因此sizeof总是8个字节。您需要将结果乘以100才能获得正确的长度。

<强>(4)

 [NSData dataWithBytes:&points ...

points已经是指向实际数据的指针。您不需要再次获取它的地址。只需直接传递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);

答案 2 :(得分: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编码的第一周,所以请原谅任何明显的错误/错误的方法,并感谢您的帮助!

希望这有帮助