Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/jenkins/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在给定一组点之间有线段的情况下查找等间距点_C++_Algorithm - Fatal编程技术网

C++ 在给定一组点之间有线段的情况下查找等间距点

C++ 在给定一组点之间有线段的情况下查找等间距点,c++,algorithm,C++,Algorithm,我目前正在编制一张地图,并试图将街道分割成相等的部分。如果一条街道是直的,只需将街道的长度除以你想要的因子即可。然而,弯曲的街道很难分成相等的部分,因为它们由多个部分组成。我想做的是找出一种方法,把一段街道分成相等的点,不管它有多弯曲,或者每条街道有多长。我试着对曲线进行参数化以使其起作用,但仍然不起作用。要了解我所说的参数化是什么意思,请查看 目前,这就是我目前实施它的方式 //street_seg_length is length of the ith street segm

我目前正在编制一张地图,并试图将街道分割成相等的部分。如果一条街道是直的,只需将街道的长度除以你想要的因子即可。然而,弯曲的街道很难分成相等的部分,因为它们由多个部分组成。我想做的是找出一种方法,把一段街道分成相等的点,不管它有多弯曲,或者每条街道有多长。我试着对曲线进行参数化以使其起作用,但仍然不起作用。要了解我所说的参数化是什么意思,请查看

目前,这就是我目前实施它的方式

        //street_seg_length is length of the ith street segment
        for (double j = 0.0; j < street_seg_length[i]; j+=inc) { 
        
        double rem = j - int(j);
        //A street segment can be split up into multiple curve points. 
        //The more curve points, the curvier a road is
        LatLon from = curve_points_pos[i][int(j)];
        LatLon to = curve_points_pos[i][int(j)+1];
        //Returns cartesian coordinates from latitude and longitude of nth and n+1th curve point
        double x1 = x_from_lon(from.longitude());
        double y1 = y_from_lat(from.latitude());
        double x2 = x_from_lon(to.longitude());
        double y2 = y_from_lat(to.latitude());
        //arrowX, arrowY are supposed to be the coordinates of a point between 2 curve points
        double arrowX = (1 - rem)*x1 + rem*x2;
        double arrowY = (1 - rem) * y1 + rem * y2;
        
         
         
        }
        
    }
//street\u seg\u length是第i个街道段的长度
对于(双j=0.0;j
rem是上面文章中讨论的余数,j是上面文章中与t相同的值,p是第n点,q是上面文章中讨论的第n+1点


有人能解释一下我能做些什么来实现这个目标,或者我做错了什么吗?我想找到一条街道上的等距点,不管它有多弯曲。我是否正确地遵循了链接帖子中的算法?我相信我是对的,但很明显,算法是错误的,或者我没有正确地实现它,后者更可能发生。

结果路径
+
将具有等距点,但原始路径
o
具有不同长度的段。您需要处理两件不同的事情:

  • 当前段的起点和终点的索引
    curr
    next
    ,以及
  • 该段的插值变量
    t
以下是
curr/next
值的示例:

o    +        0 / 1       t = 0.0
|    |
|    +        0 / 1       t = 0.667
o    |
|    +        1 / 2       t = 0.2
|    |
|    +        1 / 2       t = 0.6
|    |
o    +        1 / 2       t = 1.0
所以你的算法是这样的:

  • 找出总的和累积的段长度
  • curr=0
    next=1
    开始
  • 在n个等距点上循环:
    • 确定该点的总运行长度
      z
    • 调整
      curr
      next
      ,使
      curr≤ Z≤ 下一步
    • 确定
      t
      并插值
下面是一个将路径
seg
拆分为长度相同的
n
段的实现。(不是C++,而是JavaScript,它直接处理(x,y)坐标,而不是Lon /LAT,但我可以理解。”
功能拆分(seg,n){
设acc=[];//n+1累计长度
设len=0;//总长度
设p=seg[0];
设res=[];//n+1个结果点的数组
//查找分段和总长度
for(设i=0;iacc[next]){
curr++;
next++;
}
//分段插值
设p=seg[curr];
设q=seg[next];
设t=(z-acc[curr])/(acc[next]-acc[curr]);
res.push(新点(p.x*(1-t)+q.x*t,
p、 y*(1-t)+q.y*t);
}
//推送端点(连接连续线段时省略。)
res.push(seg[seg.length-1]);
返回res;
}

你有什么问题吗?@MOehm抱歉,我猜有点含糊不清。我用我的问题更新了帖子的结尾。
double arrowX=(1-rem)*x1+rem*x2
这里您希望
rem
是介于
0
1
之间的数字,其中
rem=0
表示
arrowX=x1
rem=1
表示
arrowX=x2
。可能类似于
rem=j/street\u seg\u length[i]虽然没有足够的上下文来确定,但几乎肯定不是
rem=j-int(j)。是的,不清楚什么是
inc
。代码需要做两件事:找出当前“箭头”所在的段,然后找出箭头在段中的位置。看起来好像你混淆了
j
是什么,段索引还是运行长度。您希望两者兼而有之,但这不可能。@dxiv谢谢您的建议,但为什么不是j-int(j)?如果j是2.6,rem将是0.6,这就是我想要的。还有,我怎样才能提供更多的背景呢?非常感谢,这正是我过去几天一直坚持的。我对你的代码做了一点修改后,它就开始工作了。非常感谢:)
function split(seg, n) {
    let acc = [];               // n + 1 accumulated lengths
    let len = 0;                // overall length
    let p = seg[0];              
    
    let res = [];               // array of n + 1 result points
    
    // find segemnt and overall lengths
    
    for (let i = 0; i < seg.length; i++) {
        let q = seg[i];
        len += Math.hypot(q.x - p.x, q.y - p.y);
        acc.push(len);

        p = q;
    }
    
    acc.push(2 * len);          // sentinel

    let curr = 0;
    let next = 1;
    
    // create equidistant result points
    
    for (let i = 0; i < n; i++) {
        let z = len * i / n;        // running length of point i
        
        // advance to current segment
        
        while (z > acc[next]) {
            curr++;
            next++;
        }
        
        // interpolate in segment
                
        let p = seg[curr];
        let q = seg[next];
        
        let t = (z - acc[curr]) / (acc[next] - acc[curr]);
        
        res.push(new Point(p.x * (1 - t) + q.x * t,
                           p.y * (1 - t) + q.y * t));
    }
    
    // push end point (leave out when joining consecutive segments.)
    
    res.push(seg[seg.length - 1]);
    
    return res;
}