Nat Strangerweather
03/20/2021, 9:45 PMNat Strangerweather
03/20/2021, 9:49 PMCanvas(modifier = Modifier
.size(350.dp)
.background(Color.Blue)
.padding(30.dp)
.clipToBounds(),
onDraw = {
val canvasWidth = size.width
val canvasHeight = size.height
val paint = Paint()
wordsAndColors.forEach { (word, color) ->
val padding = PaddingValues(10.dp)
val wordWidth = paint.measureText(word) + padding
.calculateLeftPadding(LayoutDirection.Ltr).roundToPx() + padding
.calculateRightPadding(LayoutDirection.Ltr).roundToPx()
val wordHeight = paint.ascent() + paint.descent()+ padding
.calculateTopPadding().roundToPx() + padding.calculateBottomPadding().roundToPx()
println(wordHeight)
val xCoordinate = Random.nextInt(canvasWidth.toInt() - wordWidth.toInt())
val yCoordinate = Random.nextInt(canvasHeight.toInt() - wordHeight.toInt())
paint.textSize = 64f
paint.isFakeBoldText = true
paint.color = color.toArgb()
paint.isAntiAlias = true
paint.textAlign = Paint.Align.CENTER
drawContext.canvas.nativeCanvas.drawText(
word.decapitalize(Locale.ROOT),
xCoordinate.toFloat(), yCoordinate.toFloat(),
paint
)
Any ideas how to do this properly?Tash
03/21/2021, 3:47 AMTash
03/21/2021, 3:54 AMDenis
03/21/2021, 6:57 AMEach word "wants" to be somewhere, such as "at some random x position in the vertical center". In decreasing order of frequency, do this for each word:
place the word where it wants to be
while it intersects any of the previously placed words
    move it one step along an ever-increasing spiral
That's it. The hard part is in doing the intersection-testing efficiently, for which I use last-hit caching, hierarchical bounding boxes, and a quadtree spatial index (all of which are things you can learn more about with some diligent googling).
http://static.mrfeinberg.com/bv_ch03.pdf
Nat Strangerweather
03/21/2021, 7:03 AMTash
03/21/2021, 8:34 AM