fix: smooth elevation curves using cubic Bezier instead of lineTo
Replace Path.lineTo() with Path.cubicTo() using Catmull-Rom to Bezier conversion for smooth elevation curves.
This commit is contained in:
1 parent
e59507a4d3
commit
f272e268ab
1 file changed
+24
-9
+24
-9
@@ -140,23 +140,38 @@ fun ElevationCurveChart(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Elevation curves
|
// Elevation curves (smooth cubic Bezier)
|
||||||
val pathA = Path()
|
val pathA = Path()
|
||||||
val pathB = Path()
|
val pathB = Path()
|
||||||
var first = true
|
val ptsA = mutableListOf<Offset>()
|
||||||
|
val ptsB = mutableListOf<Offset>()
|
||||||
|
|
||||||
for ((time, elev) in samples) {
|
for ((time, elev) in samples) {
|
||||||
val x = plotLeft + ((time.toFloat() - minTime) / timeRange) * plotWidth
|
val x = plotLeft + ((time.toFloat() - minTime) / timeRange) * plotWidth
|
||||||
val yA = plotBottom - ((elev.first.toFloat() / maxElev.toFloat()) * plotHeight).coerceIn(0f, plotHeight)
|
val yA = plotBottom - ((elev.first.toFloat() / maxElev.toFloat()) * plotHeight).coerceIn(0f, plotHeight)
|
||||||
val yB = plotBottom - ((elev.second.toFloat() / maxElev.toFloat()) * plotHeight).coerceIn(0f, plotHeight)
|
val yB = plotBottom - ((elev.second.toFloat() / maxElev.toFloat()) * plotHeight).coerceIn(0f, plotHeight)
|
||||||
|
ptsA.add(Offset(x, yA))
|
||||||
|
ptsB.add(Offset(x, yB))
|
||||||
|
}
|
||||||
|
|
||||||
if (first) {
|
if (ptsA.size >= 2) {
|
||||||
pathA.moveTo(x, yA)
|
pathA.moveTo(ptsA[0].x, ptsA[0].y)
|
||||||
pathB.moveTo(x, yB)
|
pathB.moveTo(ptsB[0].x, ptsB[0].y)
|
||||||
first = false
|
for (i in 1 until ptsA.size) {
|
||||||
} else {
|
val prev = ptsA.getOrNull(i - 2) ?: ptsA[i - 1]
|
||||||
pathA.lineTo(x, yA)
|
val curr = ptsA[i - 1]
|
||||||
pathB.lineTo(x, yB)
|
val next = ptsA.getOrNull(i + 1) ?: ptsA[i]
|
||||||
|
val cp1 = Offset(curr.x + (next.x - prev.x) / 6f, curr.y + (next.y - prev.y) / 6f)
|
||||||
|
val cp2 = Offset(ptsA[i].x - (ptsA[i].x - curr.x) / 6f, ptsA[i].y - (ptsA[i].y - curr.y) / 6f)
|
||||||
|
pathA.cubicTo(cp1.x, cp1.y, cp2.x, cp2.y, ptsA[i].x, ptsA[i].y)
|
||||||
|
}
|
||||||
|
for (i in 1 until ptsB.size) {
|
||||||
|
val prev = ptsB.getOrNull(i - 2) ?: ptsB[i - 1]
|
||||||
|
val curr = ptsB[i - 1]
|
||||||
|
val next = ptsB.getOrNull(i + 1) ?: ptsB[i]
|
||||||
|
val cp1 = Offset(curr.x + (next.x - prev.x) / 6f, curr.y + (next.y - prev.y) / 6f)
|
||||||
|
val cp2 = Offset(ptsB[i].x - (ptsB[i].x - curr.x) / 6f, ptsB[i].y - (ptsB[i].y - curr.y) / 6f)
|
||||||
|
pathB.cubicTo(cp1.x, cp1.y, cp2.x, cp2.y, ptsB[i].x, ptsB[i].y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user