# how to create a hexagon shape with curved endsin Jetpack composeH

## Issue

I’ve attempted to create a hexagon shape in jetpack compose but could only achieve pointed ends, tried several methods with quadraticBezierTo and arcs but couldn’t achieve a result with curved ends.

I’ve tried to look on the web but not quite what i wanted, If you have an idea how to achieve it, thanks for answering to this post.

Here’s the current code without curved ends:

``````class HexagonShape : Shape {

override fun createOutline(
size: Size,
layoutDirection: LayoutDirection,
density: Density
): Outline {
return Outline.Generic(
path = drawCustomHexagonPath(size)
)
}
}

private fun drawCustomHexagonPath(size: Size): Path {
return Path().apply {
val radius = min(size.width / 2f, size.height / 2f)
val triangleHeight = (sqrt(3.0) * radius / 2)
val centerX = size.width / 2
val centerY = size.height / 2

moveTo(x = centerX, y = centerY + radius)

lineTo(x = (centerX - triangleHeight).toFloat(), y = centerY + radius / 2)
lineTo(x = (centerX - triangleHeight).toFloat(), y = centerY - radius / 2)
lineTo(x = centerX, y = centerY - radius)
lineTo(x = (centerX + triangleHeight).toFloat(), y = centerY - radius / 2)
lineTo(x = (centerX + triangleHeight).toFloat(), y = centerY + radius / 2)

close()
}
}

@Composable
fun Hexagon(modifier: Modifier = Modifier) {
Box(
modifier = modifier
.clip(HexagonShape())
.background(md_theme_light_inversePrimary)
.width(500.dp)
.height(500.dp),
contentAlignment = Alignment.Center
) {
Image(
painter = painterResource(id = R.drawable.app_bg),
contentDescription = "My Hexagon Image",
contentScale = ContentScale.Crop,
modifier = Modifier
.wrapContentSize()
.background(color = Color.Cyan)
)
}
}

``````

## Solution

You can use `pathEffect = PathEffect.cornerPathEffect(cornerRadius)`

``````@Composable
private fun DrawPolygonPath() {
var sides by remember { mutableStateOf(3f) }
var cornerRadius by remember { mutableStateOf(1f) }

Canvas(modifier = canvasModifier) {
val canvasWidth = size.width
val canvasHeight = size.height
val cx = canvasWidth / 2
val cy = canvasHeight / 2
val radius = (canvasHeight - 20.dp.toPx()) / 2
val path = createPolygonPath(cx, cy, sides.roundToInt(), radius)

drawPath(
color = Color.Red,
path = path,
style = Stroke(
width = 4.dp.toPx(),
)
)
}

Column(modifier = Modifier.padding(horizontal = 20.dp)) {
Text(text = "Sides \${sides.roundToInt()}")
Slider(
value = sides,
onValueChange = { sides = it },
valueRange = 3f..12f,
steps = 10
)

Slider(
onValueChange = { cornerRadius = it },
valueRange = 0f..50f,
)
}
}
``````

and polygon function

``````fun createPolygonPath(cx: Float, cy: Float, sides: Int, radius: Float): Path {
val angle = 2.0 * Math.PI / sides

return Path().apply {
moveTo(
)
for (i in 1 until sides) {
lineTo(
cx + (radius * cos(angle * i)).toFloat(),
cy + (radius * sin(angle * i)).toFloat()
)
}
close()
}
}
``````

You can get `ImageBitmap` from Coil and you can draw it with `BlendMode` as like this

``````@Preview
@Composable
fun ImageTest() {
Column(
) {
val imageBitmap = ImageBitmap.imageResource(R.drawable.avatar_1_raster)

Box(
Modifier
.size(200.dp)
.border(2.dp, Color.Green)
.graphicsLayer {
compositingStrategy = CompositingStrategy.Offscreen
}
.drawWithCache {
val canvasWidth = size.width
val canvasHeight = size.height
val cx = canvasWidth / 2
val cy = canvasHeight / 2
val radius = canvasHeight / 4
val path = createPolygonPath(cx, cy, 6, radius)

onDrawWithContent {

// Source
drawPath(
path = path,
color = Color.Red,
style = Stroke(
width = canvasHeight / 2,
pathEffect = PathEffect.cornerPathEffect(15f)
)
)

drawCircle(
color = Color.Red,
)

// Destination
drawImage(
image = imageBitmap,
dstSize = IntSize(size.width.toInt(), size.height.toInt()),
blendMode = BlendMode.SrcIn
)
}
}
)
}
}
``````