2012-04-04 1 views
2

Est-il possible de détecter chaque pixel touché? Plus précisément, lorsque l'utilisateur touche l'écran, est-il possible de suivre toutes les coordonnées x-y de la grappe de points touchée par l'utilisateur? Comment puis-je faire la différence entre quand les utilisateurs dessinent avec leur pouce et quand ils dessinent avec le bout du doigt? Je voudrais refléter la différence de pinceau en fonction de la façon dont les utilisateurs touchent l'écran, et je voudrais également suivre tous les pixels touchés.Obtention de pixels individuels à partir du point de contact

J'utilise actuellement les codes suivants à partir de l'échantillon GLPaint de site développeur d'Apple:

http://developer.apple.com/library/ios/#samplecode/GLPaint/Introduction/Intro.html

Les codes d'échantillons permettre le dessin avec une taille de pinceau prédéfini et le suivi des coordonnées x-y le long du chemin. Comment puis-je changer la brosse en fonction de la façon dont les utilisateurs touchent l'écran et suivre tous les pixels touchés au fil du temps?

// Drawings a line onscreen based on where the user touches 

- (void) renderLineFromPoint:(CGPoint)start toPoint:(CGPoint)end 

{ 
    NSLog(@"x:%f y:%f",start.x, start.y); 

    static GLfloat*   vertexBuffer = NULL; 

    static NSUInteger  vertexMax = 64; 

    NSUInteger    vertexCount = 0, 

        count, 

        i; 



    [EAGLContext setCurrentContext:context]; 

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); 



    // Convert locations from Points to Pixels 

    CGFloat scale = self.contentScaleFactor; 

    start.x *= scale; 

    start.y *= scale; 

    end.x *= scale; 

    end.y *= scale; 



    // Allocate vertex array buffer 

    if(vertexBuffer == NULL) 

      vertexBuffer = malloc(vertexMax * 2 * sizeof(GLfloat)); 



    // Add points to the buffer so there are drawing points every X pixels 

    count = MAX(ceilf(sqrtf((end.x - start.x) * (end.x - start.x) + (end.y - start.y) * (end.y - start.y))/kBrushPixelStep), 1); 

    for(i = 0; i < count; ++i) { 

      if(vertexCount == vertexMax) { 

       vertexMax = 2 * vertexMax; 

       vertexBuffer = realloc(vertexBuffer, vertexMax * 2 * sizeof(GLfloat)); 

      } 



      vertexBuffer[2 * vertexCount + 0] = start.x + (end.x - start.x) * ((GLfloat)i/(GLfloat)count); 

      vertexBuffer[2 * vertexCount + 1] = start.y + (end.y - start.y) * ((GLfloat)i/(GLfloat)count); 

      vertexCount += 1; 

    } 



    // Render the vertex array 

    glVertexPointer(2, GL_FLOAT, 0, vertexBuffer); 

    glDrawArrays(GL_POINTS, 0, vertexCount); 



    // Display the buffer 

    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); 

    [context presentRenderbuffer:GL_RENDERBUFFER_OES]; 

} 


// Handles the start of a touch 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 

{ 

    CGRect     bounds = [self bounds]; 

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

    firstTouch = YES; 

    // Convert touch point from UIView referential to OpenGL one (upside-down flip) 

    location = [touch locationInView:self]; 

    location.y = bounds.size.height - location.y; 

} 

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

    } else { 

      location = [touch locationInView:self]; 

     location.y = bounds.size.height - location.y; 

      previousLocation = [touch previousLocationInView:self]; 

      previousLocation.y = bounds.size.height - previousLocation.y; 

    } 



    // Render the stroke 

    [self renderLineFromPoint:previousLocation toPoint:location]; 

} 



// Handles the end of a touch event when the touch is a tap. 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 

{ 

    CGRect     bounds = [self bounds]; 

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

    if (firstTouch) { 

      firstTouch = NO; 

      previousLocation = [touch previousLocationInView:self]; 

      previousLocation.y = bounds.size.height - previousLocation.y; 

      [self renderLineFromPoint:previousLocation toPoint:location]; 

    } 

} 


// Handles the end of a touch event. 

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event 

{ 

    // If appropriate, add code necessary to save the state of the application. 

    // This application is not saving state. 

} 

Répondre

1

AFAIK il n'y a pas d'API pour accéder à la zone tactile pour un toucher. Je ne suis même pas sûr, étant donné les limites d'un écran tactile capacitif, si ce que vous voulez est physiquement possible. Je me souviens d'une présentation faite récemment à Cocoa Heads où il était démontré que certaines informations étaient disponibles sur OS X (via une API privée) pour les trackpads, mais pas pour iOS.

Je crois que c'est une des raisons pour que les graphiques comprimés emploient stylets spéciaux qui ont leur propre technologie de capteur intégré.

Une solution partielle, pour une application de dessin, peut-être pour simuler « encrage » comme certaines applications de bureau font : si le contact d'un utilisateur persiste à un endroit donné, dessinez comme si de l'encre sortait du "stylo" et diffusait progressivement à travers le "papier".

+0

Merci beaucoup pour votre réponse. Savez-vous si cela est possible sur Android? – HappyAppDeveloper

+0

Je n'ai aucune idée, désolé, je ne développe pas pour Android. Je suis sûr que d'autres auront une réponse, cependant. Si vous ne trouvez rien sur la recherche, je suggère de poster une nouvelle question étiquetée comme Android. –

1

Le matériel Broadcomm dans l'iPad scanne l'écran avec 64 Hz. Il le fait en plaçant consécutivement un signal de 400 μs sur les 39 couches conductrices transparentes qui constituent les électrodes tactiles. Si votre doigt bouge de plus d'une distance de pixel en 0.015625 sec, ce qui est probable, le matériel ne peut pas le détecter car il est occupé à mesurer d'autres parties de l'écran pour plus d'événements tactiles.

Ceci est la même quel que soit iOS ou Android. Les tablettes Android bon marché et les grands écrans ont un taux de balayage réduit, de sorte que leurs événements tactiles sont encore plus espacés. Une tablette Wacom exécute le numériseur à 100 Hz, de sorte que la séquence de points sera plus fine, mais manquera encore les pixels que le stylet touche entre deux mesures.

Questions connexes