Skip to content

Commit

Permalink
Simplifies forces
Browse files Browse the repository at this point in the history
  • Loading branch information
igr committed Mar 22, 2024
1 parent e42e068 commit 7442063
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 10 deletions.
4 changes: 2 additions & 2 deletions gartwork/src/main/kotlin/dev/oblac/gart/flow/Flow.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import kotlin.math.sin
* @param direction in radians, indicates the direction of the flow. The angle is measured from the negative x-axis.
* 0 is up, PI/2 is right, PI is down, 3PI/2 is left.
*/
data class Flow(override val direction: Float, override val magnitude: Float = 1f) : Force<Flow> {
data class Flow(override val direction: Float, override val magnitude: Float = 1f) : Force {

override operator fun plus(other: Flow): Flow {
override operator fun plus(other: Force): Flow {
return Flow(middleAngle(direction, other.direction), (magnitude + other.magnitude) / 2)
}

Expand Down
19 changes: 13 additions & 6 deletions gartwork/src/main/kotlin/dev/oblac/gart/flow/Force.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import dev.oblac.gart.skia.Point
import kotlin.math.cos
import kotlin.math.sin

interface Force<T : Force<T>> {
/**
* Represents a force that acts on a point.
*/
interface Force {
val direction: Float
val magnitude: Float

Expand All @@ -17,26 +20,30 @@ interface Force<T : Force<T>> {
* Used to determine the next position of the point.
*/
fun offset(p: Point): Point
operator fun plus(other: T): T

/**
* Combines two forces into one.
*/
operator fun plus(other: Force): Force
}

/**
* Generates a force at the given point.
*/
fun interface ForceGenerator<T : Force<T>> {
fun interface ForceGenerator<T : Force> {
operator fun invoke(x: Float, y: Float): T
}

class ForceField<T : Force<T>>(val w: Int, val h: Int, private val field: Array<Array<T>>) {
class ForceField<T : Force>(val w: Int, val h: Int, private val field: Array<Array<T>>) {

operator fun get(x: Int, y: Int): T {
return field[x][y]
}

companion object {
inline fun <reified T : Force<T>> of(d: Dimension, supplier: ForceGenerator<T>) = of(d.w, d.h, supplier)
inline fun <reified T : Force> of(d: Dimension, supplier: ForceGenerator<T>) = of(d.w, d.h, supplier)

inline fun <reified T : Force<T>> of(width: Int, height: Int, supplier: ForceGenerator<T>): ForceField<T> {
inline fun <reified T : Force> of(width: Int, height: Int, supplier: ForceGenerator<T>): ForceField<T> {
val field = Array(width) { x ->
Array(height) { y ->
supplier(x.toFloat(), y.toFloat())
Expand Down
4 changes: 2 additions & 2 deletions gartwork/src/main/kotlin/dev/oblac/gart/flow/VecForce.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import kotlin.math.sin
/**
* Vector force has a vector defined in each point.
*/
data class VecForce(override val direction: Float, override val magnitude: Float = 1f) : Force<VecForce> {
data class VecForce(override val direction: Float, override val magnitude: Float = 1f) : Force {

override operator fun plus(other: VecForce): VecForce {
override operator fun plus(other: Force): VecForce {
val x3 = magnitude * cos(direction) + other.magnitude * cos(other.direction)
val y3 = magnitude * sin(direction) + other.magnitude * sin(other.direction)
val r3 = fastSqrt(x3 * x3 + y3 * y3)
Expand Down

0 comments on commit 7442063

Please sign in to comment.