【问题标题】:Equidistant points in a line segment线段中的等距点
【发布时间】:2023-03-28 09:55:01
【问题描述】:

假设您在二维平面上有两个点 (a , b)。给定这两个点,找到线段上与最接近它的每个点等距且距离最小的最大点的最佳方法是什么。

我使用 C#,但任何语言的示例都会有所帮助。

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

【问题讨论】:

    标签: algorithm geometry distance


    【解决方案1】:

    我不确定我是否理解你的问题,但你是想这样划分线段吗?

    之前:

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

    之后:

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

    “两个破折号”是您的最短距离吗?如果是这样,那么将有无限多的点集满足这一点,除非您的最小距离可以精确地划分线段的长度。但是,可以通过以下方式获得这样的一组:

    1. 求直线的矢量参数方程
    2. 求总点数(floor(length / minDistance) + 1)
    3. 从 0 到 n 循环 i,查找沿线的每个点(如果您的参数方程将 t 从 0 到 1,则 t = ((float)i)/n)

    [编辑] 看到j​​erryjvl的回复后,我觉得你想要的代码是这样的:(用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);
    }
    

    [警告:代码未经测试]

    【讨论】:

      【解决方案2】:

      将问题解释为:

      • start之间
      • 然后点end
      • 至少在minDistanceApart 之间均匀间隔的最大点数是多少?

      那么,这很简单:startend 之间的长度除以 minDistanceApart,向下舍入负 1。(没有负 1,您最终得到的是端点之间的距离数,而不是之间的加分数)

      实施:

      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;
      }
      

      如果你想要所有的点,包括起点和终点,那么你必须调整 for 循环,并在 'start.x' 和 'start.y' 处开始 'px' 和 'py' .请注意,如果端点的准确性至关重要,您可能希望直接根据比率 'ix / numPoints' 执行 'px' 和 'py' 的计算。

      【讨论】:

      • 鉴于他的原型,他想要一个点列表,但我认为您对如何将它们分开的解释是正确的。
      【解决方案3】:

      找出适合线上的点数。计算 X 和 Y 坐标的步长并生成点。像这样:

      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)
      }
      

      【讨论】:

        猜你喜欢
        • 2012-01-20
        • 1970-01-01
        • 1970-01-01
        • 2015-10-11
        • 2010-10-25
        • 2021-11-05
        • 2019-01-01
        • 1970-01-01
        • 2018-01-17
        相关资源
        最近更新 更多