2010-02-28 1 views
4

Недавно я загрузил образец кода GLPaint и посмотрел на него очень интересную часть. Существует зарегистрированный файл NSMutableArray, в котором есть точки, которые затем читаются и рисуются GLPaint.Как создать собственный файл записи в 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 является изменяемый массив, его в нем STRUCT гр массивы 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]; 

Это не сработало, хотя ... Любые советы?

ответ

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); 
+0

Я попытался код, с этим добавлены строки в конце: \t \t NSMutableArray * туАггау = [[NSMutableArray Alloc] инициализации]; \t \t [myArray addObject: data]; \t \t [self производитсяSelector: @selector (воспроизведение :) сObject: записаноPaths послеDelay: 0.2]; но он ничего не обнаружил, когда я запустил приложение в симуляторе. – gizmoitai

+0

@giz как вам реализовать. -renderLineFromPoint: toPoint: '? – kennytm

+0

Ну, функция воспроизведения реализует его ... (См. Оригинальный вопрос для кода) – gizmoitai

1

Я просто читал на этом посту, как я пытаюсь для того чтобы достигнуть подобную вещь. С изменениями к оригинальному проекту Apple, я смог создать новую «форму», изменив код соответствующим образом.

Обратите внимание, что он рисует только диагональ ... несколько раз. Но теория заключается в создании собственного рисунка.

Я взял код из сообщения KennyTM и включил его в функцию «окупаемости», это можно было бы адаптировать для создания массива в функции 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, так что прощу любые грубые ошибки/плохие методы и спасибо за помощь!

Надеется, что это помогает

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]]; 
    } 
    } 
} 
} 

Для достижения наилучшего эффекта встряхнуть экран, чтобы очистить и вызывать playRay из changeBrushColor в AppController.