2010-02-28 6 views
4

J'ai récemment téléchargé l'exemple de code de GLPaint et j'ai regardé un élément très intéressant. Il y a un NSMutableArray enregistréPaths qui contient des points qui sont ensuite lus et dessinés par GLPaint.Comment créer mon propre fichier recordedPath dans GLPaint Exemple de code

Il est déclaré ici:

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

Voici le code pour la lecture:

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

} 

De ce que je comprends que recordedPaths est un tableau mutable que son dedans struct tableaux c de CGPoint qui sont alors lu et rendu. Je voudrais mettre dans mon propre tableau et j'ai eu des problèmes avec cela.

J'ai essayé de changer la déclaration de recordedPaths à ceci:

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

Cela ne fonctionne pas bien ... Un conseil?

Répondre

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

Mauvais code.

(1) Vous avez besoin d'un tableau de points. Le simple fait de déclarer CGPoint* points; ne créera pas un tableau de points, mais simplement un pointeur non initialisé de CGPoint. Vous devez allouer de l'espace pour le tableau soit avec

CGPoint points[100]; 

ou

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

N'oubliez pas de free les points si vous choisissez la voie malloc.

(2) Pour copier la valeur au contenu du pointeur, vous devez utiliser

*points = a; 

Mais je vous suggère de garder le pointeur points invariant dans la boucle, puisque vous allez le réutiliser plus tard. Utilisez la syntaxe du tableau points[i].

(3)

sizeof(*points) 

Depuis *points est juste un CGPoint, de sorte que le sizeof est toujours 8 octets. Vous devez multiplier le résultat par 100 pour obtenir la bonne longueur.

(4)

[NSData dataWithBytes:&points ... 

points est déjà un pointeur vers les données réelles. Vous n'avez pas besoin d'en reprendre l'adresse. Il suffit de passer directement au points.


Ainsi, le code final devrait ressembler à

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

J'ai essayé le code, avec ces lignes ajoutées à la fin: \t \t NSMutableArray * myArray = [[NSMutableArray alloc] init]; \t \t [myArray addObject: données]; \t \t [self performSelector: @selector (lecture :) withObject: recordedPaths afterDelay: 0.2]; mais il n'a rien affiché quand j'ai lancé l'application dans le simulateur – gizmoitai

+0

@giz comment implémenter '-renderLineFromPoint: toPoint:'? – kennytm

+0

Eh bien, la fonction de lecture l'implémente ... (Voir la question originale pour le code) – gizmoitai

1

Je viens de lire sur ce poste que je suis en train de achive une chose semblable. Avec les modifications apportées au projet original par Apple, j'ai pu créer une nouvelle 'forme' en modifiant le code en conséquence. Notez qu'il ne dessine qu'une ligne diagonale ... plusieurs fois. Mais la théorie est là pour créer votre propre dessin. J'ai pris le code de la publication de KennyTM et l'ai incorporé dans la fonction 'payback', cela pourrait être adapté pour créer le tableau dans la fonction initWithCoder et ensuite l'envoyer comme le code original mais pour l'instant - ce sera vous obtenez un résultat.

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

Je suis encore dans mes premières semaines sur le codage openGL, Pardonne donc des erreurs flagrantes/mauvaises méthodes et merci pour l'aide!

Hope this helps

6

Si vous regardez le Recording.data vous remarquerez que chaque ligne est son propre tableau. Pour capturer l'encre et la lire, vous devez disposer d'un tableau de tableaux. Aux fins de cette démonstration - déclarer un tableau mutable - writRay

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

capture l'encre

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

} 

Lecture de l'encre.

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

Pour un meilleur effet secouer l'écran pour effacer et appeler regarderRay de changeBrushColor dans AppController.