Android canvas,如何从现有路径获取子路径?

时间:2017-12-26 06:54:48

标签: android canvas android-canvas

我在canvas中有一个Bezier曲线路径,从(0,0)开始到(canvasWidth,0)结束,控制点位于(canvasWidth,canvasHeight)

它的绘图正确,我得到一条曲线。我使用path.quadTo方法绘制它,如下所示

          path.moveTo(mPointStart.x, mPointStart.y);
          path.quadTo(mControlPoint.x, mControlPoint.y, mPointEnd.x, mPointEnd.y);
          canvas.drawPath(path, paint);

现在,我想在现有路径上绘制一个子路径。如果我想绘制一半路径,

我想用相同的路径透支使用其他涂料的一半,所以路径的一半将是一种颜色,另一半将是旧颜色。如何在现有路径的一半之前找到这些点?

2 个答案:

答案 0 :(得分:1)

好吧,我这样做(在Kotlin中)就是使用PathMeasure类。它看起来并不是最好的,但它确实有效!所以请发布任何更整洁的答案。

private fun getSubPath(path: Path, start: Float, end: Float): Path {
    val pathMeasure = PathMeasure(path, false)
    val point = FloatArray(2)
    val subPath = Path()
    var startFound = false
    var startDistance = start
    var endDistance = end

    while (pathMeasure.nextContour()) {
        val length = pathMeasure.length
        startDistance -= length
        endDistance -= length

        if (!startFound) {
            if (startDistance <= 0) {
                startFound = true
                val startPoint = length + startDistance

                pathMeasure.getPosTan(startPoint, point, null)
                subPath.moveTo(point[0], point[1])

                if (startDistance < 0) {
                    val endPoint = length + endDistance
                    pathMeasure.getPosTan(endPoint, point, null)
                    subPath.lineTo(point[0], point[1])

                    if (endDistance <= 0) {
                        break
                    }
                }
            }
        } else {
            val endPoint = length + endDistance
            pathMeasure.getPosTan(endPoint, point, null)
            subPath.lineTo(point[0], point[1])

            if (endDistance <= 0) {
                break
            }
        }
    }
    return subPath
}

参数startend不能小于0或大于路径的总长度。

使用方法的方法如下:

private fun usePathFunction() {
    val start = pathsTotalLength * 0.25
    val end = pathsTotalLength * 0.75

    val subPath = getSubPath(path, start, end)
}

答案 1 :(得分:0)

我认为使用getSegment是此问题的正确答案:

private fun getSubPath(path: Path, start: Float, end: Float): Path {
        val subPath = Path()
        val pathMeasure = PathMeasure(path, false)
        pathMeasure.getSegment(start * pathMeasure.length, end * pathMeasure.length, subPath, true)
        return subPath
    }

用法:

val subPath = getSubPath(path = originalPath, start = 0.2f, end = 0.8f)