Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
312 views
in Technique[技术] by (71.8m points)

ios - Multitouch tracking issue

I am working with multitouch while writing, So basically what I am doing is, I am writing with hand support, because typically, its how user rights, I followed this link How to ignore certain UITouch Points in multitouch sequence

So, what I am doing is , I am tracking a touch Object in touchesBegan and using that only in touchesMoved.Everything works fine, but some times while writing, I get this line

enter image description here

In the above image, you can see the thick line which suddenly comes while writing with my hand touched on the screen

Here is the code

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"Touches began");   

    UITouch* topmostTouch = self.trackingTouch;
    for (UITouch *touch in touches)
    {
        bufIdx = 0;
        isFirstTouchPoint = YES;
        ctr = 0;

        pts[0] = [touch locationInView:self];


        if(!topmostTouch || [topmostTouch locationInView:self].y > pts[0].y)
        {
            topmostTouch = touch;
            //touchStartPoint1 = pts[0];
        }
        else
        {
            pts[0] = pts[3];
        }
    }

   if (self.trackingTouch != nil && self.trackingTouch != topmostTouch) 
   {
     [self discardDrawing];        
   }

    self.trackingTouch = topmostTouch;
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{    
        // Find the touch that we track for drawing

            CGPoint p = [self.trackingTouch locationInView:self];
            ctr++;
            pts[ctr] = p;

            if (ctr == 4)
            {
                pts[3] = midPoint(pts[2], pts[4]);

                for ( int i = 0; i < 4; i++)
                {
                    pointsBuffer[bufIdx + i] = pts[i];
                }

                bufIdx += 4;

                dispatch_async(drawingQueue, ^{
                    //UIBezierPath *offsetPath = [UIBezierPath bezierPath]; // ................. (2)

                    self.currentPath = [[DrawingPath alloc] init];                   
                    [self.currentPath setPathColor:self.lineColor];


                    if (bufIdx == 0) return;

                    LineSegment ls[4];
                    for ( int i = 0; i < bufIdx; i += 4)
                    {
                        if (isFirstTouchPoint) // ................. (3)
                        {                           
                            ls[0] = (LineSegment){pointsBuffer[0], pointsBuffer[0]};
                            [self.currentPath.path moveToPoint:ls[0].firstPoint];                      
                            isFirstTouchPoint = NO;                   
                        }
                        else
                        {
                            ls[0] = lastSegmentOfPrev;

                        }


                        float frac1 = self.lineWidth/clamp(len_sq(pointsBuffer[i], pointsBuffer[i+1]), LOWER, UPPER); // ................. (4)
                        float frac2 = self.lineWidth/clamp(len_sq(pointsBuffer[i+1], pointsBuffer[i+2]), LOWER, UPPER);
                        float frac3 = self.lineWidth/clamp(len_sq(pointsBuffer[i+2], pointsBuffer[i+3]), LOWER, UPPER);



                        ls[1] = [self lineSegmentPerpendicularTo:(LineSegment){pointsBuffer[i], pointsBuffer[i+1]} ofRelativeLength:frac1]; // ................. (5)
                        ls[2] = [self lineSegmentPerpendicularTo:(LineSegment){pointsBuffer[i+1], pointsBuffer[i+2]} ofRelativeLength:frac2];
                        ls[3] = [self lineSegmentPerpendicularTo:(LineSegment){pointsBuffer[i+2], pointsBuffer[i+3]} ofRelativeLength:frac3];



                        [self.currentPath.path  moveToPoint:ls[0].firstPoint]; // ................. (6)
                        [self.currentPath.path  addCurveToPoint:ls[3].firstPoint controlPoint1:ls[1].firstPoint controlPoint2:ls[2].firstPoint];
                        [self.currentPath.path  addLineToPoint:ls[3].secondPoint];
                        [self.currentPath.path  addCurveToPoint:ls[0].secondPoint controlPoint1:ls[2].secondPoint controlPoint2:ls[1].secondPoint];
                        [self.currentPath.path  closePath];

                        lastSegmentOfPrev = ls[3]; // ................. (7)
                    }


                     dispatch_async(dispatch_get_main_queue(), ^{
                            bufIdx = 0;

                            [m_pathArray addObject:self.currentPath];
                            [self setNeedsDisplay];

                        });
                    });


                pts[0] = pts[3];
                pts[1] = pts[4]; 
                ctr = 1;
            }
        }        
}

So friends, please help me out.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You will need to debug to confirm, but it appears to be related to your logic in touchesBegan:withEvent:. In this method, you check each time there is a new touch to determine if it is the 'highest', but when the highest touch does actually change you don't seem to abort / reset any existing drawing.

Your best approach is probably using logging to determine if / when the 'highest' touch is changing and what affect that has on the in-progress line.

Also, in touchesMoved:, you don't need the for (UITouch *touch in touches) loop as you already have a reference to self.trackingTouch so you can just use it directly.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...