Find distance between 2D point and line segment start point.

huangapple go评论67阅读模式
英文:

Find distance between 2D point and line segment start point

问题

这似乎是一个简单的问题,但我在代数方面不擅长。

我正在尝试找到点与沿着线段的角度平行的线段起点之间的距离。我将使用这个距离来插值沿着该线的一个值。

我还需要知道点在线的外部时的情况。

这是我的代码尝试,使用了three.js的Vector2D,但它的行为不如预期。

const lineStartOrig = lineStart.clone()

const lineLength = lineStart.distanceTo(lineEnd)

const dotDiff = point2D.sub(lineStart).dot(lineEnd) / lineEnd.dot(lineEnd)

const pointIntersect = dummyLineStart.add(lineEnd)
                                     .multiplyScalar(dotDiff)
                                     .clamp(lineStartOrig, lineEnd)

const value = pointIntersect.distanceTo(lineStartOrig) / lineLength
英文:

This feels like a simple problem but I am bad at algebra.

Find distance between 2D point and line segment start point.

I'm trying to find the distance between a point and the start of a line segment at an angle parallel to the segment. I will use the distance to interpolate a value along the line.

I also need to know when the points are outside of the line.

A code example would be appreciated, this is my attempt so far using threejs Vector2D but it isn't behaving as expected.

const lineStartOrig = lineStart.clone()

const lineLength = lineStart.distanceTo(lineEnd)

const dotDiff = point2D.sub(lineStart).dot(lineEnd) / lineEnd.dot(lineEnd)


const pointIntersect = dummyLineStart.add(lineEnd)
                                     .multiplyScalar(dotDiff)
                                     .clamp(lineStartOrig, lineEnd)

const value = pointIntersect.distanceTo(lineStartOrig) / lineLength

答案1

得分: 1

以下是要翻译的代码部分:

要计算两个向量和一个测试点C之间的角度:

float calcAngle(QVector2D& A, QVector2D& B, QVector2D& C)
{
    QVector2D v1 = B - A;
    QVector2D v2 = C - A;
    float v1DotV2 = QVector2D::dotProduct(v1, v2);
    float magV1TimesMagV2 = v1.length()* v2.length();
    float cosTheta = v1DotV2/magV1TimesMagV2;
    float theta = qRadiansToDegrees(acosf(cosTheta));
    qInfo() << "Theta " << theta;

    return theta;
}

要获取距离和交点,这是我认为楼主在寻找的:

float calcDistAlongParallelLineAndIntersectPoint(const QVector2D& A, const QVector2D& B, const QVector2D& C, QVector2D& intersectPoint)
{
    QVector2D v1 = B - A;
    QVector2D v2 = C - A;
    float v1DotV2 = QVector2D::dotProduct(v1, v2);
    float magV1TimesMagV2 = v1.length()* v2.length();
    float cosTheta = v1DotV2/magV1TimesMagV2;
    float dist = v2.length() * cosTheta;

    QVector2D intersectingPoint = C - v1*(dist/v1.length());
    intersectPoint.setX(intersectingPoint.x());
    intersectPoint.setY(intersectingPoint.y());
    return dist;
}

对于一些随机点的简单检查如下:

Find distance between 2D point and line segment start point.

英文:

In case it's useful to anyone, I used the following functions (unfortunately not in .js, but should illustrate the idea)

To calc angle between two vectors and a test point C:

float calcAngle(QVector2D&amp; A, QVector2D&amp; B, QVector2D&amp; C)
{
    QVector2D v1 = B - A;
    QVector2D v2 = C - A;
    float v1DotV2 = QVector2D::dotProduct(v1, v2);
    float magV1TimesMagV2 = v1.length()* v2.length();
    float cosTheta = v1DotV2/magV1TimesMagV2;
    float theta = qRadiansToDegrees(acosf(cosTheta));
    qInfo() &lt;&lt; &quot;Theta &quot; &lt;&lt; theta;

    return theta;
}

