有效的方法是从一组点到一个范围之间的触摸点找到最近点?

时间:2016-09-02 00:51:54

标签: ios objective-c xcode uibezierpath cgpoint

我有一个CGPoints数组,用于使用CGPoint interpolation by jnfisher绘制Catmull-Rom bezierpath我想要的是当用户触摸任何一个范围内的任何地方时,选择触摸点路径上的最近点指向路径。该范围被指定为一个虚构的正方形,其中包含路径上的点,沿着X和Y轴在路径上的每个点之前和之后具有公差。我的策略是1.为路径上的每个点设置一个公差,观察触摸的位置是否在X轴上的这些边的正方形内:( discoveryPoint.x - 对discoveryPoint.x +容差的容忍度)和Y axis :( discoveryPoint.y - 对discoveryPoint.y +容差的容差.2。计算触摸点与数组中包含其方块内触摸点的所有点之间的距离.3。从距离中选择最小量。 4.找到与触摸点距离最小的点。是否有更简单,更有效的方法?我非常感谢任何帮助。谢谢。

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

1 个答案:

答案 0 :(得分:0)

#!/usr/bin/perl -w

use strict;

chomp(my $text    = <STDIN>);
chomp(my $regex   = <STDIN>);
chomp(my $replace = <STDIN>);

$replace = '"' . $replace . '"';   # creating the string as '"\u\L$1\E Flintstone"'

$text = ~s/$regex/$replace/gee; # applying double evaluation

print $text,"\n";