mike-neckのブログ

Java or Groovy or Swift or Golang

JavaFX's CubicCurve may have a bug??? #javafx (fixed it's my mistake!!!)

Today, I wrote an article on CubicCurve(Bezier curve) of JavaFX.

After I tried it much, finally I found some strangeness on CubicCurve.

An control line 2 should tangent at the end point of the Curve, but it doesn't.

Please see the following figure.

control line 2 doesn't tangent at the end point

The control line 2 (the line with magenta color) actually doesn't tangent at the end point, but it is perpendicular on that point.

I think this is a bug on CubicCurve.

The code is shown bellow.

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 = 10
    static final double MAX = 410

    final double x1 = 10
    final double y1 = 10
    final double x2 = 410
    final double y2 = 410

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

        def scene = new Scene(parent, 830, 440, new Color(0/256d, 0/256d, 144/256f, 96/256f))

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

        def bg = new Rectangle()
        bg.x = 0
        bg.y = 0
        bg.width = 420
        bg.height = 420
        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 = 4
        children << curve

        def l1 = new Line(x1,y1,x2,y2)
        l1.stroke = Color.CYAN
        l1.strokeWidth = 1
        children << l1

        def l2 = new Line(x2,y2,x1,y1)
        l2.stroke = Color.MAGENTA
        l2.strokeWidth = 1
        children << l2

        def sliders = new VBox(5d)
        parent.children << sliders
        [
            [n: 'startX',    v: x1, l: l1.startXProperty(), p: curve.startXProperty()],
            [n: 'startY',    v: y1, l: l1.startYProperty(), p: curve.startYProperty()],
            [n: 'controlX1', v: x2, l: l1.endXProperty(),   p: curve.controlX1Property()],
            [n: 'controlY1', v: y2, l: l1.endYProperty(),   p: curve.controlY1Property()],
            [n: 'controlX2', v: x1, l: l2.startXProperty(), p: curve.controlX2Property()],
            [n: 'controlY2', v: y1, l: l2.startYProperty(), p: curve.controlX2Property()],
            [n: 'endX',      v: x2, l: l2.endXProperty(),   p: curve.endXProperty()],
            [n: 'endY',      v: y2, l: l2.endYProperty(),   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 = 250
            s.maxWidth = 250
            s.minHeight = 25
            s.maxHeight = 25
            s.showTickMarks = true
            s.majorTickUnit = 100
            s.blockIncrement = 25
            it.p.bind(s.valueProperty())
            it.l.bind(s.valueProperty())

            def l = new Label(it.n)
            l.minWidth = 140
            l.maxWidth = 140
            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)

If my code is wrong, please mention me at twitter @mike_neck.


postscript

Woops! I found my bug, on line 76.

error : p:curve.controlX2Property()

correct : p:curve.controlY2Property()