gpt4 book ai didi

iphone - 寻找离CGPoint最近的物体

转载 作者:行者123 更新时间:2023-12-03 18:29:24 25 4
gpt4 key购买 nike

我在 UIScrollView 上有四个 UIView(屏幕分为四分位数)

在四分位数上,每个四分位数上都有一些对象(UIImageViews)。

当用户点击屏幕时,我想找到距离给定CGPoint最近的对象?

有什么想法吗?

我有每个四分位数内对象的 CGPoint 和框架 (CGRect)。

更新:

hRuler
(来源:skitch.com)

红色图钉是 UIImageView。
    // UIScrollView
NSLog(@" UIScrollView: %@", self);

// Here's the tap on the Window in UIScrollView's coordinates
NSLog(@"TapPoint: %3.2f, %3.2f", tapLocation.x, tapLocation.y);

// Find Distance between tap and objects
NSArray *arrayOfCGRrectObjects = [self subviews];
NSEnumerator *enumerator = [arrayOfCGRrectObjects objectEnumerator];

for (UIView *tilesOnScrollView in enumerator) {

// each tile may have 0 or more images
for ( UIView *subview in tilesOnScrollView.subviews ) {

// Is this an UIImageView?
if ( [NSStringFromClass([subview class]) isEqualToString:@"UIImageView"]) {

// Yes, here are the UIImageView details (subView)
NSLog(@"%@", subview);

// Convert CGPoint of UIImageView to CGPoint of UIScrollView for comparison...
// First, Convert CGPoint from UIScrollView to UIImageView's coordinate system for reference
CGPoint found = [subview convertPoint:tapLocation fromView:self];
NSLog(@"Converted Point from ScrollView: %3.2f, %3.2f", found.x, found.y);

// Second, Convert CGPoint from UIScrollView to Window's coordinate system for reference
found = [subview convertPoint:subview.frame.origin toView:nil];
NSLog(@"Converted Point in Window: %3.2f, %3.2f", found.x, found.y);

// Finally, use the object's CGPoint in UIScrollView's coordinates for comparison
found = [subview convertPoint:subview.frame.origin toView:self]; // self is UIScrollView (see above)
NSLog(@"Converted Point: %3.2f, %3.2f", found.x, found.y);

// Determine tap CGPoint in UIImageView's coordinate system
CGPoint localPoint = [touch locationInView:subview];
NSLog(@"LocateInView: %3.2f, %3.2f",localPoint.x, localPoint.y );

//Kalle's code
CGRect newRect = CGRectMake(found.x, found.y, 32, 39);
NSLog(@"Kalle's Distance: %3.2f",[self distanceBetweenRect:newRect andPoint:tapLocation]);

}

调试控制台

问题就在这里。每个图 block 的尺寸为 256x256。第一个UIImageView的CGPoint转换为UIScrollView 的坐标系 (53.25, 399.36) 应该与 tapPoint (30,331) 完全一致。为什么有区别??点击点右侧的另一个点正在计算较近(距离方面)??

<CALayer: 0x706a690>>
[207] TapPoint: 30.00, 331.00
[207] <UIImageView: 0x7073db0; frame = (26.624 71.68; 32 39); opaque = NO; userInteractionEnabled = NO; tag = 55; layer = <CALayer: 0x70747d0>>
[207] Converted Point from ScrollView: 3.38, 3.32
[207] Converted Point in Window: 53.25, 463.36
[207] Converted Point: 53.25, 399.36 *** Looks way off!
[207] LocateInView: 3.38, 3.32
[207] Kalle's Distance: 72.20 **** THIS IS THE TAPPED POINT
[207] <UIImageView: 0x7074fb0; frame = (41.984 43.008; 32 39); opaque = NO; userInteractionEnabled = NO; tag = 55; layer = <CALayer: 0x7074fe0>>
[207] Converted Point from ScrollView: -11.98, 31.99
[207] Converted Point in Window: 83.97, 406.02
[207] Converted Point: 83.97, 342.02
[207] LocateInView: -11.98, 31.99
207] Kalle's Distance: 55.08 ***** BUT THIS ONE's CLOSER??????

最佳答案

下面的方法应该可以解决问题。如果您发现其中有任何奇怪的地方,请随时指出。

- (CGFloat)distanceBetweenRect:(CGRect)rect andPoint:(CGPoint)point
{
// first of all, we check if point is inside rect. If it is, distance is zero
if (CGRectContainsPoint(rect, point)) return 0.f;

// next we see which point in rect is closest to point
CGPoint closest = rect.origin;
if (rect.origin.x + rect.size.width < point.x)
closest.x += rect.size.width; // point is far right of us
else if (point.x > rect.origin.x)
closest.x = point.x; // point above or below us
if (rect.origin.y + rect.size.height < point.y)
closest.y += rect.size.height; // point is far below us
else if (point.y > rect.origin.y)
closest.y = point.y; // point is straight left or right

// we've got a closest point; now pythagorean theorem
// distance^2 = [closest.x,y - closest.x,point.y]^2 + [closest.x,point.y - point.x,y]^2
// i.e. [closest.y-point.y]^2 + [closest.x-point.x]^2
CGFloat a = powf(closest.y-point.y, 2.f);
CGFloat b = powf(closest.x-point.x, 2.f);
return sqrtf(a + b);
}

示例输出:

CGPoint p = CGPointMake(12,12);

CGRect a = CGRectMake(5,5,10,10);
CGRect b = CGRectMake(13,11,10,10);
CGRect c = CGRectMake(50,1,10,10);
NSLog(@"distance p->a: %f", [self distanceBetweenRect:a andPoint:p]);
// 2010-08-24 13:36:39.506 app[4388:207] distance p->a: 0.000000
NSLog(@"distance p->b: %f", [self distanceBetweenRect:b andPoint:p]);
// 2010-08-24 13:38:03.149 app[4388:207] distance p->b: 1.000000
NSLog(@"distance p->c: %f", [self distanceBetweenRect:c andPoint:p]);
// 2010-08-24 13:39:52.148 app[4388:207] distance p->c: 38.013157

可能有更优化的版本,因此可能值得深入挖掘。

以下方法确定两个 CGPoint 之间的距离。

- (CGFloat)distanceBetweenPoint:(CGPoint)a andPoint:(CGPoint)b
{
CGFloat a2 = powf(a.x-b.x, 2.f);
CGFloat b2 = powf(a.y-b.y, 2.f);
return sqrtf(a2 + b2)
}

更新:删除了 fabsf(); -x^2 与 x^2 相同,因此不需要。

更新 2:为了完整性,还添加了 distanceBetweenPoint:andPoint: 方法。

关于iphone - 寻找离CGPoint最近的物体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3552108/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com