mike-neckのブログ

JavaかJavaFXかJavaEE(なんかJava8が多め)

JavaFXでベジエ曲線を描いてみたい

こんにちわ、と挨拶をするほど心に余裕のないみけです。

アドビのイラストレーターを持っていますが、古いマシンに入っていてほとんどさわってなくて、もったいないと思いつつ、古いマシンを起動するのもアレなのでアレで、ベジエ曲線とかを描いてみるツールを触りたいと思っていたけど、どうしたものか考えてたら、JavaFXアドベントカレンダーでさくらばさんがベジエ曲線を描いていたので、真似してJavaFXベジエ曲線を描くツール作ってみた。とは言っても、Groovyだけど…

import javafx.application.*
import javafx.scene.*
import javafx.scene.paint.*
import javafx.scene.shape.*
import javafx.geometry.*
import javafx.stage.*
import javafx.scene.control.*
import javafx.scene.layout.*

class App extends Application {

    static final double MIN = 0
    static final double MAX = 400

    final double x1 = 25
    final double y1 = 25
    final double x2 = 375
    final double y2 = 375

    @Override void start(Stage stg) {
        def parent = new HBox(10d)
        parent.width = 830
        parent.height = 420
        parent.padding = new Insets(10)

        def scene = new Scene(parent, 830, 420)

        def group = new Group()
        group.minWidth(400)
        group.minHeight(400)
        group.maxWidth(400)
        group.maxHeight(400)
        parent.children << group
        def children = group.children

        def bg = new Rectangle()
        bg.x = 0
        bg.y = 0
        bg.width = 400
        bg.height = 400
        bg.fill = Color.DARKSLATEGRAY
        children << bg

        def curve = new CubicCurve()
        curve.startX = x1
        curve.startY = y1
        curve.controlX1 = x2
        curve.controlY1 = y2
        curve.controlX2 = x1
        curve.controlY2 = y1
        curve.endX = x2
        curve.endY = y2
        curve.stroke = Color.SNOW
        curve.fill = Color.TRANSPARENT
        curve.strokeWidth = 3
        children << curve

        def sliders = new VBox(5d)
        parent.children << sliders
        [
            [n: 'startX', v: x1, p: curve.startXProperty()],
            [n: 'startY', v: y1, p: curve.startYProperty()],
            [n: 'controlX1', v: x2, p: curve.controlX1Property()],
            [n: 'controlY1', v: y2, p: curve.controlY1Property()],
            [n: 'controlX2', v: x1, p: curve.controlX2Property()],
            [n: 'controlY2', v: y1, p: curve.controlX2Property()],
            [n: 'endX', v: x2, p: curve.endXProperty()],
            [n: 'endY', v: y2, p: curve.endYProperty()]
        ].each {
            def c = new HBox(10d)
            c.minWidth = 400
            c.maxWidth = 400
            c.minHeight = 45
            c.maxHeight = 45
            sliders.children << c

            def s = new Slider(MIN, MAX, it.v)
            s.orientation = Orientation.HORIZONTAL
            s.minWidth = 200
            s.maxWidth = 200
            s.minHeight = 25
            s.maxHeight = 25
            s.showTickMarks = true
            s.majorTickUnit = 100
            s.blockIncrement = 25
            it.p.bind(s.valueProperty())

            def l = new Label(it.n)
            l.minWidth = 190
            l.maxWidth = 190
            l.minHeight = 45
            l.maxHeight = 45
            l.labelFor = s

            c.children << l
            c.children << s
        }

        stg.scene = scene
        stg.title = 'draw Bezier Curve'
        stg.show()
    }
}

Application.launch(App.class)

起動するとこんな感じになります。

【追記】

なんか、上記のプログラムに走査線を表示して試してみたいたところ、なんかベジエ曲線の表示がなんかおかしい。

ベジェ曲線の表示がおかしい

上記の走査線および開始・終端点の設定では単純なカーブ型の曲線になるのに、なぜかS字型の曲線を描いている。

なんなんでしょう、これ???