3

シェイプのスケーリング機能に問題があります。いくつかの形状を保持する独自に作成した座標系を使用したい。これらの形状にはスケーリング関数が必要です。スケーリングは各シェイプの中心で行われるため、シェイプをスケーリングすると移動します。この動きに反応するために、原点を再計算します。しかし、何度もスケーリングすると、形状は依然として原点から離れます。どうしてか分かりません。誰でもこの動作を説明できますか? さらに、ストローク幅を再計算して 1px のままにします。

ありがとうございました!

私のコード:

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.shape.Polyline;
import javafx.stage.Stage;

public class ScaleTest extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        Pane root = new Pane();
        Scene scene = new Scene(root, 800, 600, Color.WHITE);
        stage.setScene(scene);

        Polyline line1 = new Polyline(new double[] { 50, 50, 50, 150, 150, 150,
                150, 50, 50, 50 });
        line1.setStrokeWidth(1);

        Group polylines = new Group();
        polylines.getChildren().add(line1);

        Line xAxis = new Line(0, 50, 800, 50);
        Line yAxis = new Line(50, 0, 50, 800);

        root.setScaleY(-1);
        root.getChildren().addAll(xAxis, yAxis);
        root.getChildren().add(polylines);

        scene.setOnScroll(new EventHandler<ScrollEvent>() {

            @Override
            public void handle(ScrollEvent event) {
                double scale = 0;
                if (event.getDeltaY() < 0) {
                    scale = -0.1;
                } else {
                    scale = 0.1;
                }

                Bounds beforeScaling = polylines.getBoundsInParent();
                polylines.setScaleX(polylines.getScaleX() + scale);
                polylines.setScaleY(polylines.getScaleY() + scale);
                Bounds afterScaling = polylines.getBoundsInParent();
                polylines.setTranslateX(polylines.getTranslateX()
                        + beforeScaling.getMinX() - afterScaling.getMinX());
                polylines.setTranslateY(polylines.getTranslateY()
                        + beforeScaling.getMinY() - afterScaling.getMinY());

                //optional
                line1.setStrokeWidth(1/polylines.getScaleX());
            }

        });

        stage.show();
    }
}
4

1 に答える 1

5

なぜ「ドリフト」しているのかはわかりません。丸め誤差が蓄積しているだけかもしれません。とにかく簡単なアプローチは、Scale変換を使用することです。これにより、スケールが発生する「ピボット」ポイントを指定できます。

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.shape.Polyline;
import javafx.scene.transform.Scale;
import javafx.stage.Stage;

public class ScaleTest extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        Pane root = new Pane();
        Scene scene = new Scene(root, 800, 600, Color.WHITE);
        stage.setScene(scene);

        Polyline line1 = new Polyline(new double[] { 50, 50, 50, 150, 150, 150,
                150, 50, 50, 50 });
        line1.setStrokeWidth(1);

        Group polylines = new Group();
        polylines.getChildren().add(line1);

        Line xAxis = new Line(0, 50, 800, 50);
        Line yAxis = new Line(50, 0, 50, 800);

        root.setScaleY(-1);
        root.getChildren().addAll(xAxis, yAxis);
        root.getChildren().add(polylines);

        Scale scale = new Scale();
        scale.setPivotX(50);
        scale.setPivotY(50);
        polylines.getTransforms().add(scale);

        scene.setOnScroll(new EventHandler<ScrollEvent>() {

            @Override
            public void handle(ScrollEvent event) {
                double scaleDelta = 0;
                if (event.getDeltaY() < 0) {
                    scaleDelta = -0.1;
                } else {
                    scaleDelta = 0.1;
                }
                scale.setX(scale.getX() + scaleDelta);
                scale.setY(scale.getY() + scaleDelta);
                //optional
                line1.setStrokeWidth(1/scale.getX());
            }

        });

        stage.show();
    }
}
于 2014-09-23T16:18:18.667 に答える