如何绘制Uber折线?

3

Uber应用程序使用了一个带阴影的弯曲折线(polyline)。这个阴影可能只是连接两点的黑色透明折线。这很容易实现。但是第二个弯曲折线,如何完成?这是贝塞尔曲线还是内置函数(setGeodesic(true))吗?

enter image description here

我已经查看了Google Maps的示例,并看到了一个关于圆形折线的部分。这是否可以改编为创建半圆形?以下是示例代码:

PolylineOptions options = new PolylineOptions();
int radius = 5; //What is that?
int numPoints = 100;
double phase = 2 * Math.PI / numPoints;
for (int i = 0; i <= numPoints; i++) {
    options.add(new LatLng(SYDNEY.latitude + radius * Math.sin(i * phase),
            SYDNEY.longitude + radius * Math.cos(i * phase)));
}
int color = Color.RED;
mMap.addPolyline(options
        .color(color)
        .width(2));

1
类似的问题可以在这里找到答案:https://dev59.com/zqDia4cB1Zd3GeqPIsDp。 - xomena
该算法的曲线不够平滑。我创建了一个更新后的算法,它更加平滑。 - portfoliobuilder
@portfoliobuilder,您能提供您的解决方案吗? - Shrikant Salunkhe
iOS 解决方案链接:https://dev59.com/LKbja4cB1Zd3GeqPdT1M#53569754 - Rouny
你可以在这里看到我的答案,可能对你有帮助。 - Amir Raza
2个回答

15
我可以用以下的贝塞尔曲线计算方法来实现这个目标。
    double cLat = ((start.latitude + end.latitude) / 2);
    double cLon = ((start.longitude + end.longitude) / 2);

    //add skew and arcHeight to move the midPoint
    if(Math.abs(start.longitude - end.longitude) < 0.0001){
        cLon -= 0.0195;
    } else {
        cLat += 0.0195;
    }

    double tDelta = 1.0/50;
    for (double t = 0;  t <= 1.0; t+=tDelta) {
        double oneMinusT = (1.0-t);
        double t2 = Math.pow(t, 2);
        double lon = oneMinusT * oneMinusT * start.longitude
                + 2 * oneMinusT * t * cLon
                + t2 * end.longitude;
        double lat = oneMinusT * oneMinusT * start.latitude
                + 2 * oneMinusT * t * cLat
                + t2 * end.latitude;
        alLatLng.add(new LatLng(lat, lon));
    }

    // draw polyline
    PolylineOptions line = new PolylineOptions();
    line.width(POLYGON_STROKE_WIDTH_PX);
    line.color(Color.RED);
    line.addAll(alLatLng);
    map.addPolyline(line);

我如何在单条曲线上提供由暗到亮的颜色? - Ashim Kansal
@AshimKansal 这是可能的。但你应该在SO上提出问题。如果我看到了,我会给你一个答案。我也弄清楚了那个问题。虽然它非常复杂。作为一个警告,小心提问。正如你所看到的,人们无缘无故地对我的问题进行了负投票。这让你不想再问任何问题了。 - portfoliobuilder
alLatLng变量的类型是什么? - Usman Jdn
1
@UsmanJdn 谷歌LatLng对象的ArrayList - portfoliobuilder

3
 private fun plotPolyline(
    startLat: Double?,
    startLon: Double?,
    markerLat: Double?,
    markerLon: Double?
) {
    if (startLat == null || startLon == null || markerLat == null || markerLon == null) {
        return
    }
    var startPoint = LatLng(startLat, startLon)
    var endPoint = LatLng(markerLat, markerLon)
    val distance = SphericalUtil.computeDistanceBetween(startPoint, endPoint)
    val midPoint = SphericalUtil.interpolate(startPoint, endPoint, 0.5)
    val midToStartLocHeading = SphericalUtil.computeHeading(midPoint, startPoint)
    val controlPointAngle = 360.0 - (90.0 - midToStartLocHeading)
    val controlPoint = SphericalUtil.computeOffset(midPoint, distance / 2.0, controlPointAngle)
    var t = 0.0
    val polylineOptions = PolylineOptions()

    while (t <= 1.00) {
        val oneMinusT = 1.0 - t
        val lon: Double =
            oneMinusT * oneMinusT * startLon + 2 * oneMinusT * t * controlPoint.longitude + t * t * markerLon
        val lat: Double =
            oneMinusT * oneMinusT * startLat + 2 * oneMinusT * t * controlPoint.latitude + t * t * markerLat
        polylineOptions.add(LatLng(lat, lon))
        t += 0.05
    }

    polylineOptions.add(endPoint)

    // Draw polyline
    polyline?.remove()
    var pattern = listOf<PatternItem>(Gap(10.0f), Dash(10.0f))
    polyline = googleMap?.addPolyline(
        polylineOptions.width(10f).pattern(pattern)
            .geodesic(false)
    )
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接