寻找点接近线和线的端点之间

时间:2012-10-16 20:21:32

标签: objective-c xcode algorithm line point

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

-(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 个答案:

答案 0 :(得分: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提供了这个,但如果不是,它只是基本的三角函数。

答案 1 :(得分: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;

答案 2 :(得分: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));
}

答案 3 :(得分:1)

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

现在当角度接近90度时,切线的幅度会迅速增加,直到达到90度时的无限远。在90度时,x坐标的差值为零,你最终会得到一个被零除错误,而不是加入0.00001常数来避免它。虽然90附近的两条切线之间的相对差异可能很小,但即使非常接近的角度,绝对差异也很大,因此< 0.5测试失败。

所以你需要另一种方法。一种是计算从点到两个端点的距离,以及线本身的长度,并进行比较 - 如果距离点的两个距离的总和大于线的长度,则三个点形成三角形如果不是,它们是共线的。 (如果总和少了,你就会陷入另一个维度......)。

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