这是检验两条线是否共线的正确方法吗?

Is this the correct way to test to see if two lines are colinear?

本文关键字:方法 检验 两条线 是否      更新时间:2023-10-16

我的代码在共线性中似乎不工作,这让我很沮丧。在点类中使用两个点是使用直线类的最佳方式吗?我的colinearly测试失败了,所以我在过去的几天里一直处于常规状态。

bool line::isColinear(line)
{
     bool line2=false;
     line l1,l2;
     if (l1.slope()==l2.slope())
     {
         if (l1.y_int()==l2.y_int())
         {
             line2 =true;
             return line2;
         }
     }
     else
     { 
         line2 =false;
     }
}

//这是我的行类

的副本
class line
{
    private:
    point p1,p2;
    public:
    bool isColinear(line);
    bool isParallel(line);
    point solve(line);
    double slope();
    double y_int();
    void  Display(ostream&);
};
  1. 您正在存储两点之间的直线。一条线的斜率通常定义为

    slope = (y2 - y1) / ( x2 - x1 )

如果x1等于x2,则可以得到除零错误/异常。

其他注意事项

  1. 如果你把点坐标存储为整数,你可能只做一个整数除法而得不到你想要的
  2. 如果您一直使用双精度,请在比较它们时使用公差

这里没有足够的东西来真正判断出什么是错误的,所以有一些概括:

  • 永远不要直接比较浮点值是否相等。它在很多时候都不会起作用。相反,将它们的差异与一个小到可以称之为"零"(通常我们称之为"epsilon")的量进行比较:

    if (abs((num1 - num2)) < 0.001) {
        /* pretend they're equal */
    } else {
        /* not equal */
    }
    
  • line2在本例中不需要。你也可以直接从结论中返回truefalse。通常,甚至return truereturn false都是不必要的混淆。让我们假设您将这个方法重写为三个方法。(这可能是也可能不是一种进步。只是假设一下。)

    bool line::compare_slope(line l2) {
        return fabs((l2.slope() - self.slope()) < 0.001; // don't hardcode this
    }
    bool line::compare_origin(line l2) {
        return fabs((l2.y_int() - self.y_int()) < 0.001; // nor this
    }
    bool line::is_colinear(line l2) {
        return compare_slope(l2) && compare_origin(l2);
    }
    

    没有任何truefalse硬编码——相反,您依赖于条件的值来计算truefalse。(顺便说一下,这些函数中的重复表明,函数floating_comparison(double f1, double f2, double epsilon)可以使修改epsilon更容易,无论是在项目范围内还是根据所讨论的浮点数的绝对值计算epsilon。)

我的猜测是,由于l1l2是未初始化的,它们的slope方法正在做一个除零。正确地初始化这些或切换到适当的变量,你会修复你的崩溃。

即使你让它工作了,测试也可能失败。你不能比较浮点数并期望它们相等,即使它们看起来应该相等。你应该读一下《每个计算机科学家都应该知道的浮点算术》

一个简单的线条(2D)公式(从这里导出)是:

P1(x1,y1)和P2(x2,y2)是该线的两点。

(y-y1) (x2-x1) + (y1 y2) (x-x1) = 0(我们用f (x, y) = 0)

要测试两条线是否匹配,假设第二条线由点P3(x3,y3), P4(x4,y4)定义。

为了确保这些线条"完全"相同,你应该测试确定第二行的两个点(P3, P4)是否"足够"接近前一行。

这很容易通过计算f(x3,y3)和f(x4,y4)来完成。如果这些值接近于0,那么这两行是相同的。
Pseudocode:
// I would chose tolerance around 1
if ( f(x3,y3) < tolerance && f(x4,y4) < tolerance )
{
    // line P1,P2 is the same as P3,P4
}