簡體   English   中英

查看點是否在直線上(矢量)

[英]See if a point lies on a line(vector)

在此處輸入圖片說明

我的程序中目前有以下行。 我還有另外兩個整數變量, xy

我想看看這個新點(x, y)是否在這條線上。 我一直在看以下線程:

給定起點和終點以及距離,沿直線計算一個點

我想出了以下幾點:

if(x >= x1 && x <= x2 && (y >= y1 && y <= y2 || y <= y1 && y >= y2))
{
    float vx = x2 - x1;
    float vy = y2 - y1;
    float mag = sqrt(vx*vx + vy*vy);
    // need to get the unit vector (direction)
    float dvx = vx/mag; // this would be the unit vector (direction) x for the line
    float dvy = vy/mag; // this would be the unit vector (direction) y for the line

    float vcx = x - x1;
    float vcy = y - y1;
    float magc = sqrt(vcx*vcx + vcy*vcy);
    // need to get the unit vector (direction)
    float dvcx = vcx/magc; // this would be the unit vector (direction) x for the point
    float dvcy = vcy/magc; // this would be the unit vector (direction) y for the point

    // I was thinking of comparing the direction of the two vectors, if they are the same then the point must lie on the line?
    if(dvcx == dvx && dvcy == dvy)
    {
        // the point is on the line!
    }
}

似乎沒有用,還是這個想法不對勁?

浮點數的精度有限,因此您會從計算中得出舍入誤差,結果在數學上應該相等的值最終會略有不同。

您需要比較一個小的容錯度:

if (std::abs(dvcx-dvx) < tolerance && std::abs(dvcy-dvy) < tolerance)
{
    // the point is (more or less) on the line!
}

困難的部分是選擇那個公差。 如果您不能接受任何錯誤,那么您需要使用除固定精度浮點值之外的其他值-可能是整數,並且重新排列計算以避免除法和其他不精確的運算。

無論如何,您可以更簡單地執行此操作,而無需像平方根這樣的東西。 您想找出兩個向量是否平行; 如果向量乘積為零,或者它們具有相等的切線,則等於。 所以你只需要

if (vx * vcy == vy * vcx)  // might still need a tolerance for floating-point
{
    // the point is on the line!
}

如果您的輸入是整數,足夠小以至於乘法不會溢出,那么根本就不需要浮點運算。

解決此問題的有效方法是使用三角形的有符號區域。 當由點{x1,y1}{x2,y2}{x,y}創建的三角形的有符號區域接近零時,可以認為{x,y}在直線上。 正如其他人提到的那樣,如果使用浮點值,則選擇一個好的公差值是其中的重要部分。

bool isPointOnLine (xy p1, xy p2, xy p3) // returns true if p3 is on line p1, p2
    {
    xy va = p1 - p2;
    xy vb = p3 - p2;
    area = va.x * vb.y - va.y * vb.x;
    if (abs (area) < tolerance)
        return true;
    return false;
    }

這將讓您知道{x,y}位於直線上,但不會確定線段是否包含{x,y} 為此,您還需要對照線段的邊界檢查{x,y}

首先,您需要計算直線方程。 然后查看該方程式對您擁有的x和y的值是否成立。 要計算您的直線方程,您需要計算出它在y軸上的位置以及其梯度是多少。 該方程的形式為y = mx + c,其中m為梯度,c為“截距”(其中線與y軸交叉)。

對於浮點值,請不要使用==,而應測試微小差異:

if (fabs(dvcx-dvx) < delta && fabs(dvcy-dvy) < delta)

另外,您實際上並不需要單位向量,僅需要切線:

float originalTangent = (y2 - y1) / (x2 - x1);
float newTangent = (y - y1) / (x - x1);
if (fabs(newTangent - originalTangent) < delta) { ... }

增量應為小數,具體取決於您期望的精度。)

鑒於(x,y)實際上是一個要點,這項工作似乎比您要完成的要簡單一些。

您可能首先要檢查一條完美的水平或垂直線。 在那種情況下,您只需檢查x是否落在x1x2之間(或y在垂直方向上在y1y2之間)。

否則,您可以在x上使用線性插值,看看它是否為y提供了正確的值(在一些可能的舍入公差范圍內)。 為此,您可以執行以下操作:

slope = (y2-y1)/(x2-x1);
if (abs(slope * (x - x1) - y) < tolerance)
    // (x,y) is on the line
else
    // (x,y) isn't on the line

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM