如何改进目前在 Kotlin 中使用函数扩展的代码?

Hel*_*oCW -1 kotlin

我希望在新的坐标系中放置一条线,新的原点坐标是val orig=Point(100,50),新的X轴是向右,新的Y轴是向上。

\n

目前我使用的是函数扩展,就像代码A一样。

\n

我觉得不太好,有很多重复的代码,比如.toX(orig).toY(orig)

\n

如何设计数据结构来改进代码\xef\xbc\x9f

\n

代码A

\n
val orig=Point(100,50)\n\ndrawIntoCanvas {\n    it.drawLine(\n          Offset(x = 0f.toX(orig), y = 0f.toY(orig)),\n          Offset(x = (size.width- 200).toX(orig), y = 0f.toY(orig)),\n          axisPaint\n    )\n        \n    val shadowPath = Path()\n    val data =  maxCountList.toList()\n    val step= 20       \n    for (i in data.indices){\n       shadowPath.lineTo((orignX+step*i).toX(orig),data[i].toFloat().toY(orig))\n    }\n    shadowPath.close()\n    it.drawPath(shadowPath,pathPaint)\n    \n    it.nativeCanvas.drawText("Max",50f.toX(orig), 100f.toY(orig), textPaint)\n}\n\n\nfun Float.toX(originCoordinate: Point) : Float {\n    return originCoordinate.x+this\n}\n\nfun Float.toY(originCoordinate: Point): Float {\n    return originCoordinate.y-this\n}\n
Run Code Online (Sandbox Code Playgroud)\n

结束

\n

我可以在 Kotlin 中将委托传递给变量吗?是完美的解决方案!

\n
data class MyPoint(val x: Float, val y: Float) {\n    val Float.toXX: Float get() = x + this\n    val Float.toYY: Float get() = y - this\n}\n\n// In a function:\nval orig = MyPoint(size.width / 2, size.height / 2)\norig.run {\n    drawPath.moveTo(10.0f.toXX, 20.0f.toYY)\n    drawPath.moveTo(5.0f.toXX, 80.0f.toYY)\n    drawPath.moveTo(1.0f.toXX, 3.0f.toYY)\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Kar*_*iel 5

我想说,最简单的方法是在绘图时通过平移画布,使原点成为画布的实际原点:

fun Canvas.withTranslation(x: Float, y: Float, block: (Canvas) -> Unit) {
    withSave {
        translate(x, y)
        block(this)
    }
}

fun DrawScope.drawIntoCanvasWithOrigin(origin: PointF, block: (Canvas) -> Unit) {
    drawIntoCanvas {
        it.withTranslation(origin.x, origin.y) { canvas ->
            block(canvas)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您不需要将原点添加到每个值,因为所有内容都已经相对于您的原点,您可以编写:

val orig=Point(100,50)

drawIntoCanvasWithOrigin(orig.toPointF()) {
    it.drawLine(
          Offset(x = 0f, y = 0f),
          Offset(x = size.width- 200, y = 0f),
          axisPaint
    )
        
    val shadowPath = Path()
    val data =  maxCountList.toList()
    val step= 20       
    for (i in data.indices){
       shadowPath.lineTo(orignX+step*i,data[i].toFloat())
    }
    shadowPath.close()
    it.drawPath(shadowPath,pathPaint)
    
    it.nativeCanvas.drawText("Max",50f, 100f, textPaint)
}
Run Code Online (Sandbox Code Playgroud)

考虑到您希望在定义的原点镜像 y 轴的评论,我们可以相应地扩展代码:

fun Canvas.withScale(x: Float, y: Float, block: (Canvas) -> Unit) {
    withSave {
        scale(x, y)
        block(this)
    }
}

fun DrawScope.drawIntoCanvasWithOrigin(origin: PointF, block: (Canvas) -> Unit) {
    drawIntoCanvas {
        it.withTranslation(origin.x, origin.y) { canvasAtOrigin ->
            canvasAtOrigin.withScale(1.0f, -1.0f) { mirroredCanvas ->
                block(mirroredCanvas)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)