๐Ÿ”ง โ”  6. Extension ํ•จ์ˆ˜ โ€” OPENRNDR ์Šคํƒ€์ผ์˜ ํ•ต์‹ฌ

BamgasiJMยท6์ผ ์ „

OPENRNDR

๋ชฉ๋ก ๋ณด๊ธฐ
6/17
post-thumbnail

์ง€๊ธˆ๊นŒ์ง€ 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 ํ•จ์ˆ˜๊ฐ€ ๋ฌด์—‡์ธ๊ฐ€
  • ์™œ OPENRNDR ์Šคํƒ€์ผ์˜ ํ•ต์‹ฌ์ธ๊ฐ€
  • ์‹ค์ œ๋กœ ์ž์ฃผ ์“ฐ์ด๋Š” Extension ํ•จ์ˆ˜ ํŒจํ„ด๋“ค

์„ ๋‹ค๋ฃจ๊ฒ ์Šต๋‹ˆ๋‹ค.


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์—์„œ์˜ Extension ํ•จ์ˆ˜

์™œ ์ค‘์š”ํ•œ๊ฐ€?

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์™€์˜ ๋น„๊ต

p5.js: ์žฌ์‚ฌ์šฉ์ด ์–ด๋ ค์›€

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์˜ ๊ด€๊ณ„๊ฐ€ ๋ช…ํ™•ํ•˜์ง€ ์•Š์Œ
  • ์ „์—ญ ํ•จ์ˆ˜ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๊ฐ€ ์˜ค์—ผ๋จ

OPENRNDR: ๋ฉ”์„œ๋“œ์ฒ˜๋Ÿผ ์‚ฌ์šฉ

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. ์—†์ด๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
  • ์˜๋„๊ฐ€ ๋ช…ํ™•ํ•จ (์ด๊ฒƒ์€ ๋“œ๋กœ์ž‰ ๋ฉ”์„œ๋“œ)

์‹ค์ „ ์˜ˆ์ œ 1: ๊ฒฉ์ž ๊ทธ๋ฆฌ๊ธฐ

// 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 ๋ฃจํ”„๋ฅผ ๋งค๋ฒˆ ์ž‘์„ฑํ•ด์•ผ ํ•จ

์‹ค์ „ ์˜ˆ์ œ 2: ์›ํ˜• ๋ฐฐ์น˜

// ์ค‘์‹ฌ ์ฃผ์œ„์— ์›ํ˜•์œผ๋กœ ๋ฐฐ์น˜
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)
    }
}

์‹ค์ „ ์˜ˆ์ œ 3: ๋‚˜์„  ๊ทธ๋ฆฌ๊ธฐ

// ๋‚˜์„  ํŒจํ„ด
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์— ๋ฉ”์„œ๋“œ ์ถ”๊ฐ€

// 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 ๋ผ๋””์•ˆ

Drawer์™€ Vector2 Extension ์กฐํ•ฉ

// 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)  // ์‚ผ๊ฐํ˜• ๊ทธ๋ฆฌ๊ธฐ
    }
}

๊ธฐ๋ณธ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฐ’ (Default Parameters)

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 (๋ช…์‹œ)
}

์ข‹์€ ๊ธฐ๋ณธ๊ฐ’ ์„ค๊ณ„:

  • ์ž์ฃผ ์“ฐ๋Š” ๊ฐ’์„ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ
  • ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋Š” ๊ฐ’๋งŒ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ

์‹ค์ „ ์˜ˆ์ œ 4: ๋ณต์žกํ•œ ํŒจํ„ด

// ๋™์‹ฌ์›(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 ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋งŒ๋“ค๊ธฐ

์ž์ฃผ ์“ฐ๋Š” 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)
    }
}

Vector2 Extension์˜ ์‹ค์šฉ์„ฑ

๋ฒกํ„ฐ ์—ฐ์‚ฐ ํ™•์žฅ

// ์ •๊ทœํ™”๋œ ๋ฒกํ„ฐ (๋ฐฉํ–ฅ๋งŒ, ๊ฑฐ๋ฆฌ๋Š” 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
    }
}

์กฐ๊ฑด๋ถ€ ๋กœ์ง์ด ์žˆ๋Š” Extension

