3dayboy

技術備忘録

Kotlin + Gradle + Processing + ND4J で GUIシミュレータを作ってみた

流行りの Kotlin に挑戦したくなったので,前回作った Java + Processing + ND4J のGUIシミュレータの Kotlin 版を作ってみた.

sawa2d2.hatenablog.com

前回と同様,IntelliJ等の特定のIDEの機能に頼らず,Gradleを用いて直接プロジェクトを作成する.

環境

  • Java 8 (Open JDK 1.8.0)
  • Kotlin 1.3.50
  • Gradle 5.6.1

実装

プロジェクトの新規作成

まずは,Gradleを用いてプロジェクトを新規作成する. 以下のコマンドを実行し,kotlin プロジェクトの雛形を生成する:

$ mkdir simulator
$ cd simulator
$ gradle init --type kotlin-application
...
Enter selection (default: Groovy) [1..2] [Enter]
...
Enter selection (default: JUnit 4) [1..4] [Enter]
...
Project name (default: simulator):  [Enter]
Source package (default: simulator):  [Enter]
...

   

パッケージのインストール

Processing および ND4J のライブラリを利用するために,次のパッケージを導入する:

これらのパッケージを利用するために, build.gradle.kts の "dependencies" 内に次の記述を加える:

implementation("org.processing:core:3.3.7")
implementation("org.nd4j:nd4j-native-platform:0.9.1")

メインプログラムの作成

src/main/kotlin/simulator/App.kt を次のように書き換える:

package simulator

import processing.core.*
import org.nd4j.linalg.api.ndarray.INDArray
import org.nd4j.linalg.factory.Nd4j

class App : PApplet () {
    var p = Nd4j.zeros(2) // position
    var v = Nd4j.zeros(2) // velocity
    var d = 40F // diameter

    override fun settings() {
        size(200, 200)
    }

    override fun setup(){
        p = Nd4j.create(doubleArrayOf(0.0, height / 2.0))
        v = Nd4j.create(doubleArrayOf(1.0, 0.0))
    }
    
    override fun draw(){
        background(255)
        p = p.add(v)
        if(p.getDouble(0) >= width + d/2) {
            p.putScalar(0, -d/2)
        } 
        ellipse(p.getFloat(0), p.getFloat(1), d, d)
    }
 
    fun run(args: Array<String>) : Unit = PApplet.main("simulator.App")
}

fun main(args : Array<String>) : Unit = App().run(args)

実行

次のコマンドを実行する:

$ gradle run

 

結果

ウィンドウが出現し,円が左から右に流れるアニメーションが再生される.

おわりに

次のところがJavaと違った.

  • プリミティブ型 (int, doubleなど) がすべてオブジェクト (Int, Double など) に統一されている.
  • クラス変数は、宣言と同時に必ず初期化しなければならない.このように、クラス直下の宣言 & 初期化を行う部分をKotlinでは「プライマリコンストラクタ」といい、クラス生成時に自動実行される。
    • コンストラクタと呼ばれるが、Javaと違って関数ではない。
  • Double や Float などの小数型に数値を代入するときは,小数点を明記しないとエラーになる.例えば " 0.0" は代入できるが "0" は代入できない.

作成済みソースコードGitHubを参照.

参考