To get the distance and intersect point which I think the OP is after:

float calcDistAlongParallelLineAndIntersectPoint(const QVector2D&amp; A, const QVector2D&amp; B, const QVector2D&amp; C, QVector2D&amp; intersectPoint)
{
    QVector2D v1 = B - A;
    QVector2D v2 = C - A;
    float v1DotV2 = QVector2D::dotProduct(v1, v2);
    float magV1TimesMagV2 = v1.length()* v2.length();
    float cosTheta = v1DotV2/magV1TimesMagV2;
    float dist = v2.length() * cosTheta;

    QVector2D intersectingPoint = C - v1*(dist/v1.length());
    intersectPoint.setX(intersectingPoint.x());
    intersectPoint.setY(intersectingPoint.y());
    return dist;
}

A little check for some random points gives:
Find distance between 2D point and line segment start point.

答案2

得分: 0

我采用了稍微不同的方法,但Gremto的答案帮助了很多,并正确回答了问题,所以我将其标记为解决方案。

我使用了一个渐变函数来解决这个问题,我在这里找到了它:https://www.shadertoy.com/view/lscGDr

这是GLSL的版本,但这里是我使用three.js的Vector2的ts版本:

interface Line2D {
    x1: number,
    x2: number,
    y1: number,
    y2: number
}  

const dummyLineStart = new Vector2(0, 0)
const dummyLineEnd = new Vector2(0, 0)
const dummyPoint = new Vector2(0, 0)
const dummyLineEndTranslated = new Vector2(0, 0)

// 提供一个在0和1之间的插值值,取决于点相对于一条线的平行位置

// 在线的起始点之前的点将返回1
function interpolatePointValueAlongLine(
    line: Line2D,
    pointX: number,
    pointY: number
) {

    // 使用可重用的向量以防止在每次调用时重新初始化类
    dummyLineStart.set(line.x1, line.y1)
    dummyLineEnd.set(line.x2, line.y2)
    dummyPoint.set(pointX, pointY)

    // 代码来自:https://www.shadertoy.com/view/lscGDr
    dummyLineEndTranslated.set(line.x2, line.y2)
                          .sub(dummyLineStart)

    return dummyPoint.sub(dummyLineStart)
                     .dot(dummyLineEndTranslated) / 
    dummyLineEndTranslated.dot(dummyLineEndTranslated)
}
英文:

I went in a slightly different direction but Gremto's answer helped a lot and correctly answered the question so I'm marking that as the solution.

I solved the problem using a gradient function that I found here: https://www.shadertoy.com/view/lscGDr

It's in GLSL but here's my ts version using three.js's Vector2

interface Line2D {
    x1: number,
    x2: number,
    y1: number,
    y2: number
}  

const dummyLineStart = new Vector2(0, 0)
const dummyLineEnd = new Vector2(0, 0)
const dummyPoint = new Vector2(0, 0)
const dummyLineEndTranslated = new Vector2(0, 0)

//provides an interpolation value between 0 and 1 for a point depending on its 
relative parallel position to a line

//points before the start of the line will return 1
function interpolatePointValueAlongLine(
    line: Line2D,
    pointX: number,
    pointY: number
) {

    //use reusable vecs to prevent reinitialising class every call
    dummyLineStart.set(line.x1, line.y1)
    dummyLineEnd.set(line.x2, line.y2)
    dummyPoint.set(pointX, pointY)

    //code from: https://www.shadertoy.com/view/lscGDr
    dummyLineEndTranslated.set(line.x2, line.y2)
                          .sub(dummyLineStart)

    return dummyPoint.sub(dummyLineStart)
                     .dot(dummyLineEndTranslated) / 
    dummyLineEndTranslated.dot(dummyLineEndTranslated)
}

huangapple
  • 本文由 发表于 2023年6月6日 05:50:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76410220.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定