// ๊ฒฉ์ž + ์„ ํƒ์  ํ•„ํ„ฐ๋ง
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 ํ•จ์ˆ˜์˜ ์ด์ 

์ด์ ์„ค๋ช…
์žฌ์‚ฌ์šฉ์„ฑ๋ฐ˜๋ณต๋˜๋Š” ํŒจํ„ด์„ ํ•œ ๋ฒˆ๋งŒ ์ •์˜
๋ช…ํ™•์„ฑ์ฝ”๋“œ์˜ ์˜๋„๊ฐ€ ๋ช…ํ™•ํ•จ
๊ฐ€๋…์„ฑ๋ณต์žกํ•œ ๋กœ์ง์„ ๊ฐ„๋‹จํ•œ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ๋กœ
์œ ์ง€๋ณด์ˆ˜ํŒจํ„ด ์ˆ˜์ • ์‹œ ํ•œ ๊ณณ๋งŒ ๋ณ€๊ฒฝ
๋ฉ”์„œ๋“œ ์ฒด์ด๋‹Extension์„ ์กฐํ•ฉํ•ด์„œ ๋ณต์žกํ•œ ์ž‘์—… ๊ตฌ์„ฑ
๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌํ™”์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜๋“ค์„ ์ฒด๊ณ„์ ์œผ๋กœ ๊ด€๋ฆฌ

p5.js์™€์˜ ์ฐจ์ด

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() {
    drawGrid(10, 10, 80);
}

๋ฌธ์ œ: ์ „์—ญ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ์˜ค์—ผ, ์˜๋„ ๋ถˆ๋ช…ํ™•

OPENRNDR: Extension ํ•จ์ˆ˜

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)
}

์ด๊ฒƒ์ด ์‚ฌ์šฉ์ž ์ž…๋ ฅ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ํŒจํ„ด์„ ๊ทธ๋ฆฌ๋Š” ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒ ์•„ํŠธ๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.


์—ฐ์Šต ๋ฌธ์ œ

1. ๊ธฐ๋ณธ Extension ๋งŒ๋“ค๊ธฐ

// ์ •์ˆ˜์— "2๋ฐฐ๊ฐ€ ๋˜๋Š”๊ฐ€" ๋ฉ”์„œ๋“œ ์ถ”๊ฐ€
fun Int.isDouble(other: Int): Boolean {
    return this == other * 2
}

// ํ…Œ์ŠคํŠธ
println(10.isDouble(5))   // true
println(10.isDouble(3))   // false

2. Drawer Extension ๋งŒ๋“ค๊ธฐ

// ์ •์‚ฌ๊ฐํ˜• ๊ทธ๋ฆฌ๊ธฐ (์ค‘์‹ฌ ๊ธฐ์ค€)
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)
}

3. ๊ฒฉ์ž ๊ฐœ์„ 

// ๊ฒฉ์ž๋ฅผ 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)
    }
}

์‹คํ–‰ํ•ด ๋ณธ ํ›„:

  • ๋ฐ˜์ง€๋ฆ„์„ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ถ”๊ฐ€ํ•ด๋ณด์„ธ์š”
  • ๊ธฐ๋ณธ๊ฐ’์„ ์„ค์ •ํ•ด๋ณด์„ธ์š”

4. ๋ณตํ•ฉ Extension

// 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)
    }
}

5. ์‹ฌํ™”: ์กฐ๊ฑด๋ถ€ Grid

์•ž์˜ "์กฐ๊ฑด๋ถ€ ๋กœ์ง์ด ์žˆ๋Š” Extension" ์˜ˆ์ œ๋ฅผ ์‹คํ–‰ํ•ด ๋ณด๊ณ :

  • ๋‹ค์–‘ํ•œ ํŒจํ„ด์„ ๋งŒ๋“ค์–ด ๋ณด์„ธ์š” (๋Œ€๊ฐ์„ , ์ฒด์ŠคํŒ, ํ…Œ๋‘๋ฆฌ๋งŒ ๋“ฑ)
  • ์—ฌ๋Ÿฌ ์กฐ๊ฑด์„ ์กฐํ•ฉํ•ด ๋ณด์„ธ์š”

profile
Coding Art with Blender / Three.js / p5.js / GLSL Shader / Processing / nannou

0๊ฐœ์˜ ๋Œ“๊ธ€