4

要查找该点是否在包含两个点的指定线上,我进行以下检查:

-(Boolean)isOnLine:(Line*) line point:(CGPoint) point{
    //If between two dots:
    if (((line.first.x <= point.x && point.x <= line.last.x)||(line.first.x >= point.x && point.x >= line.last.x))&&((line.first.y<=point.y && point.y<= line.last.y)||(line.first.y>=point.y && point.y>=line.last.y)) ) {    
        //Calculate distance:
        double dist = (((double)point.y - line.first.y)) / (0.00001+((double)(point.x - line.first.x)))- ((double)(line.last.y - line.first.y)) / (0.00001+((double)(line.last.x - line.first.x)));
        NSLog(@"Dist to line: %f", fabs(dist));
        return fabs(dist) <0.5;
    }else
        return NO;  
    }
}

然而,不知何故,该功能不适用于垂直线。我的猜测是 if 子句在某种意义上是无效的。

4

4 回答 4

2

我没有仔细阅读你的代码,所以我不完全确定你在做什么,但是做这个操作最简单的方法是找到线的一端到点的距离,找到另一端的距离线的末端到点,然后添加这些距离并与线的长度进行比较。

就像是:

Boolean isOnLine(line, point) {
  var dist1 = dist(line.first, point)
  var dist2 = dist(line.last, point)
  return abs(line.length - (dist1 + dist2)) < .5
}

对于 dist() 函数,我猜 CoreGraphics 提供了它,但如果不是,它只是基本的三角函数。

于 2012-10-16T20:28:49.983 回答
2

@jhocking 解决方案的另一个(我的)实现:

- (BOOL)isPoint:(CGPoint)origin nearToLineSegmentPointA:(CGPoint)pointA pointB:(CGPoint)pointB withMarginOfError:(CGFloat)marginOfError {
    CGFloat distanceAP = [self distanceBetweenPointA:origin pointB:pointA];
    CGFloat distanceBP = [self distanceBetweenPointA:origin pointB:pointB];
    CGFloat distanceAB = [self distanceBetweenPointA:pointA pointB:pointB];

    if (fabsf(distanceAB - distanceAP - distanceBP) < marginOfError) {
        return YES;
    } else {
        return NO;
    }
}

- (CGFloat)distanceBetweenPointA:(CGPoint)pointA pointB:(CGPoint)pointB {
    return sqrtf(powf((pointA.x - pointB.x), 2.f) + powf((pointA.y - pointB.y), 2.f));
}
于 2015-01-20T17:55:21.277 回答
2

这是我对 jhockings 解决方案的实现

    return abs([line length] -
    (sqrt((line.first.x - point.x)*(line.first.x - point.x)
    + (line.first.y - point.y)*(line.first.y - point.y))
    + sqrt((line.last.x - point.x)*(line.last.x - point.x)
    + (line.last.y - point.y)*(line.last.y - point.y)))) < .5;
于 2012-10-23T22:32:04.177 回答
1

为什么它不起作用的解释是您正在比较两个三角形的角度的切线- 尽管有注释和变量名称,但您根本没有计算距离。

现在,随着角度接近 90 度,切线的大小迅速增加,直到它本身在 90 度处达到无穷大。在 90 度时,x 坐标的差异为零,您最终会遇到被零除的错误,而不是添加0.00001常数来避免它。虽然 90 附近的两条切线之间的相对差异可能很小,但即使角度非常接近,绝对< 0.5差异也可能很大,因此您的测试失败。

所以你需要另一种方法。一种是计算点到两个端点的距离,以及线本身的长度,然后比较——如果到点的两个距离之和大于线的长度,则三个点形成一个三角形,如果不是,它们是共线的。(如果总和更小,你就滑入了另一个维度……)。

您可以使用毕达哥拉斯计算线条的长度:sqrt((x1 - x2)^2 + (y1 - y2)^2)。

于 2012-10-16T20:50:36.650 回答