我正试图让一辆汽车沿着一条车道行驶。我知道车道的所有点,因为现在车道用多边形表示,以两组线段为边界。给定这两个边界,我想找到汽车将要行驶的另一组线段,例如铁路,使其始终位于两个边界段之间。每个边界线段中的线数可能并不总是相同,线段不是“平行”的。
图(这是一个非常简单的图,但是我相信它传达了信息):
我已经考虑过以下问题,但我认为它们没有起作用,或者至少效率不高:
我想到了更多,但不值得一提。
感谢您的帮助,请随时提出任何问题。
答案 0 :(得分:1)
以下想法受Dynamic Time Warping(DTW)的启发。这是Shreyas Pimpalgaonkar的想法在评论中的延伸:
总体思路是将街道一侧的点与另一侧的点匹配。例如,沿两侧分布100个点,并尝试在它们之间画线。我们将用于匹配点的标准是接近度。因此,连接线的总长度应尽可能小。一旦有了这些线,就可以计算它们的中点并连接它们。根据您开始的点数,这也会使您的线条更平滑。
这里有一些细节:分配积分并不难。您可以每x单位放置一个点。或者,您可以在线段上分配恒定数量的点。最后,点的分布并不重要。不过,均匀分布会给您更好的结果。
中心点是DTW变体。该算法的基本数据是一个匹配矩阵,该矩阵告诉您将一个点匹配到另一个点的代价是多少。为此,可以使用两点的欧几里得距离。一旦有了这个矩阵(它不必是一个完整的矩阵;对角线附近的条目通常就足够了;请参阅Wikipedia文章中的位置约束),您只需使用动态程序即可解决翘曲问题。
最后,您连接到中间点。就是这样。
我还要补充一点,这不一定能保证路径保持在车道内。但是,只有在非常怪异的道路群中才会破坏。为了安全起见,您可以调整成本矩阵,以使算法不会匹配连接线与车道边界交叉的点。
这里有一些例子。如果需要更平滑的路径,则可以更改在连接线上选择的点(而不是中点)。您可以例如相对于生成线的拉普拉斯算子优化插值参数。这将为您提供线性方程组,使您可以控制路径的平滑度。但是,要保证路径不再留在车道内并不容易。
答案 1 :(得分:-1)
首先,如果您已经设计了一些代码部分,然后提出了问题。只有通过分析才能使您有很多选择,都可以通过java / python来完成。
我只是向您展示一个简单的示例,它详细说明了地图中使用的路径/车道追随者。
private void CarMove(final Marker marker, final LatLng beginLatLng, final LatLng endLatLng, final long duration) {
final Handler handler = new Handler();
final long startTime = SystemClock.uptimeMillis();
final Interpolator interpolator = new LinearInterpolator();
// set car bearing for current part of path
float angleDeg = (float)(180 * getAngle(beginLatLng, endLatLng) / Math.PI);
Matrix matrix = new Matrix();
matrix.postRotate(angleDeg);
marker.setIcon(BitmapDescriptorFactory.fromBitmap(Bitmap.createBitmap(mMarkerIcon, 0, 0, mMarkerIcon.getWidth(), mMarkerIcon.getHeight(), matrix, true)));
handler.post(new Runnable() {
@Override
public void run() {
// calculate phase of animation
long elapsed = SystemClock.uptimeMillis() - startTime;
float t = interpolator.getInterpolation((float) elapsed / duration);
// calculate new position for marker
double lat = (endLatLng.latitude - beginLatLng.latitude) * t + beginLatLng.latitude;
double lngDelta = endLatLng.longitude - beginLatLng.longitude;
if (Math.abs(lngDelta) > 180) {
lngDelta -= Math.signum(lngDelta) * 360;
}
double lng = lngDelta * t + beginLatLng.longitude;
marker.setPosition(new LatLng(lat, lng));
// if not end of line segment of path
if (t < 1.0) {
// call next marker position
handler.postDelayed(this, 16);
} else {
// call turn animation
nextTurnAnimation();
}
}
});
}