3 个点在 2d 中共线

发布于 2024-10-18 02:51:49 字数 519 浏览 6 评论 0原文

我试图验证 3 个点(双)何时在二维中共线。我已经找到了 如果经过验证,则返回 true 的不同 Pascal 函数;这些函数使用整数来指定 X 和 Y 坐标。我需要更精确的计算 至少到X和Y表示的小数部分前3位 作为双类型。谁能帮我解决这个问题?

我发现了这个函数:

function Collinear(x1, y1, x2, y2, x3, y3: Double): Boolean;
begin
  Result := (((x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1)) = 0);
end;

但我猜计算永远不会是0。我应该使用类似的东西吗?

function Collinear(x1, y1, x2, y2, x3, y3: Double): Boolean;
begin
  Result := (((x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1)) < 0.01);
end;

I am trying to verify when 3 points (double) are collinear in 2-D. I have found
different Pascal functions that return true if this is verified; those functions use integer to specify X and Y coordinates. I need a more precise calculation
at least to the first 3 digits of the decimal part of X and Y expressed
as double type. Who can help me with this?

I found this function:

function Collinear(x1, y1, x2, y2, x3, y3: Double): Boolean;
begin
  Result := (((x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1)) = 0);
end;

But I guess the calculation would never be 0. Should I use something like that?

function Collinear(x1, y1, x2, y2, x3, y3: Double): Boolean;
begin
  Result := (((x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1)) < 0.01);
end;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甲如呢乙后呢 2024-10-25 02:51:49

当且仅当三个点共线时,您计算的标量积方程为零。但是,在有限精度机器上,您不想测试是否等于零,而是测试零到某个小容差。

由于方程可能为负数,也可能为正数,因此您的测试将不起作用。当方程计算结果为大负值时,它将返回误报。因此,您需要测试绝对值是否很小:

function Collinear(const x1, y1, x2, y2, x3, y3: Double): Boolean;
const
  tolerance = 0.01;//need a rationale for this magic number
begin
  Result := abs((x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1)) < tolerance;
end;

具体如何选择容差取决于您未提供的信息。价值观从何而来?它们是立体的吗?

The scalar product equation you calculate is zero if and only if the three points are co-linear. However, on a finite precision machine you don't want to test for equality to zero but instead you test for zero up to some small tolerance.

Since the equation can be negative as well as positive your test isn't going to work. It will return false positives when the equation evaluates to a large negative value. Thus you need to test that the absolute value is small:

function Collinear(const x1, y1, x2, y2, x3, y3: Double): Boolean;
const
  tolerance = 0.01;//need a rationale for this magic number
begin
  Result := abs((x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1)) < tolerance;
end;

Exactly how to choose tolerance depends on information you haven't provided. Where do the values come from? Are they dimensional?

苄①跕圉湢 2024-10-25 02:51:49

David 的代码可以工作,但您应该获得作为参数函数的容差,如下所示:

function Collinear(const x1, y1, x2, y2, x3, y3: Double): Boolean; inline;   
var  
  tolerance: double;  
begin  
  tolerance := abs(max(x1,x2,x3,y1,y2,y3)) * 0.000001;  
  Result := abs((x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1)) < tolerance;  
end;  

如果您不这样做并使用常量,则可能会遇到 x1..y3 值较大的奇怪错误。

David's code will work, but you should get the tolerance as a function of the parameters, like so:

function Collinear(const x1, y1, x2, y2, x3, y3: Double): Boolean; inline;   
var  
  tolerance: double;  
begin  
  tolerance := abs(max(x1,x2,x3,y1,y2,y3)) * 0.000001;  
  Result := abs((x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1)) < tolerance;  
end;  

If you don't do that and use a constant instead you can run into weird errors with large values for x1..y3.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文