
์ง๊ธ๊น์ง Drawer์ ๋ด์ฅ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ด์:
extend {
drawer.clear(ColorRGBa.BLACK)
drawer.circle(400.0, 400.0, 100.0)
}
๊ทธ๋ฐ๋ฐ ๋ง์ฝ ์์ฃผ ์ฐ๋ ํจํด์ด ๋ฐ๋ณต๋๋ค๋ฉด?
์๋ฅผ ๋ค์ด, ๊ฒฉ์๋ฅผ ๋งค๋ฒ ์ด๋ ๊ฒ ๊ทธ๋ ค์ผ ํ๋ค๋ฉด:
extend {
for (x in 0 until 10) {
for (y in 0 until 10) {
val px = x * 80.0
val py = y * 80.0
circle(px, py, 20.0)
}
}
}
๋ฐ๋ณต๋๋ ํจํด์ ํ๋์ ๋ฉ์๋๋ก ๋ง๋ค ์ ์๋ค๋ฉด?
extend {
grid(10, 10, 80.0, 20.0) // ํจ์ฌ ๊ฐ๋จ!
}
์ด๊ฒ์ด Extension ํจ์์ ๋๋ค.
์ด ๊ธ์์๋:
์ ๋ค๋ฃจ๊ฒ ์ต๋๋ค.
Extension ํจ์๋ ๊ธฐ์กด ํด๋์ค์ ์๋ก์ด ๋ฉ์๋๋ฅผ "๋ถ์ด๋" ๊ธฐ๋ฅ์ ๋๋ค.
// ์ ์ ํด๋์ค์ ์ ๋ฉ์๋ ์ถ๊ฐ
fun Int.isEven(): Boolean {
return this % 2 == 0
}
// ์ฌ์ฉ
val num = 10
println(num.isEven()) // true
๊ตฌ์กฐ:
fun ํด๋์ค์ด๋ฆ.๋ฉ์๋์ด๋ฆ(ํ๋ผ๋ฏธํฐ): ๋ฐํํ์
{
// this๋ ์๋์ผ๋ก ํด๋์ค์ ์ธ์คํด์ค
}
// String ํด๋์ค์ "๋จ์ด ๊ฐ์ ์ธ๊ธฐ" ๋ฉ์๋ ์ถ๊ฐ
fun String.wordCount(): Int {
return this.split(" ").size
}
val text = "Hello World OPENRNDR"
println(text.wordCount()) // 3
์ฌ๊ธฐ์ this๋ ์๋์ผ๋ก String ๊ฐ์ฒด์
๋๋ค.
OPENRNDR์ ์ฒ ํ: ์์ฃผ ์ฐ๋ ํจํด์ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ๋ฉ์๋๋ก ๋ง๋ค์
// 1๋จ๊ณ: ๋ฐ๋ณต๋๋ ์ฝ๋ ๋ฐ๊ฒฌ
extend {
// ๊ฒฉ์ ํจํด์ ๋งค๋ฒ ์ด๋ ๊ฒ ์ด๋ค
for (x in 0 until 10) {
for (y in 0 until 10) {
circle(x * 80.0, y * 80.0, 20.0)
}
}
}
// 2๋จ๊ณ: Extension ํจ์๋ก ์ถ์ํ
fun Drawer.grid(cols: Int, rows: Int, spacing: Double, radius: Double = 20.0) {
for (x in 0 until cols) {
for (y in 0 until rows) {
circle(x * spacing, y * spacing, radius)
}
}
}
// 3๋จ๊ณ: ๊ฐ๋จํ๊ฒ ์ฌ์ฉ
extend {
grid(10, 10, 80.0) // ๋งค์ฐ ๊ฐ๊ฒฐ!
}
p5.js์์๋ ์ ํจ์๋ฅผ ๋ง๋ค์ด์ผ ํฉ๋๋ค:
function drawGrid(cols, rows, spacing) {
for (let x = 0; x < cols; x++) {
for (let y = 0; y < rows; y++) {
circle(x * spacing, y * spacing, 20);
}
}
}
function draw() {
background(0);
drawGrid(10, 10, 80);
}
๋ฌธ์ ์ :
drawGrid์ circle์ ๊ด๊ณ๊ฐ ๋ช
ํํ์ง ์์fun Drawer.grid(cols: Int, rows: Int, spacing: Double) {
for (x in 0 until cols) {
for (y in 0 until rows) {
circle(x * spacing, y * spacing, 20.0)
}
}
}
extend {
grid(10, 10, 80.0) // Drawer์ ๋ฉ์๋์ฒ๋ผ!
}
์ฅ์ :
grid๋ ๋ช
ํํ๊ฒ Drawer์ ๋ฉ์๋drawer. ์์ด๋ ์ฌ์ฉ ๊ฐ๋ฅ// Extension ํจ์ ์ ์
fun Drawer.grid(
cols: Int,
rows: Int,
spacing: Double,
radius: Double = 20.0
) {
for (x in 0 until cols) {
for (y in 0 until rows) {
circle(x * spacing, y * spacing, radius)
}
}
}
program {
extend {
clear(ColorRGBa.BLACK)
fill = ColorRGBa.WHITE
grid(12, 12, 60.0, 15.0)
}
}
์ฌ์ฉ์ ํธ์์ฑ:
grid(12, 12, 60.0, 15.0) ํ ์คfor ๋ฃจํ๋ฅผ ๋งค๋ฒ ์์ฑํด์ผ ํจ// ์ค์ฌ ์ฃผ์์ ์ํ์ผ๋ก ๋ฐฐ์น
fun Drawer.radialLayout(
count: Int,
distance: Double,
radius: Double = 20.0
) {
for (i in 0 until count) {
val angle = TWO_PI / count * i
val x = distance * cos(angle)
val y = distance * sin(angle)
circle(x, y, radius)
}
}
program {
extend {
clear(ColorRGBa.BLACK)
fill = ColorRGBa.PINK
// ์ค์ฌ์์ 12๊ฐ ์์ 150 ํฝ์
๊ฑฐ๋ฆฌ์ ๋ฐฐ์น
radialLayout(12, 150.0, 15.0)
}
}
// ๋์ ํจํด
fun Drawer.spiral(
count: Int,
spacing: Double,
rotation: Double = 0.0
) {
for (i in 0 until count) {
val angle = rotation + i * 0.2
val radius = i * spacing
val x = radius * cos(angle)
val y = radius * sin(angle)
point(x, y)
}
}
program {
var t = 0.0
extend {
clear(ColorRGBa.BLACK)
strokeWeight = 2.0
stroke = ColorRGBa.CYAN
spiral(500, 0.5, t) // ํ์ ํ๋ ๋์
t += 0.02
}
}
Drawer + Vector2 Extension// Vector2์ ๊ฐ๋์ ๊ฑฐ๋ฆฌ๋ฅผ ์ป๊ธฐ
fun Vector2.angle(): Double {
return atan2(y, x)
}
fun Vector2.magnitude(): Double {
return sqrt(x * x + y * y)
}
// ์ฌ์ฉ
val v = Vector2(3.0, 4.0)
println(v.magnitude()) // 5.0
println(v.angle()) // ~0.93 ๋ผ๋์
// Vector2 ๋ฆฌ์คํธ๋ฅผ ๊ฒฝ๋ก๋ก ๊ทธ๋ฆฌ๊ธฐ
fun Drawer.path(points: List<Vector2>, closed: Boolean = false) {
if (points.isEmpty()) return
for (i in 0 until points.size - 1) {
lineSegment(points[i], points[i + 1])
}
if (closed) {
lineSegment(points.last(), points.first())
}
}
program {
extend {
clear(ColorRGBa.BLACK)
stroke = ColorRGBa.WHITE
val triangle = listOf(
Vector2(400.0, 200.0),
Vector2(600.0, 400.0),
Vector2(200.0, 400.0)
)
path(triangle, closed = true) // ์ผ๊ฐํ ๊ทธ๋ฆฌ๊ธฐ
}
}
Extension ํจ์์์ ๊ธฐ๋ณธ๊ฐ์ ์ง์ ํ ์ ์์ต๋๋ค:
// ๋ฐ์ง๋ฆ์ ๊ธฐ๋ณธ๊ฐ ์ค์
fun Drawer.grid(
cols: Int,
rows: Int,
spacing: Double,
radius: Double = 20.0 // ๊ธฐ๋ณธ๊ฐ
) {
for (x in 0 until cols) {
for (y in 0 until rows) {
circle(x * spacing, y * spacing, radius)
}
}
}
// ์ฌ์ฉ
extend {
grid(10, 10, 80.0) // radius = 20.0 (๊ธฐ๋ณธ๊ฐ)
grid(10, 10, 80.0, 30.0) // radius = 30.0 (๋ช
์)
}
์ข์ ๊ธฐ๋ณธ๊ฐ ์ค๊ณ:
// ๋์ฌ์(concentric circles)
fun Drawer.concentricCircles(
count: Int,
startRadius: Double,
spacing: Double,
centerX: Double = 400.0,
centerY: Double = 400.0
) {
for (i in 0 until count) {
val radius = startRadius + i * spacing
circle(centerX, centerY, radius)
}
}
// ๊ฒฉ์ + ๋์ฌ์ ์กฐํฉ
program {
var t = 0.0
extend {
clear(ColorRGBa.BLACK)
fill = ColorRGBa.WHITE
// ๊ฒฉ์
for (x in 0 until 5) {
for (y in 0 until 5) {
val cx = 100.0 + x * 160.0
val cy = 100.0 + y * 160.0
concentricCircles(
count = 3,
startRadius = 20.0,
spacing = 15.0,
centerX = cx,
centerY = cy
)
}
}
t += 0.01
}
}
Extension ํจ์๋ ๋ค๋ฅธ Extension ํจ์ ์์์๋ ์ฌ์ฉํ ์ ์์ต๋๋ค:
// ๊ธฐ๋ณธ Extension
fun Drawer.box(
x: Double,
y: Double,
width: Double,
height: Double,
cornerRadius: Double = 0.0
) {
rectangle(x, y, width, height)
// ๋ชจ์๋ฆฌ ์ฒ๋ฆฌ ๋ฑ...
}
// ๋ค๋ฅธ Extension์ ์ฌ์ฉํ๋ ์๋ก์ด Extension
fun Drawer.tiled(
cols: Int,
rows: Int,
width: Double,
height: Double
) {
for (x in 0 until cols) {
for (y in 0 until rows) {
val px = x * width
val py = y * height
box(px, py, width, height) // ๋ค๋ฅธ Extension ์ฌ์ฉ
}
}
}
extend {
tiled(5, 5, 100.0, 100.0)
}
์์ฃผ ์ฐ๋ Extension๋ค์ ํ ํ์ผ์ ๋ชจ์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ฒ๋ผ ์ฌ์ฉํ ์ ์์ต๋๋ค:
// DrawerExtensions.kt (๋๋ ์๋ฌด ํ์ผ)
// ๊ฒฉ์
fun Drawer.grid(cols: Int, rows: Int, spacing: Double, radius: Double = 20.0) {
for (x in 0 until cols) {
for (y in 0 until rows) {
circle(x * spacing, y * spacing, radius)
}
}
}
// ์ํ ๋ฐฐ์น
fun Drawer.radialLayout(count: Int, distance: Double, radius: Double = 20.0) {
for (i in 0 until count) {
val angle = TWO_PI / count * i
val x = distance * cos(angle)
val y = distance * sin(angle)
circle(x, y, radius)
}
}
// ๊ฒฝ๋ก ๊ทธ๋ฆฌ๊ธฐ
fun Drawer.path(points: List<Vector2>, closed: Boolean = false) {
if (points.isEmpty()) return
for (i in 0 until points.size - 1) {
lineSegment(points[i], points[i + 1])
}
if (closed) {
lineSegment(points.last(), points.first())
}
}
// ๋์
fun Drawer.spiral(count: Int, spacing: Double, rotation: Double = 0.0) {
for (i in 0 until count) {
val angle = rotation + i * 0.2
val radius = i * spacing
val x = radius * cos(angle)
val y = radius * sin(angle)
point(x, y)
}
}
// --------- ๋ฉ์ธ ํ์ผ์์ ์ฌ์ฉ ---------
program {
extend {
clear(ColorRGBa.BLACK)
fill = ColorRGBa.WHITE
// ๋ชจ๋ Extension ๋ฉ์๋ ์ฌ์ฉ ๊ฐ๋ฅ
grid(10, 10, 80.0)
radialLayout(8, 150.0)
spiral(200, 1.0)
}
}
// ์ ๊ทํ๋ ๋ฒกํฐ (๋ฐฉํฅ๋ง, ๊ฑฐ๋ฆฌ๋ 1)
fun Vector2.normalized(): Vector2 {
val len = sqrt(x * x + y * y)
if (len == 0.0) return Vector2(0.0, 0.0)
return Vector2(x / len, y / len)
}
// ๋ฒกํฐ์ ํ์
fun Vector2.rotated(angleRadians: Double): Vector2 {
val cos = cos(angleRadians)
val sin = sin(angleRadians)
return Vector2(
x * cos - y * sin,
x * sin + y * cos
)
}
// ์ฌ์ฉ
val v = Vector2(1.0, 1.0)
val rotated = v.rotated(PI / 4) // 45๋ ํ์
val norm = v.normalized() // ์ ๊ทํ
program {
extend {
clear(ColorRGBa.BLACK)
val center = Vector2(400.0, 400.0)
val direction = (mouse.position - center).normalized()
// direction ๋ฐฉํฅ์ผ๋ก ์ ๊ทธ๋ฆฌ๊ธฐ
lineSegment(center, center + direction * 150.0)
}
}
// ๋ง์ฐ์ค๋ฅผ ๋ฐ๋ผ๋ค๋๋ ๋์
fun Drawer.spiralTowards(
count: Int,
spacing: Double,
targetPosition: Vector2,
rotation: Double = 0.0
) {
for (i in 0 until count) {
val angle = rotation + i * 0.2
val radius = i * spacing
val x = radius * cos(angle)
val y = radius * sin(angle)
val point = Vector2(x, y) + targetPosition
circle(point.x, point.y, 2.0)
}
}
program {
var t = 0.0
extend {
clear(ColorRGBa.BLACK)
fill = ColorRGBa.CYAN
spiralTowards(200, 0.8, mouse.position, t)
t += 0.02
}
}
// ๊ฒฉ์ + ์ ํ์ ํํฐ๋ง
fun Drawer.selectiveGrid(
cols: Int,
rows: Int,
spacing: Double,
radius: Double = 20.0,
shouldDraw: (Int, Int) -> Boolean = { _, _ -> true } // ๊ธฐ๋ณธ: ๋ชจ๋ ๊ทธ๋ฆฌ๊ธฐ
) {
for (x in 0 until cols) {
for (y in 0 until rows) {
if (shouldDraw(x, y)) {
circle(x * spacing, y * spacing, radius)
}
}
}
}
// ์ฌ์ฉ 1: ๊ธฐ๋ณธ (๋ชจ๋ ๊ทธ๋ฆฌ๊ธฐ)
extend {
selectiveGrid(10, 10, 80.0)
}
// ์ฌ์ฉ 2: ์ฒด์คํ ํจํด
extend {
selectiveGrid(10, 10, 80.0) { x, y ->
(x + y) % 2 == 0
}
}
// ์ฌ์ฉ 3: ๋๊ฐ์ ํจํด
extend {
selectiveGrid(10, 10, 80.0) { x, y ->
x == y
}
}
๊ณ ๊ธ ๊ธฐ๋ฅ:
| ์ด์ | ์ค๋ช |
|---|---|
| ์ฌ์ฌ์ฉ์ฑ | ๋ฐ๋ณต๋๋ ํจํด์ ํ ๋ฒ๋ง ์ ์ |
| ๋ช ํ์ฑ | ์ฝ๋์ ์๋๊ฐ ๋ช ํํจ |
| ๊ฐ๋ ์ฑ | ๋ณต์กํ ๋ก์ง์ ๊ฐ๋จํ ๋ฉ์๋ ํธ์ถ๋ก |
| ์ ์ง๋ณด์ | ํจํด ์์ ์ ํ ๊ณณ๋ง ๋ณ๊ฒฝ |
| ๋ฉ์๋ ์ฒด์ด๋ | Extension์ ์กฐํฉํด์ ๋ณต์กํ ์์ ๊ตฌ์ฑ |
| ๋ผ์ด๋ธ๋ฌ๋ฆฌํ | ์ ํธ๋ฆฌํฐ ํจ์๋ค์ ์ฒด๊ณ์ ์ผ๋ก ๊ด๋ฆฌ |
function drawGrid(cols, rows, spacing) {
for (let x = 0; x < cols; x++) {
for (let y = 0; y < rows; y++) {
circle(x * spacing, y * spacing, 20);
}
}
}
function draw() {
drawGrid(10, 10, 80);
}
๋ฌธ์ : ์ ์ญ ๋ค์์คํ์ด์ค ์ค์ผ, ์๋ ๋ถ๋ช ํ
fun Drawer.grid(cols: Int, rows: Int, spacing: Double) {
for (x in 0 until cols) {
for (y in 0 until rows) {
circle(x * spacing, y * spacing, 20.0)
}
}
}
extend {
grid(10, 10, 80.0)
}
์ฅ์ : ๋ช ํํ ๊ด๊ณ, ์ฒด๊ณ์ ์กฐ์ง, ๋ฉ์๋์ฒ๋ผ ์ฌ์ฉ
when ์กฐ๊ฑด ๋ถ๊ธฐ๋ค์ ๊ธ์์๋ when ๋ฌธ๋ฒ์ ๋ค๋ฃน๋๋ค.
if-else๋ณด๋ค ํจ์ฌ ๊ฐ๋ ฅํ ์กฐ๊ฑด ๋ถ๊ธฐ:
val mode = getUserInput()
when (mode) {
0 -> drawGrid(10, 10, 80.0)
1 -> radialLayout(12, 150.0)
2 -> spiral(200, 1.0)
else -> clear(ColorRGBa.BLACK)
}
์ด๊ฒ์ด ์ฌ์ฉ์ ์ ๋ ฅ์ ๋ฐ๋ผ ๋ค๋ฅธ ํจํด์ ๊ทธ๋ฆฌ๋ ์ธํฐ๋ํฐ๋ธ ์ํธ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
// ์ ์์ "2๋ฐฐ๊ฐ ๋๋๊ฐ" ๋ฉ์๋ ์ถ๊ฐ
fun Int.isDouble(other: Int): Boolean {
return this == other * 2
}
// ํ
์คํธ
println(10.isDouble(5)) // true
println(10.isDouble(3)) // false
// ์ ์ฌ๊ฐํ ๊ทธ๋ฆฌ๊ธฐ (์ค์ฌ ๊ธฐ์ค)
fun Drawer.square(
centerX: Double,
centerY: Double,
size: Double
) {
val half = size / 2
rectangle(centerX - half, centerY - half, size, size)
}
extend {
square(400.0, 400.0, 100.0)
}
// ๊ฒฉ์๋ฅผ Drawer์ ๋ฉ์๋๋ก
fun Drawer.grid(cols: Int, rows: Int, spacing: Double) {
for (x in 0 until cols) {
for (y in 0 until rows) {
circle(x * spacing, y * spacing, 20.0)
}
}
}
program {
extend {
clear(ColorRGBa.BLACK)
fill = ColorRGBa.WHITE
grid(12, 12, 60.0)
}
}
์คํํด ๋ณธ ํ:
// Vector2 ๋ฆฌ์คํธ๋ฅผ ์๊ฐํ
fun Drawer.visualizePoints(points: List<Vector2>, radius: Double = 5.0) {
for (point in points) {
circle(point.x, point.y, radius)
}
}
program {
extend {
clear(ColorRGBa.BLACK)
fill = ColorRGBa.PINK
val points = (0 until 20)
.map { Vector2(it * 40.0, 200.0 + 100.0 * sin(it.toDouble())) }
visualizePoints(points, 10.0)
}
}
์์ "์กฐ๊ฑด๋ถ ๋ก์ง์ด ์๋ Extension" ์์ ๋ฅผ ์คํํด ๋ณด๊ณ :