2016-09-02 5 views
-1

Ich habe ein Array von CGPoints, die gezeichnet einer Catmull-Rom verwendet werden bezierpath CGPoint interpolation by jnfisher mit Was ich will, ist der nächste Punkt auf dem Weg zu dem Berührungspunkt zu wählen, wenn der Benutzer eine beliebige Stelle innerhalb eines Bereichs berührt um jeden Punkt auf dem Weg. Dieser Bereich wird als ein imaginäres Quadrat angegeben, das den Punkt auf dem Pfad mit einer Toleranz vor und nach jedem Punkt auf dem Pfad entlang der X- und Y-Achse enthält. Meine Strategie ist 1. Legen Sie eine Toleranz für jeden Punkt auf dem Pfad fest, der feststellt, ob sich die Touch-Position innerhalb des Quadrats mit diesen Seiten auf der X-Achse befindet: (discoveryPoint.x - tolerance to discoveryPoint.x + tolerance) und auf Y axis: (discoveryPoint.y - Toleranz für discoveryPoint.y + tolerance. 2. Berechne den Abstand zwischen dem berührten Punkt und allen Punkten in meinem Array, die den berührten Punkt in ihrem Quadrat enthalten. 3. Wähle den Mindestbetrag aus Entfernungen. 4. suchen Sie den Punkt, der den geringsten Abstand von dem berührten Punkt hat. gibt es eine einfachere und effizientere Art und Weise? ich schätze alle help.Thanks im Voraus.Effizienter Weg, den nächsten Punkt von einer Menge von Punkten zum berührten Punkt zwischen einem Bereich zu finden?

-(void)drawRect:(CGRect)rect{ 
      self.modifiablePath = [UIBezierPath interpolateCGPointsWithCatmullRom:self.pointsArray closed:YES alpha:0.9]; 
      self.modifiablePath.lineWidth = 20.0; 
      [[UIColor yellowColor] setStroke]; 
      [self.modifiablePath stroke]; 
    } 
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 
      { 

     CGPoint touchedPoint = [[touches anyObject]locationInView:self]; 
     CGPoint discoveryPoint; 
     CGFloat tolerance = 20; 
     int numOfPointsWithMinDistance=0; 
     NSDictionary* pointsWithMinDistanceWithKeys = [NSDictionary new]; 
     NSDictionary* minDistancesWithKeys = [NSDictionary new]; 
     // Had to Create these two arrays because there's no such thing as [NSDictionary objectAtIndex:] 
     NSArray *pointsWithMinDistancesArray = [NSArray new]; 
     NSArray *minDistanceArray = [NSArray new]; 

     for (NSValue * cgpointVal in self.pointsArray){ 
      discoveryPoint = cgpointVal.CGPointValue; 

      if (fabs(touchedPoint.x - discoveryPoint.x)<tolerance && fabs(touchedPoint.y - discoveryPoint.y)<tolerance) { 
       numOfPointsWithMinDistance++; 
       //Adding the points which touchedPoint is inside their range(Square). 
       [pointsWithMinDistanceWithKeys setValue:[NSValue valueWithCGPoint:discoveryPoint] forKey:[NSString stringWithFormat:@"%d",numOfPointsWithMinDistance]]; 

       //Calculating the distance between points with touchedPoint in their range(Square) and adding them to an array. 
       CGFloat distance = hypotf(touchedPoint.x - discoveryPoint.x, touchedPoint.y - discoveryPoint.y); 
       [minDistancesWithKeys setValue:[NSNumber numberWithFloat:distance] forKey:[NSString stringWithFormat:@"%d",numOfPointsWithMinDistance]]; 
      } 
     } 
     //Finding the key for minimum distance between all distances to the touchedPoint. 
     minDistanceArray = [minDistancesWithKeys allValues]; 
     pointsWithMinDistancesArray = [pointsWithMinDistanceWithKeys allValues]; 

     CGFloat k = [[minDistanceArray objectAtIndex:0] floatValue]; 
     int keyOfPointWithMinDistance =0; 
     for (unsigned i = 1; i <[minDistanceArray count]; i++){ 

      if([[minDistanceArray objectAtIndex:i] floatValue] < k){ 
       k = [[minDistanceArray objectAtIndex:i] floatValue]; 
       keyOfPointWithMinDistance=i; 
      }else{ 
       keyOfPointWithMinDistance=0; 
      } 
     } 
     //Getting the nearest CGPoint value with the smallest distance to the touchedPoint. 
     NSValue * valueOfNearestPoint =[pointsWithMinDistancesArray objectAtIndex:keyOfPointWithMinDistance]; 
     CGPoint nearestPointToTouchedPoint =valueOfNearestPoint.CGPointValue; 
} 

Antwort

0
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 
    CGPoint touchedPoint = [[touches anyObject]locationInView:self]; 
    CGPoint discoveryPoint; 
    CGFloat tolerance = 20; 
    // Had to Create these two arrays because there's no such thing as [NSDictionary objectAtIndex:] 
    NSArray *pointsArray; 

    CGFloat keyOfPointWithMinDistance = -1; 
    CGPoint nearestPointToTouchedPoint = CGPointZero; 
    Int index = 0; 
    Int keyIndex = NSNotFound; 

    for (NSValue * cgpointVal in self.pointsArray){ 

     discoveryPoint = cgpointVal.CGPointValue; 

     if (fabs(touchedPoint.x - discoveryPoint.x)<tolerance && fabs(touchedPoint.y - discoveryPoint.y)<tolerance) { 
      //Calculating the distance between points with touchedPoint in their range(Square) and adding them to an array. 
      CGFloat distance = hypotf(touchedPoint.x - discoveryPoint.x, touchedPoint.y - discoveryPoint.y); 

      if (keyOfPointWithMinDistance == -1 || keyOfPointWithMinDistance < distance) { 
       keyOfPointWithMinDistance = distance; 
       nearestPointToTouchedPoint = discoveryPoint; 
       keyIndex = index; 
      } 

      index++; 
     } 
    } 

    //Update self.pointsArray using keyIndex 

    if keyIndex != NSNotFound { 

    } 

} 
+1

Es hat funktioniert! Vielen Dank ! –

+0

Eigentlich brauche ich neede d das NSDictionary, um zu wissen, welcher Punkt (welcher einen bestimmten Schlüssel hat) war es im ursprünglichen Array, also kann ich seinen Wert ändern, indem ich es auswähle und verschiebe, aber wie erreiche ich das mit Ihrem Code ohne Verwendung von NSDictionaries? –

+1

Meine Antwort wurde aktualisiert. –

Verwandte Themen