Let’s have some fun by drawing a dynamic infinity symbol using Jetpack Compose. We’ll also add a simple animation to bring it to life.
First, let’s understand the mathematical representation of the infinity symbol. There is a simple equation that can help us shape it accurately.
\( x(\theta) = \frac{scale \cdot \cos(\theta)}{1 + \sin^2(\theta)} \)
\( y(\theta) = \frac{\text{scale} \cdot \sin(\theta) \cdot \cos(\theta)}{1 + \sin^2(\theta)} \)
\( \theta =[0, 2\pi] \)
At this point, the range
is often used in parametric equations because it represents a full cycle around the unit circle. This static range for theta( ) provides a comprehensive set of values, ensuring we have enough points to accurately draw the complete shape of the infinity symbol.data class InfinityCoordinate(val x: Float, val y: Float)
Kotlinfun calculateCoordinates(theta: Double, scale: Float) = InfinityCoordinate(
(scale * cos(theta) / (1 + sin(theta) * sin(theta))).toFloat(),
(scale * sin(theta) * cos(theta) / (1 + sin(theta) * sin(theta))).toFloat()
)
KotlinNow, we have a function representing the mathematical equation, let’s create a helper function to generate values based on a given range.
fun generateSequenceInRange(start: Double, end: Double, step: Double) =
generateSequence(start) { it + step }.takeWhile { it <= end }.toList()
KotlinWith these functions in place, we can begin drawing using a custom path.
@Composable
fun DrawInfinity(
.
.
thetaValues: List<Double>
) {
Canvas {
val path = Path().apply {
var firstPoint = true
for (theta in thetaValues) {
val (x, y) = calculateCoordinates(theta = theta, scale = 300f)
// Translate coordinates to the middle of the canvas
val xMiddleOfCanvas = x + size.width / 2
val yMiddleOfCanvas = y + size.height / 2
// Move to the starting point or draw a line segment
if (firstPoint) {
moveTo(xMiddleOfCanvas, yMiddleOfCanvas)
firstPoint = false
} else {
lineTo(xMiddleOfCanvas, yMiddleOfCanvas)
}
}
}
drawPath(
path = path,
brush = brush,
style = Stroke(width = stroke)
)
}
}
KotlinLet’s call the DrawInfinity function and provide it with the theta values.
setContent {
Box {
DrawInfinity(
thetaValues = generateSequenceInRange(0.0, 2 * PI, 0.001)
)
}
}
KotlinThanks for reading! If you want to see animation code please check out the code here.