简体   繁体   English

线段中的等距点

[英]Equidistant points in a line segment

Let assume you have two points (a , b) in a two dimensional plane. 假设您在二维平面中有两个点(a,b)。 Given the two points, what is the best way to find the maximum points on the line segment that are equidistant from each point closest to it with a minimal distant apart. 给定两个点,最好的方法是找到线段上的最大点,这些点与距离它最近的每个点等距且相距最小。

I use C#, but examples in any language would be helpful. 我使用C#,但是使用任何语言的示例都会有所帮助。

List<'points> FindAllPointsInLine(Point start, Point end, int minDistantApart)  
{  
//    find all points  
}

Interpreting the question as: 将问题解释为:

  • Between point start start之间
  • And point end end
  • What is the maximum number of points inbetween spaced evenly that are at least minDistanceApart 间隔至少等于minDistanceApart的点之间的最大数目是多少

Then, that is fairly simply: the length between start and end divided by minDistanceApart , rounded down minus 1. (without the minus 1 you end up with the number of distances between the end points rather than the number of extra points inbetween) 然后,这非常简单: startend之间的长度除以minDistanceApart ,然后四舍五入后减去1。(如果没有负1,则最终得出的是端点之间的距离数,而不是端点之间的额外点数)

Implementation: 实现方式:

List<Point> FindAllPoints(Point start, Point end, int minDistance)
{
    double dx = end.x - start.x;
    double dy = end.y - start.y;

    int numPoints =
        Math.Floor(Math.Sqrt(dx * dx + dy * dy) / (double) minDistance) - 1;

    List<Point> result = new List<Point>;

    double stepx = dx / numPoints;
    double stepy = dy / numPoints;
    double px = start.x + stepx;
    double py = start.y + stepy;
    for (int ix = 0; ix < numPoints; ix++)
    {
        result.Add(new Point(px, py));
        px += stepx;
        py += stepy;
    }

    return result;
}

If you want all the points, including the start and end point, then you'll have to adjust the for loop, and start 'px' and 'py' at 'start.x' and 'start.y' instead. 如果需要所有点,包括起点和终点,则必须调整for循环,并在“ start.x”和“ start.y”处分别启动“ px”和“ py”。 Note that if accuracy of the end-points is vital you may want to perform a calculation of 'px' and 'py' directly based on the ratio 'ix / numPoints' instead. 请注意,如果端点的准确性至关重要,则可能需要直接基于比率“ ix / numPoints”执行“ px”和“ py”的计算。

I'm not sure if I understand your question, but are you trying to divide a line segment like this? 我不确定我是否理解您的问题,但是您是否要像这样划分线段?

Before: 之前:

A +--------------------+ B A + -------------------- + B

After: 后:

A +--|--|--|--|--|--|--+ B A +-|-|-||||-|-|-++ B

Where "two dashes" is your minimum distance? 您的最小距离是“两个破折号”吗? If so, then there'll be infinitely many sets of points that satisfy that, unless your minimum distance can exactly divide the length of the segment. 如果是这样,那么将有无数的点集可以满足此要求,除非您的最小距离可以精确地划分线段的长度。 However, one such set can be obtained as follows: 但是,可以按以下方式获得这样的一组:

  1. Find the vectorial parametric equation of the line 查找直线的矢量参数方程
  2. Find the total number of points (floor(length / minDistance) + 1) 找到总点数(地板(长度/最小距离)+1)
  3. Loop i from 0 to n, finding each point along the line (if your parametric equation takes at from 0 to 1, t = ((float)i)/n) 将i从0循环到n,找到沿线的每个点(如果参数方程取0到1,则t =((float)i)/ n)

[EDIT] After seeing jerryjvl's reply, I think that the code you want is something like this: (doing this in Java-ish) [编辑]看到jerryjvl的回复后,我认为您想要的代码是这样的:(使用Java-ish进行此操作)

List<Point> FindAllPointsInLine(Point start, Point end, float distance)
{
    float length = Math.hypot(start.x - end.x, start.y - end.y);
    int n = (int)Math.floor(length / distance);
    List<Point> result = new ArrayList<Point>(n);

    for (int i=0; i<=n; i++) {  // Note that I use <=, not <
        float t = ((float)i)/n;
        result.add(interpolate(start, end, t));
    }

    return result;
}

Point interpolate(Point a, Point b, float t)
{
    float u = 1-t;
    float x = a.x*u + b.x*t;
    float y = a.y*u + b.y*t;
    return new Point(x,y);
}

[Warning: code has not been tested] [警告:代码尚未经过测试]

Find the number of points that will fit on the line. 找到适合该线的点数。 Calculate the steps for X and Y coordinates and generate the points. 计算X和Y坐标的步骤并生成点。 Like so: 像这样:

lineLength = sqrt(pow(end.X - start.X,2) + pow(end.Y - start.Y, 2))
numberOfPoints = floor(lineLength/minDistantApart)
stepX = (end.X - start.X)/numberOfPoints
stepY = (end.Y - start.Y)/numberOfPoints
for (i = 1; i < numberOfPoints; i++) {
    yield Point(start.X + stepX*i, start.Y + stepY*i)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM