从一组点到范围内的触摸点找到最近点的有效方法?
Efficient way to find the nearest point from a set of points to the touched point inbetween a range?
我有一个 CGPoints 数组,用于使用 CGPoint interpolation by jnfisher 绘制 Catmull-Rom bezierpath 我想要的是当用户触摸范围内的任何地方时选择路径上最近的点到触摸点围绕路径上的任何点。该范围被指定为一个假想的正方形,其中包含路径上的点,路径上沿 X 和 Y 轴的每个点前后都有公差。我的策略是 1. 为路径上的每个点设置一个公差,该公差将观察触摸位置是否在 X 轴上这些边的正方形内部:(discoveryPoint.x - 公差到 discoveryPoint.x + 公差) 和在 Y 轴上:(discoveryPoint.y - 公差到 discoveryPoint.y + 公差。2.Calculate 触摸点与我的数组中包含触摸点的所有点之间的距离. 3. 从距离中选择最小量。 4. 找到与触摸点距离最小的点。有没有更简单更有效的方法?我非常感谢任何提前help.Thanks。
-(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;
}
- (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 {
}
}
我有一个 CGPoints 数组,用于使用 CGPoint interpolation by jnfisher 绘制 Catmull-Rom bezierpath 我想要的是当用户触摸范围内的任何地方时选择路径上最近的点到触摸点围绕路径上的任何点。该范围被指定为一个假想的正方形,其中包含路径上的点,路径上沿 X 和 Y 轴的每个点前后都有公差。我的策略是 1. 为路径上的每个点设置一个公差,该公差将观察触摸位置是否在 X 轴上这些边的正方形内部:(discoveryPoint.x - 公差到 discoveryPoint.x + 公差) 和在 Y 轴上:(discoveryPoint.y - 公差到 discoveryPoint.y + 公差。2.Calculate 触摸点与我的数组中包含触摸点的所有点之间的距离. 3. 从距离中选择最小量。 4. 找到与触摸点距离最小的点。有没有更简单更有效的方法?我非常感谢任何提前help.Thanks。
-(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;
}
- (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 {
}
}