You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Android Canvas上绘制带圆角的六边形?

绘制带圆角的六边形

我想要绘制一个带圆角的六边形,但毫无头绪。我尝试过cubicTo、arcTo等多种方法。

当前尝试效果

以下是我当前的绘制代码:

fun Path.customHexagon(radius: Float, size: Size) {
    val triangleHeight = (sqrt(3.0) * radius / 2)
    val centerX = size.width / 2
    val centerY = size.height / 2

    moveTo(centerX, centerY + radius)
    lineTo((centerX - triangleHeight).toFloat(), centerY + radius/2)
    lineTo((centerX - triangleHeight).toFloat(), centerY - radius/2)
    lineTo(centerX, centerY - radius)
    lineTo((centerX + triangleHeight).toFloat(), centerY - radius/2)
    lineTo((centerX + triangleHeight).toFloat(), centerY + radius/2)

    close()
}

解决方案

要实现带圆角的六边形,核心是用arcTo替换每个顶点的直角连接,让每个角平滑过渡。下面是修改后的代码:

import android.graphics.PointF
import kotlin.math.cos
import kotlin.math.sin
import kotlin.math.sqrt
import kotlin.math.toRadians

fun Path.customRoundedHexagon(radius: Float, size: Size, cornerRadius: Float) {
    val triangleHeight = (sqrt(3.0) * radius / 2).toFloat()
    val centerX = size.width / 2
    val centerY = size.height / 2

    // 六边形的六个顶点坐标
    val vertices = listOf(
        PointF(centerX, centerY + radius),
        PointF(centerX - triangleHeight, centerY + radius/2),
        PointF(centerX - triangleHeight, centerY - radius/2),
        PointF(centerX, centerY - radius),
        PointF(centerX + triangleHeight, centerY - radius/2),
        PointF(centerX + triangleHeight, centerY + radius/2)
    )

    // 每个顶点对应的方向角度(用于计算切线)
    val vertexAngles = listOf(270f, 210f, 150f, 90f, 30f, 330f)
    val arcAngle = 60f // 六边形内角120°,圆弧覆盖60°实现圆角

    // 移动到第一个边的起始点(避开圆角区域)
    val startAngle = vertexAngles[0] + 30f
    moveTo(
        vertices[0].x + cornerRadius * cos(startAngle.toRadians()),
        vertices[0].y + cornerRadius * sin(startAngle.toRadians())
    )

    // 遍历每个顶点,绘制圆角圆弧
    for (i in vertices.indices) {
        val nextIndex = (i + 1) % vertices.size
        val currentVertex = vertices[i]
        val nextVertex = vertices[nextIndex]

        // 计算圆弧的边界矩形和角度参数
        val left = currentVertex.x - cornerRadius * cos((vertexAngles[i] - 30f).toRadians())
        val top = currentVertex.y - cornerRadius * sin((vertexAngles[i] - 30f).toRadians())
        val right = currentVertex.x + cornerRadius * cos((vertexAngles[nextIndex] + 30f).toRadians())
        val bottom = currentVertex.y + cornerRadius * sin((vertexAngles[nextIndex] + 30f).toRadians())

        arcTo(
            left, top, right, bottom,
            vertexAngles[i] - 60f, arcAngle,
            false
        )
    }

    close()
}

// 扩展函数:角度转弧度
private fun Float.toRadians() = this.toDouble().toRadians().toFloat()

关键说明

  • cornerRadius参数用于控制圆角大小,建议取值不超过triangleHeight * 0.5,避免图形变形
  • 利用六边形每个内角120°的特性,通过arcTo绘制60°的圆弧来实现圆角,保证边与圆弧平滑连接
  • 所有顶点坐标计算逻辑和原代码保持一致,只修改了顶点处的连接方式

内容的提问来源于stack exchange,提问作者xMaster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 11:43:12