Add new Rectangle.grid with cell size argument (#223)

This commit is contained in:
Abe Pazos
2022-02-28 21:02:57 +01:00
committed by GitHub
parent 7ab9e683bd
commit b7bd7aee83
3 changed files with 88 additions and 13 deletions

View File

@@ -18,26 +18,62 @@ fun Rectangle.grid(
marginY: Double = 0.0,
gutterX: Double = 0.0,
gutterY: Double = 0.0
) = grid(
(width - marginX * 2 - gutterX * (columns - 1)) / columns,
(height - marginY * 2 - gutterY * (rows - 1)) / rows,
marginX, marginY,
gutterX, gutterY
)
/**
* Splits [Rectangle] into a grid of [Rectangle]s
* @param cellWidth the unitless width of a cell
* @param cellHeight the unitless height of a cell
* @param minMarginX the unitless minimum margin width (may increase to produce
* the desired cell aspect ratio)
* @param minMarginY the unitless minimum margin height (may increase to produce
* the desired cell aspect ratio)
* @param gutterX the unitless gutter width, the horizontal space between grid cells
* @param gutterY the unitless gutter height, the vertical space between grid cells
*/
fun Rectangle.grid(
cellWidth: Double,
cellHeight: Double,
minMarginX: Double = 0.0,
minMarginY: Double = 0.0,
gutterX: Double = 0.0,
gutterY: Double = 0.0
): List<List<Rectangle>> {
val totalWidth = width - marginX * 2.0
val totalHeight = height - marginY * 2.0
val totalGutterWidth = gutterX * (columns - 1).coerceAtLeast(0)
val totalGutterHeight = gutterY * (rows - 1).coerceAtLeast(0)
val cellWidth = ((totalWidth - totalGutterWidth) / columns).coerceAtLeast(0.0)
val cellHeight = ((totalHeight - totalGutterHeight) / rows).coerceAtLeast(0.0)
val availableWidth = (width - minMarginX * 2).coerceAtLeast(0.0)
val availableHeight = (height - minMarginY * 2).coerceAtLeast(0.0)
val cellSpaceX = cellWidth + gutterX
val cellSpaceY = cellHeight + gutterY
val x0 = x + marginX
val y0 = y + marginY
val columns = ((availableWidth + gutterX) / cellSpaceX).toInt()
val rows = ((availableHeight + gutterY) / cellSpaceY).toInt()
if (columns == 0 || rows == 0) {
return emptyList()
}
val totalGutterWidth = gutterX * (columns - 1).coerceAtLeast(0)
val totalGutterHeight = gutterY * (rows - 1).coerceAtLeast(0)
val totalWidth = cellWidth * columns + totalGutterWidth
val totalHeight = cellHeight * rows + totalGutterHeight
val x0 = x + (width - totalWidth) / 2
val y0 = y + (height - totalHeight) / 2
return (0 until rows).map { row ->
(0 until columns).map { column ->
Rectangle(x0 + column * cellSpaceX, y0 + row * cellSpaceY, cellWidth, cellHeight)
Rectangle(
x0 + column * cellSpaceX,
y0 + row * cellSpaceY,
cellWidth, cellHeight
)
}
}
}
}

View File

@@ -1,6 +1,5 @@
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.extensions.SingleScreenshot
import org.openrndr.extra.shapes.grid
fun main() {
@@ -13,6 +12,9 @@ fun main() {
extend {
drawer.fill = ColorRGBa.WHITE.opacify(0.25)
drawer.stroke = ColorRGBa.PINK
// Notice the negative gutter in this grid. It creates an
// overlap between the resulting rectangles.
val grid = drawer.bounds.grid(8, 4, 20.0, 20.0, -20.0, -20.0)
for (cell in grid.flatten()) {
drawer.rectangle(cell)

View File

@@ -0,0 +1,37 @@
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.extra.noise.Random
import org.openrndr.extra.shapes.grid
fun main() {
application {
// Try changing the resolution. The design will use the available space.
configure {
width = 800
height = 400
}
program {
// By specifying the cell size we make sure the design will
// contain squares, independently of the window size and its
// aspect ratio.
val grid = drawer.bounds.grid(50.0, 50.0,
20.0, 20.0, 20.0, 20.0).flatten()
val grid2 = grid.map { rect ->
// Each of these inner grids will occupy the available space
// in the parent grid cells. Notice how we don't specify cell
// sizes here but counts instead (between 1 and 3 columns and
// rows)
val count = Random.int(1, 4)
rect.grid(count, count, 5.0, 5.0, 5.0, 5.0).flatten()
}.flatten().filter { Random.bool(0.5)}
extend {
drawer.clear(ColorRGBa.PINK)
drawer.rectangles(grid)
drawer.fill = ColorRGBa.BLACK
drawer.rectangles(grid2)
}
}
}
}